I am currently working with the vss-web-extension-sdk. I am using ESLint, eslint-plugin-import, and eslint-import-resolver-typescript to validate the files.
import { WidgetSettings, WidgetStatus } from "TFS/Dashboards/WidgetContracts";
The line above, extracted from my run.ts, throws the following error.
Unable to resolve path to module 'TFS/Dashboards/WidgetContracts'. eslint(import/no-unresolved).
However, when I control-click on the import in VSCode, it navigates to the module in tfs.d.ts. I am doing something incorrectly to make the resolver not detect the module?
My tsconfig.json has
{
"compilerOptions": {
"module": "amd",
"strict": true,
"moduleResolution": "node",
"types": [
"vss-web-extension-sdk"
]
}
}
and my .eslintrc.json has
{
"settings": {
"plugins": [
"import"
],
"rules": {
"import/no-unresolved": "error"
},
"import/resolver": {
"typescript": {}
}
}
}
Install Commands
npm install --save-dev eslint-plugin-import typescript-eslint-parser eslint-import-resolver-typescript
npm install --save vss-web-extension-sdk
Try setting your baseUrl and your rootDir in your tsconfig.json to specify where that absolute path starts.
See here: https://maxisam.github.io/2017/01/03/rootDirs-in-tsconfig/
Related
I'm trying to run a script created in a regular folder with two .ts files. One with the script and one with helper functions to run it. I'm also importing more things such as axios or form-data.
The thing is that when I try to run the script with ts-node: node script.ts, the following error appears:
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts"
My package.json:
{
"dependencies": {
"#types/node": "^17.0.23",
"axios": "^0.26.1",
"form-data": "^4.0.0",
"showdown": "^2.0.3",
"ts-node": "^10.7.0",
"typescript": "^4.6.3"
},
"type": "module"
}
And my tsconfig.json:
{
"compilerOptions": {
"esModuleInterop": true
},
"include": ["/**/*.ts"],
"exclude": ["node_modules"]
}
My imports in the script.ts file are:
import { datoManagementPrimaryEnvironment } from "./content.management";
import {
createContent,
uploadToCloudfare,
getEntryFromDatoWithTheId,
getFilters,
} from "./helpers";
and in helpers.ts:
import { datoManagementPrimaryEnvironment } from "./content.management";
import axios from "axios";
import FormData from "form-data";
var showdown = require("showdown");
Does anyone know what I'm doing wrong? thanks!
Remove "type": "module" from your package.json
And change your tsconfig.json to:
{
"compilerOptions": {
"esModuleInterop": true,
"moduleResolution": "node"
},
"include": ["/**/*.ts"],
"exclude": ["node_modules"]
}
Here's how you use TypeScript with native ESM
Update your package.json to have:
{
"type": "module",
// …
}
Install the #tsconfig/node-lts-strictest-esm dependency:
npm i -D #tsconfig/node-lts-strictest-esm
Update your tsconfig.json to have:
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "#tsconfig/node-lts-strictest-esm/tsconfig.json",
// …
}
Use imports with .js extension in your TS source files, e.g.:
import { Foo } from './common/foo.js';
Then use the ts-node-esm file.ts command instead of ts-node file.ts.
This should do the trick.
Also, look at the detailed guide.
Use the --esm switch for ts-node.
Eg
ts-node --esm index.ts
This requires you to have the module to set to one of the newer ones (like nodenext or node16) and moduleResolution also set to a newer method, in your tsconfig.
This is what worked for me. Thanks to #Slava for pointing me in the right direction.
Linking the documentation here.
The easiest method is to add esm: true to your TypeScript config file:
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "#tsconfig/node-lts-strictest-esm/tsconfig.json",
"compilerOptions": {
// …
},
"include": [
// …
],
"ts-node": {
"esm": true, // «———— enabling ESM for ts-node
},
}
The only thing I was missing was adding "esm": true, because I already have ts-config setup for esm. But if you have nothing, it's probably helpful to add the "$schema" and "extends".
I also needed to add "type": "module" in the package.json file.
When you want to use ts-node you should try running the file with ts-node scripts.ts instead of node scripts.ts.
You can also refer to the usage examples on npmjs.com
I was watching this video in order to learn how to add some simple tests to my Express routes but I am getting all kind of errors while executing a test. The error is:
import * as chai from 'chai';
^^^^^^
SyntaxError: Cannot use import statement outside a module
I have read some similar Stack Overflow questions and GitHub issues but I didn't find a solution for my own application. Finally I found Mocha documentation on GitHub regarding ES modules but it didn't work:
I created the app using TypeScript and CommonJS module to transpile, so I added "test": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha src/test/*.ts" to the package.json scripts but I am getting the same error every time. I am using ts-node as a server.
Anyway, this is my tsconfig.json file:
{
"compilerOptions": {
"sourceMap": true,
"target": "es6",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src"
},
"exclude": [
"node_modules"
]
}
And this is the src/test/mi-route.ts file:
import * as chai from 'chai';
import * as chaiHttp from 'chai-http';
import server from '../app';
// Assertions
chai.should();
chai.use(chaiHttp);
describe('API Users', () => {
// Test Route GET
describe('GET /api/admin/users', () => {
it('Should return all the users', done => {
chai.request(server)
.get('/api/admin/users')
.end((err, response) => {
response.should.have.status(200);
response.body.should.be.a('object');
done();
});
});
});
});
An this is my package.json scripts:
"scripts": {
"dev": "ts-node-dev src/app.ts",
"start": "node dist/app.js",
"test": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha src/test/*.ts",
"build": "tsc -p"
},
So... any suggestions? Should I change Common JS Module? Thanks in advance
Had the same issue and almost gave up using Mocha with TypeScript (in our case Angular 9).
This is what helped me:
In tsconfig.json:
Replaced this:
"module": "esnext",
with this:
"module": "commonjs",
Also here I found a working example of Mocha with TypeScript and used the tsconfig file from there to compare with mine:
https://medium.com/#RupaniChirag/writing-unit-tests-in-typescript-d4719b8a0a40
I was able to test thanks to the #types/chai-http – Can't use ES6 import
GitHub issue's answer.
I added a second TypeScript configuration file tsconfig.testing.json with the following information:
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"lib": ["es2017"],
"declaration": false,
"noImplicitAny": false,
"removeComments": true,
"inlineSourceMap": true,
"moduleResolution": "node"
},
"include": ["scripts/**/*.ts", "src/**/*.ts", "node_modules/lodash-es/**/*.js"]
}
Then I changed my package.json scripts as:
"test": "env TS_NODE_PROJECT=\"tsconfig.testing.json\" mocha --require ts-node/register 'src/test/**/*.ts'",
Finally I changed the test file like:
import * as chai from 'chai';
import 'chai-http';
import server from '../app';
// Assertions
chai.should();
chai.use(require('chai-http'));
Well, running the tests works now.
Ensure you have .mocharc.json in your project:
{
"extension": ["ts"],
"timeout": 5000,
"exit": true,
"require": "ts-node/register"
}
(see also https://github.com/mochajs/mocha-examples/tree/master/packages/typescript#es-modules)
Also had this problem and found I didn't have to switch to commonJS, just had to enable ESM:
npm install --save-dev esm
./node_modules/mocha/bin/mocha -r esm -r ts-node/register "src/**/*Test.ts"
I've recently hit this problem a few times in a project I'm working on.
The project contains many smaller modules which are all written in TypeScript and compiled before being committed. I have (clearly at least couple of times by the fact this link was already purple) somehow managed to commit my module without compiling. This resulted in the error when mocha tried to execute the .js version of a dependency which wasn't committed to version control.
Building the dependency, committing and updating the packages fixed my issue. Hopefully this helps someone else out in a similar position to me!
Another possible cause for this error:
Is you file type .tsx instead of .ts? Changing it to .ts will fix the error or add proper support for .tsx files.
In my Vs code editor, i am getting following error in simple require statement like:
const HtmlWebpackPlugin = require('html-webpack-plugin')
Error: [eslint] 'html-webpack-plugin' should be listed in the project's dependencies, not devDependencies. (import/no-extraneous-dependencies)
Can anyone explain what is no-extraneous-dependencies and why it is giving me this error in simple require statement in my webpack config. I went through this link : eslint should be listed in the project's dependencies, not devDependencies but it was not much helpful as it did not explain why i am adding that line.
My eslintrc.json file:
{
"env": {
"browser": true,
"es6": true,
"commonjs": true,
"node": true
},
"extends": ["airbnb", "prettier", "prettier/react"],
"plugins": ["prettier"],
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
}
}
You just need to tell eslint that it's ok to require dev dependency in webpack.
You can create .eslintrc in your webpack folder with
rules:
import/no-extraneous-dependencies: [error, { devDependencies: true }]
This will prevent the error from appearing.
Alternatively you can just set
const HtmlWebpackPlugin = require('html-webpack-plugin'); // eslint-disable-line import/no-extraneous-dependencies
to disable only this line
In your .eslintrc.json include webpack.config.js in devDependencies:
"rules": {
"import/no-extraneous-dependencies": [
"error",
{
"devDependencies": [
"**/*.test.ts?(x)",
"**/*.spec.ts?(x)",
"**/test-utils.ts",
"webpack.config.js"
]
}
],
Add "type": "module" to your package.json, then you can use ES6 import without this error/warning.
How can I compile my Typescript project into a TS compilation so I can then import it into other TS projects and use the type definitions? For backward compatibility, I also want to export them as pure JS too so others who don't use TS, can still use the project.
You need to publish your project as an npm package. You can create a private package on npm if you want (but you need a paid account for that), or you can publish it publicly, or you can use sinopia, which is basically a local instance of npm.
Any one of these options requires you to have an up to date package.json file that specifies your project's dependencies.
You will be publishing your package in compiled form. So, if you specify your tsconfig and package.json properly, you will be exporting js files along with d.ts. files and the package will be usable either by typescript or vanilla javascript.
This is how I've done it:
// package.json
// The property name: #my-org/... means that the package is scoped -
// you can point a #scope at a specific NPM registry.
// See https://docs.npmjs.com/misc/scope
// We use myget.org to host our private packages.
{
"name": "#my-org/ng-lib",
"version": "1.0.8",
"main": "dist/index.js",
"scripts": {
"transpile": "tsc --outDir ./",
"clean": "rimraf ./services && rimraf ./*.js && rimraf ./*.d.ts"
},
"author": "*** <me#my-org.com>",
"license": "ISC",
"files": [
"**/*.js",
"**/*.d.ts"
],
"typings": "index.d.ts",
"dependencies": {
"#types/angular": "^1.5.20",
"angular": "^1.5.9"
},
"devDependencies": {
"rimraf": "^2.5.4"
}
}
EDIT:
Notice the "typings": "index.d.ts" line? That describes the main "types" file for the package. So when you do an import * as ngLib from '#my-org/ng-lib' it will use the typings from node_modules/#my-org/ng-lib/index.d.ts for intellisense, and upon transpile webpack will find the main js file at node_modules/#my-org/ng-lib/dist/index.js
So if you've created an index.d.ts by hand and all you've got to export are interfaces you can point the typings field at that index.d.ts as interfaces have no implementation, and just describe the shape of an object.
However, if you've got objects with logic (methods, getters/setters, etc) they will more than likely be classes, which you'll need to transpile down to .js AND .d.ts files.
EXAMPLE:
./index.ts # Re-exports both my-class and my-interface
./my-class.ts # Implements my-interface.d.ts
./my-interface.d.ts
This output of this after transpile should be as follows in a "typed" NPM package:
./index.d.ts
./index.js
./my-class.js
./my-class.d.ts
./my-interface.d.ts
And package.json will include the following lines:
"main": "./index.js",
"typings": "./index.d.ts",
"files": [
"./index.d.ts",
"./index.js",
"./my-class.js",
"./my-class.d.ts",
"./my-interface.d.ts"
]
... and when consuming the package (once it's published and installed in another project) can be done in the following ways:
import * as ngLib from '#my-org/ng-lib'
import { MyClass } from '#my-org/ng-lib'
import { MyInterface } from '#my-org/ng-lib'
import { MyClass } from '#my-org/ng-lib/my-class'
import { MyInterface } from '#my-org/ng-lib/my-interface'
END EDIT
The declaration property in tsconfig.json will emit .d.ts files describing the 'shape' of your exported objects.
// tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"sourceMap": false,
"emitDecoratorMetadata": true,
"declaration": true,
"experimentalDecorators": true,
"removeComments": true,
"noImplicitAny": false,
"suppressImplicitAnyIndexErrors": false,
"baseUrl": "./src",
"listFiles": true,
"noImplicitUseStrict": false
},
"exclude": [
"node_modules"
]
}
And if it's a complicated package, I'll have separate modules and aggregate them in the index.ts like so:
// index.ts
export * from './module-one'
export * from './module-two'
export * from './module-three'
You can also have sub-directories, each with their own indexes.
This will create both the index.js and index.d.ts files, which allows the following:
import * as ngLib from '#my-org/ng-lib'
import { ModuleOne } from '#my-org/ng-lib/module-one'
import { SubModuleOne } from '#my-org/ng-lib/submodules/submodule-one'
I used a visual studio asp core angular 2 starter template form here .
The template uses webpack as module loader.
https://visualstudiogallery.msdn.microsoft.com/31a3eab5-e62b-4030-9226-b5e4c9e1ffb5
Now I created a project with this template (can be found here).
In VS Code everything is fine. but when i open the typescript files i can see that some TypeScript are not understood. For example in the code below module cannot be resolved
import 'angular2-universal-polyfills/browser';
import { enableProdMode } from '#angular/core';
import { platformUniversalDynamic } from 'angular2-universal';
import { AppModule } from './app/app.module';
import 'bootstrap';
// Enable either Hot Module Reloading or production mode
if (module['hot']) { //=>Cannot Resolve Moodule
module['hot'].accept();
module['hot'].dispose(() => { platform.destroy(); });
} else {
enableProdMode();
}
I also tried installing typings with this command
npm install --save #types/node
npm install --save #types/lodash
The tsconfig (placed in the javascript app folder) looks like this:
{
"compilerOptions": {
"moduleResolution": "node",
"target": "es5",
"sourceMap": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"skipDefaultLibCheck": true,
"lib": [ "es6", "dom" ],
"types": [ "node" ]
},
"exclude": [ "bin", "node_modules" ],
"atom": { "rewriteTsconfig": false }
}
What am I missing?