How to build with babel and node 14? - node.js

Im trying to build my project with babel and target node 14.15.4
My .babelrc is like this
{
"presets": [
[
"#babel/preset-env",
{
"targets": {
"node": true
}
}
]
]
}
So i expected babel output will be compatible with current node. Unfortunately babel output keeps using require syntax instead of import so can't be run with node 14, that throws error
require("./server.js");
^
ReferenceError: require is not defined
at file:///Users/grzegorz/Projects/charts/server/dist/index.js:3:1
at ModuleJob.run (internal/modules/esm/module_job.js:152:23)
at async Loader.import (internal/modules/esm/loader.js:166:24)
at async Object.loadESM (internal/process/esm_loader.js:68:5)
Any idea what im doing wrong?

node
Type: string | "current" | true.
If you want to compile against the current node version, you can specify "node": true or "node": "current", which would be the same as "node": process.versions.node.
Example:1
{
"targets": "current"
}
example:2
{
"targets": true
}
example:3
{
"targets": "process.versions.node"
}
Alternatively, you can specify the node version in a browserslist query:
{
"targets": "node 12" // not recommended
}
Because Node.js may support new language features in minor releases, a program generated for Node.js 12.22 may throw a syntax error on Node.js 12.0. We recommend that you always specify a minor version.
{
"targets": "node 12.0"
}
Info coming from here!

The following will tell babel not to transform modules:
{
"presets": [
[
"#babel/preset-env",
{
"targets":{"node":"14"},
"modules": false,
}
]
]
}
Modules code produced in this manor will contain no inter-op glue. "modules": false is the key to this. Without it babel is very insistent on trans-piling to CommonJS compatible syntax. This option disables all module syntax transforms. This option drops the comp-ability glue and requires usage.

Related

How to use jsonapi-vuex [es6 module export] with Jest?

I'm trying to make use of the jsonapi-vuex npm package. I import it within my code like so:
import { jsonapiModule } from "jsonapi-vuex";
Jest however stumbles over this package. This package uses es6 modules. The index.js for that node module looks like this:
export { jsonapiModule, utils } from './src/jsonapi-vuex'
Jest fails on this even though babel-jest is installed with the following error:
Jest encountered an unexpected token
/node_modules/jsonapi-vuex/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export { jsonapiModule, utils } from './src/jsonapi-vuex'
^^^^^^
I've tried various things:
Tried adding to jest config so that just shouldn't ignore this library when transpiling:
transformIgnorePatterns: [
"<rootDir>/node_modules/(?!jsonapi-vuex)"
],
Tried the babel-plugin-transform-es2015-modules-commonjs plugin
As far as I can tell, babel-jest makes use of .babelrc. I have this configured with the #babel/preset-env preset, which is supposed to handle es6 modules... so I really don't understand why it is failing. Here's the .babelrc
{
"presets": [
[
"#babel/preset-env",
{
"modules": "commonjs",
"targets": {
"node": "current"
}
}
]
]}

Jest Is Not Transpiling ES6 Modules In Test (SyntaxError: Unexpected token export)

I'm at a boiling point with getting Jest to understand ES6 modules import/export syntax and it is hindering my project development progress. My project structure is the following:
root module
org-domain (ES6)
org-services (ES6)
react-ui-module (React via CRA2)
org-services has a local path dependency on org-domain in its package json:
// in org-services package.json
"dependencies": {
"#org/domain": "file:../org-domain",
},
My .babelrc in org-services is the following:
{
"env": {
"test": {
"presets": ["#babel/preset-flow", "#babel/preset-env"]
"plugins": ["#babel/plugin-transform-modules-commonjs"]
}
},
"presets": [
"#babel/preset-flow",
["#babel/preset-env", {
"targets": {
"esmodules": true
}
}]
],
"plugins": [
["module-resolver", {
"root": ["./node_modules/#org/domain"],
"alias": {
"#org/constants": "./node_modules/#org/domain/src/constants",
"#org/contracts": "./node_modules/#org/domain/src/request-contracts"
}
}]
]
}
I do not know if the problem is due to how I am including my dependencies so I'm going to add the finer details of anything related to my import/export of these modules for the sake of clarity.
In the implementation files of org-services I am importing org-domain using npm scoped syntax like so: import ... from '#org/domain
Here are some observations I have:
In local development, when I try to reference click #org/domain, instead of being directed to org-services/node_modules/#org/domain I get redirected to the actual relative directory location which is root/org-services. I believe Jest ignores node_modules (correct me if I am wrong) but in my jest.config.js for org-services, I have:
collectCoverage: true,
coverageDirectory: 'coverage',
coveragePathIgnorePatterns: [
'/node_modules/'
],
moduleDirectories: [
'src',
'node_modules'
],
moduleFileExtensions: [
'js'
],
transform: {
'^.+\\.js$': 'babel-jest'
},
transformIgnorePatterns: [
'node_modules/(?!#org/domain)$'
]
To my understanding, everything should just work right now with all the configuration I have with respect to setting the plugin #babel/plugin-transform-modules-commonjs in test (within .babelrc) and including the '^.+\\.js$': 'babel-jest' instruction under the transform key in jest.config.js located under org-services -- but it does not.
I have tried every single thing I could find online with respect to this issue with no success. I have not gotten anywhere since and my patience is lost with this testing framework and the lack of support for ES6. It should not be this hard, so clearly I am doing something wrong here. Please advise.
Update 1
Found another SO post that is a mirror of this situation I am in.
Jest fails to transpile import from npm linked module
Unfortunately, the provided solution does not work for my case.
After upgrading from #babel/xyz: 7.0.0 to 7.1.2 I started getting an error regarding "import"
Jest encountered an unexpected token
<snip>
Details:
C:\....\SstcStrategy.test.js:2
import sequelizeFixtures from 'sequelize-fixtures';
^^^^^^
SyntaxError: Unexpected token import
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
To fix this I had to add #babel/plugin-transform-modules-commonjs as you mention in your question.
My babel.config.js now looks like this:
module.exports = {
presets: [
[
'#babel/preset-env',
{
targets: {
node: '8.10',
},
debug: false,
},
],
],
ignore: ['node_modules'],
plugins: [
'#babel/plugin-transform-runtime',
'#babel/plugin-transform-modules-commonjs',
// Stage 2
['#babel/plugin-proposal-decorators', { legacy: true }],
'#babel/plugin-proposal-function-sent',
'#babel/plugin-proposal-export-namespace-from',
'#babel/plugin-proposal-numeric-separator',
'#babel/plugin-proposal-throw-expressions',
// Stage 3
'#babel/plugin-syntax-dynamic-import',
'#babel/plugin-syntax-import-meta',
['#babel/plugin-proposal-class-properties', { loose: false }],
'#babel/plugin-proposal-json-strings',
],
};
Also BTW you don't need to define babel-jest transform in jest.config.js as this is the default setting.
Hope this helps

Jest gives an error: "SyntaxError: Unexpected token export"

I'm using Jest to test my React app.
Recently, I added DeckGL to my app. My tests fail with this error:
Test suite failed to run
/my_project/node_modules/deck.gl/src/react/index.js:21
export {default as DeckGL} from './deckgl';
^^^^^^
SyntaxError: Unexpected token export
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:318:17)
at Object.<anonymous> (node_modules/deck.gl/dist/react/deckgl.js:9:14)
at Object.<anonymous> (node_modules/deck.gl/dist/react/index.js:7:15)
This looks like an issue with Jest transforming a node module before running it's tests.
Here is my .babelrc:
{
"presets": ["react", "es2015", "stage-1"]
}
Here is my jest setup:
"jest": {
"testURL": "http://localhost",
"setupFiles": [
"./test/jestsetup.js"
],
"snapshotSerializers": [
"<rootDir>/node_modules/enzyme-to-json/serializer"
],
"moduleDirectories": [
"node_modules",
"/src"
],
"moduleNameMapper": {
"\\.(css|scss)$": "<rootDir>/test/EmptyModule.js"
}
},
I seem to have the correct things necessary to transform export {default as DeckGL }. So any ideas whats going wrong?
This means, that a file is not transformed through TypeScript compiler, e.g. because it is a JS file with TS syntax, or it is published to npm as uncompiled source files. Here's what you can do.
Adjust your transformIgnorePatterns allowed list:
{
"jest": {
"transformIgnorePatterns": [
"node_modules/(?!#ngrx|(?!deck.gl)|ng-dynamic)"
]
}
}
By default Jest doesn't transform node_modules, because they should be valid JavaScript files. However, it happens that library authors assume that you'll compile their sources. So you have to tell this to Jest explicitly. Above snippet means that #ngrx, deck and ng-dynamic will be transformed, even though they're node_modules.
And if you are using 'create-react-app', it won't allow you to specify 'transformIgnorePatterns' via Jest property in package.json
As per this https://github.com/facebook/create-react-app/issues/2537#issuecomment-390341713
You can use CLI as below in your package.json to override and it works :
"scripts": {
"test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!your-module-name)/\"",
},
This is because Node.js cannot handle ES6 modules.
You should transform your modules to CommonJS therefore.
Babel 7 >=
Install
npm install --save-dev #babel/plugin-transform-modules-commonjs
And to use only for test cases add to .babelrc,
Jest automatically gives NODE_ENV=test global variable.
"env": {
"test": {
"plugins": ["#babel/plugin-transform-modules-commonjs"]
}
}
Babel 6 >=
npm install --save-dev babel-plugin-transform-es2015-modules-commonjs
to .babelrc
"env": {
"test": {
"plugins": ["transform-es2015-modules-commonjs"]
}
}
Jest by default won't compile files in the node_modules directory.
transformIgnorePatterns [array]
Default: ["/node_modules/"]
An array of regexp pattern strings that are matched against all source
file paths before transformation. If the test path matches any of the
patterns, it will not be transformed.Default: ["/node_modules/"]
DeckGL seems to be in ES6, to make jest able to read it, you need to compile this as well.
To do that, just add an exception for DeckGL in the transformignorePatterns
"transformIgnorePatterns": ["/node_modules/(?!deck\.gl)"]
https://facebook.github.io/jest/docs/en/configuration.html#transformignorepatterns-array-string
I was having this issue with a monorepo. A package in the root node_modules was breaking my tests. I fixed by changing my local .babelrc file to babel.config.js. Explanation: https://github.com/facebook/jest/issues/6053#issuecomment-383632515
It was work around #1 on this page that fixed it for me though workaround #2 on that page is mentioned in above answers so they may also be valid.
"Specify the entry for the commonjs version of the corresponding package in the moduleNameMapper configuration"
jest.config.js
moduleNameMapper: {
"^uuid$": require.resolve("uuid"),
"^jsonpath-plus$": require.resolve("jsonpath-plus")
...
In my case I use this config in the file package.json:
"jest": {
"transformIgnorePatterns": [
"!node_modules/"
]
}
This code worked for me
// .babelrc
{
"presets": [
["env", {
"modules": "commonjs", // <- Check and see if you have this line
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime"],
"env": {
"test": {
"presets": ["env", "stage-2"],
"plugins": ["transform-vue-jsx", "transform-es2015-modules-commonjs", "dynamic-import-node"]
}
}
}
jest understands commonJs so it needs babel to transform the code for it before use. Also jest uses caching when running code. So make sure you run jest --clearCache before running jest.
Tested Environment:
Node v8.13.0
Babel v6+
Jest v27
I'm using a monorepo (it contains multiple packages for the frontend and backend).
The package I'm testing imports a file from another package that uses the dependency uuid.
All the files are in Typescript (not Javascript).
The package I'm testing has a tsconfig file for testing only, called tsconfig.test.json. It has the properties commonjs and allowJs. Adding allowJs solves the problem when importing uuid, I don't know why.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": [
"jest",
"node"
],
// Necessary to import dependency uuid using CommonJS
"allowJs": true
},
"include": [
"jest.config.ts",
"**/*.test.ts",
"**/*.d.ts"
]
}
I was upgrading a project that uses a version of babel that reads the config from .babelrc, when I upgraded to a newer version I read:
https://babeljs.io/docs/en/configuration#whats-your-use-case
What's your use case?
You are using a monorepo?
You want to compile node_modules?
babel.config.json is for you!
On top of:
{
"jest": {
"transformIgnorePatterns": [
"node_modules/(?!(module))"
]
}
}
I renamed .babelrc to babel.config.json too.
I had the same error of importing dataSet from vis-data.js library
import { DataSet } from 'vis-data/esnext';
So I just removed /esnext from the path and now it works:
import { DataSet } from 'vis-data';

Use Jest and spread operator without babel?

Is it possible to use the spread operator in code with Jest and without babel if the node engine is 8+?
I am dropping support for Node.js <8 in my app and assumed I could remove all babel dependencies and transpiling from package.json, however npm run jest fails immediately with these types of errors:
FAIL test/workers/repository/onboarding.spec.js
● Test suite failed to run
/Users/me/project/lib/workers/repository/onboarding.js: Unexpected token (13:17)
11 |
12 | async function createOnboardingBranch(inputConfig) {
> 13 | let config = { ...inputConfig };
| ^
Is there any way to get Jest to work without needing to add back all the babel dependencies and configuration?
Node.js version: 8.9.0
Jest version: 20.0.4
jest config in package.json:
"jest": {
"cacheDirectory": ".cache/jest",
"coverageDirectory": "./coverage",
"collectCoverage": true,
"collectCoverageFrom": [
"lib/**/*.js"
],
"coverageReporters": [
"json",
"lcov",
"text-summary"
],
"setupTestFrameworkScriptFile": "./test/chai.js"
},
Edit:
I have been able to narrow my babel configuration down to just one plugin: babel-plugin-transform-object-rest-spread and configure babel in package.json like so:
"babel": {
"plugins": [
"transform-object-rest-spread"
]
},
Taking this out or attempting to use babel-preset env causes Jest to fail on the spread operator again.

need a correct eslintrc for async/await - using 7.6+ nodejs

With the latest version of nodejs 7.6+ I started using async/await.
I was using jshint but from what I read they currently do support this syntax and some suggested using eslint.
So ok I set eslint up but argh.. it flags async functions too.
Parsing error: Unexpected token init (Fatal)
I know there is nothing wrong as my code is running fine it's just the linter. Too if I comment out an async function it just flags the next one. IN fact eslint only flags the first async found with this error not all of them (what up with that?)
Here is the eslintrc file made using the init wizard. I was hoping just asking for node and es6 for env would be sufficient...apparently not.
module.exports = {
"env": {
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"rules": {
"indent": [
"error",
"tab"
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"never"
]
}
};
What is the fix?
I've tried several versions of .eslintrc and even saw there are a few issues related at the eslint repo but none are helping me to resolve this. I don't think it's a bug just missing something about getting eslint set up correctly for native nodejs using commonjs (no babel).
Who knows maybe babel plugin is required to make this work even though I am not using babel??? If that's true how do I set that up.
Since async/await is an ES2017 feature, you need to add that to your .eslintrc.js:
module.exports = {
// ...
"parserOptions": {
"ecmaVersion": 2017
},
// ...
}

Resources