How to transform ES2017 to ES5 - node.js

I have a es2017 code with async/await, I want to transform it to es5 so that it'll be supported by most Node.js versions.
My current .babelrc file looks like this:
{
"presets": ["es2015", "es2016", "es2017"]
}
So I'm transforming es2017 to es2016, from es2016 to es2015 and from es2015 to es5.
When I'm trying to run the code after I built it with babel src -d dist -s I'm getting error saying that: ReferenceError: regeneratorRuntime is not defined
How can I transform the es2017 code to es5? I wanna publish the code later and make it usable by node.js v4 and up.

Thanks to #Bergi I found a way how to solve this ReferenceError: regeneratorRuntime is not defined error.
I added the transform-runtime plugin to my .babelrc
Now my .babelrc is:
{
"presets": ["es2015", "es2016", "es2017"],
"plugins": ["transform-runtime"]
}
There aren't any errors now and it works fine.

Related

Force TypeScript to generate export/imports with the ".js" extension; running Node 16?

Have a TS 4.7 library using ESM modules.
tsconfig.json:
"target": "ES2020",
"module": "ES2020",
"lib": ["ES2020"],
"moduleResolution": "node",
package.json
"type": "module",
I have a main file with only a one silly export:
index.ts
export { Spig } from './spig';
which is compiled to:
index.js
export { Spig } from './spig';
//# sourceMappingURL=index.js.map
Problem
When I use this library from a Node CLI program (with ESM modules enabled as well), I get the following error:
Cannot find module <path>/lib/spig imported from <path>/lib/index.js
When I manually add .js in the generated index.js, the issue is gone:
export { Spig } from './spig.js';
How can I force TypeScript compiler to generate the extension, too? What am I missing here?
You cannot omit the file extension anymore in ESM module imports. The extension should be always .js/.jsx, not .ts/.tsx for a typescript file. So, in the index.ts you should add the extension to spig export like the following and every other file imported/exported if using ESM modules.:
index.ts
export { Spig } from './spig.js';
Also, moduleResolution should be set to Node16 or NodeNext so ESM modules work as expected.
As stated in the docs (enphasis by me):
Relative import paths need full extensions (e.g we have to write import "./foo.js" instead of import "./foo").
When a .ts file is compiled as an ES module, ECMAScript import/export syntax is left alone in the .js output; when it’s compiled as a CommonJS module, it will produce the same output you get today under module: commonjs.
This also means paths resolve differently between .ts files that are ES modules and ones that are CJS modules. For example, let’s say you have the following code today:
// ./foo.ts
export function helper() {
// ...
}
// ./bar.ts
import { helper } from "./foo"; // only works in CJS
helper();
This code works in CommonJS modules, but will fail in ES modules because relative import paths need to use extensions. As a result, it will have to be rewritten to use the extension of the output of foo.ts - so bar.ts will instead have to import from ./foo.js.
// ./bar.ts
import { helper } from "./foo.js"; // works in ESM & CJS
helper();
This might feel a bit cumbersome at first, but TypeScript tooling like auto-imports and path completion will typically just do this for you.

How to use TypeScript Declaration File with mocha tests?

I have a TypeScript project, where the test are written in TypeScript. I want to use mocha to directly test TS files. I'm using ts-node for that, as described in ts-node#mocha.
In the project I'm using a JS library which doesn't have TS type definitions. So I created a d.ts file for that. Everything works well when compiling and running the projects. However mocha fails with:
% yarn mocha --require ts-node/register --require source-map-support/register ./test/*.ts
src/client.ts:3:26 - error TS7016: Could not find a declaration file for module 'algosdk'. '/home/robert/projects/algorand/ts-mocha/node_modules/algosdk/index.js' implicitly has an 'any' type.
Try `npm install #types/algosdk` if it exists or add a new declaration (.d.ts) file containing `declare module 'algosdk';`
3 import * as algosdk from "algosdk";
It seams that ts-node doesn't recognize the d.ts files.
The only solution which works is to use require instead of import statement, but this will not link the types to algosdk.
How to use mocha with TS files and type definition file?
This is the project structure (also in github):
├── build <-- JS from compiled TS go here
├── node_modules
├── package.json
├── src
├── #types <-- d.ts files
├── test
├── tsconfig.json
The tsconfig.json:
{
"compilerOptions": {
"target": "es2017",
"lib": ["esnext"],
"module": "commonjs",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"outDir": "./build",
"typeRoots" : ["./#types", "node_modules/#types"]
},
"exclude": ["**/node_modules"],
"include": [
"src",
"test",
"#types"
]
}
UPDATE
I confirm that the problem is related to ts-node, not to mocha. Running:
yarn ts-node src/client.ts
returns the same error.
References:
Mocha + ts-node
TypeScript: Could not find a declaration file for module in unit tests, only
you can add the following configuration to tsconfig.json file.
"ts-node": {
"files": true
},
it works well on my side.

Intellisense for module-alias Package

I am using this npm module (module-alias)
https://www.npmjs.com/package/module-alias in my Node project.
To make use of this package you have to set path aliases in the package.json file.
However, using this package comes with the disadvantage, that intellisense doesn't work anymore.
My question is how to enable intellisense with those path aliases?
The problem is that you did not register those aliases anywhere with your linter. I would gerenally suggest to use ESLint here (even if you use TypeScript as TSLint will be discontinued in favour of ESLint). My examples will include the TypeScript endings as well. If you definately want to make it work for JavaScript only you can skip the .ts .tsx extentensions in the eslint) So to make intellisense work do this in
.eslintrc.js
settings: {
"import/resolver": {
alias : {
map: [
["#","./src"]
],
extensions: [".js", ".jsx", ".ts", ".tsx"],
},
}
},
Note that in this case you will need the import Plugin for ESLint. If you don't already have it install it.
If you are using TypeScript you will also have to make that alias known to your compiler. So add this to your
tsconfig.json
"compilerOptions": {
"baseUrl": ".",
"paths": [
"#/*" : [
"src/*"
]
]
}

How to bundle node project into one file

Is there any WORKING way how to bundle node project into one single file (including dependencies) and how?
I am using babel (.babelrc)
{
"presets": ["#babel/preset-env"],
"plugins": [
[
"module-resolver",
{
"root": [
"./src"
],
"alias": {
"test": "./test",
"underscore": "lodash"
}
}
]
]
}
the answer is no. babel can not do what you want by itself. It is a tool for transforming one dialect of Javascript into another, based on rules defined in your .babelrc file. It is a compiler, not a linker (to borrow terms from the C world).
Using babel-plugin-module-resolver will not cause babel to transpile dependencies as if they were source files. It is simply a babel rule which modifies the paths passed to require() or import.
To include dependencies as well as source files you need to use both a compiler like babel and a bundler such as webpack or rollup.

Make babel exclude test files

On my build step I'm using babel to transpile the code to es5 (from src to dist). How do I make it exclude files ending in .test.js?
package.json
"scripts": {
"build": "babel src --out-dir dist",
.babelrc
{
"presets": [ "es2015" ],
"ignore": "\\.test\\.js"
}
Based on the documentation, you should be able to write .babelrc
{
"ignore": [
"**/*.test.js"
]
}
However, I was able to verify that this does not seem to work. I tried it with version 6.5.1 (babel-core 6.5.2).
At the same time, the following does work:
babel src --out-dir build --ignore '**/*.test.js'
That is the same glob pattern as written in the .babelrc file. If you install any glob library from npm you'll find that this glob pattern would work (that is how I came up with it...I do not currently use babel).
As of today, the following works in .babelrc
(babel-core: v6.26.3)
"ignore": [
"**/__tests__", // ignore the whole test directory
"**/*.test.js" // ignore test files only
]

Resources