I'm using react and I'm trying to use the spread syntax. For some reason it doesn't work and it gives an error:
const { className, children, ...otherprops } = this.props;
Any idea what I'm doing wrong?
You are getting Unexpected token because you are missing one babel preset, stage-0
With stage-0, it works
Without stage-0, it doesn't work
In order to add it, you have to
1º Install it
npm install --save-dev babel-preset-stage-0
2º Add it to .babelrc
{
"presets": ["react","es2015","stage-0"]
}
Related
I have a Vue.js application where two files contain:
import axios from "axios"
These files are located in src/lib within the application and include the import statement on their first line.
Running tests on Github causes Axios 1.0.0 to be installed, no matter what the package.json says, and now any test involving these files fails with the above error.
Changing the statement to const axios = require("axios") fails also; node_modules/axios/index.js contains an import statement on line 1 and the exception is thrown there.
A suggestion I've seen quite often for such issues is to add "type": "module" to package.json (which is at the same level as src/). This causes all tests to fail with a demand to rename vue.config.js as vue.config.cjs. Doing that gets me: Error: You appear to be using a native ECMAScript module configuration file, which is only supported when running Babel asynchronously, which I do not understand.
Can anyone suggest what to do here?
I was able to fix this error by forcing jest to import the commonjs axios build by adding
"jest": {
"moduleNameMapper": {
"axios": "axios/dist/node/axios.cjs"
}
},
to my package.json. Other solutions using transformIgnorePatterns didn't work for me.
The 1.x.x version of axios changed the module type from CommonJS to ECMAScript.
The 0.x.x version of axios index.js file
module.exports = require('./lib/axios');
The 1.x.x version of axiox index.js file
import axios from './lib/axios.js';
export default axios;
Basically, jest runs on Node.js environment, so it uses modules following the CommonJS.
If you want to use axios up to 1.x.x, you have to transpile the JavaScript module from ECMAScript type to CommonJS type.
Jest ignores /node_modules/ directory to transform basically.
https://jestjs.io/docs/27.x/configuration#transformignorepatterns-arraystring
So you have to override transformIgnorePatterns option.
There are two ways to override transformIgnorePatterns option.
jest.config.js
If your vue project uses jest.config.js file, you add this option.
module.exports = {
preset: "#vue/cli-plugin-unit-jest",
transformIgnorePatterns: ["node_modules/(?!axios)"],
...other options
};
package.json
If your vue project uses package.json file for jest, you add this option.
{
...other options
"jest": {
"preset": "#vue/cli-plugin-unit-jest",
"transformIgnorePatterns": ["node_modules\/(?!axios)"]
}
}
This regex can help you to transform axios module and ignore others under node_modules directory.
https://regexper.com/#node_modules%5C%2F%28%3F!axios%29
Updating the version of jest to v29 fixed this in my project. It could be the case that you have an incompatible jest version.
I had the same issues and was able to solve this by using jest-mock-axios library
I experience similar problem but the error is caused by jest.
All the tests trying to import axios fail and throw the same exception:
Test suite failed to run
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
/monorepo/node_modules/axios/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import axios from './lib/axios.js';
^^^^^^
SyntaxError: Cannot use import statement outside a module
1 | import { describe, expect, it } from '#jest/globals'
> 2 | import axios from 'axios'
The solution is simply tell jest that axios should be transformed with babel:
const esModules = ['lodash-es', 'axios'].join('|')
# add these entries in module.exports
transform: {
[`^(${esModules}).+\\.js$`]: 'babel-jest',
},
transformIgnorePatterns: [`node_modules/(?!(${esModules}))`],
Note: I'm using Quasar Vue and this is their implementation.
Quick fix
Update the npm run test script from
"test": "react-scripts test",
to
"test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!axios)/\"",
In my case I had to add the following line to the moduleNameMapper object in the jest config:
axios: '<rootDir>/node_modules/axios/dist/node/axios.cjs',
I had the same issue, it works fine when changing axios to fetch.
axios (Fail)
try {
const response = await axios("api/fruit/all");
return response.data;
} catch (error) {
return error;
}
Fetch (Works fine)
try {
const response = await fetch("api/fruit/all",{method:"GET"});
const data = await response.json();
return data;
} catch (error) {
return error;
}
I use grunt-babel to compile my ES6 code. But it returns Warning: dist/app.js: Unexpected token (321:9) Use --force to continue. when I try to use {...obj} to copy and extend object. Following code is working perfect in console of Chrome v61 but Babel doesn't like it. What is the problem?
let a = { a: 12 };
let b = { ...a, b: 15 };
I am using env preset. (babel-core v.6.26.0 and babel-preset-env v.1.6.1)
The spread property for objects is not part of ES6. Currently, as of Dec 2017, it is part of the stage 3 proposal for ECMAScript. You can have a look at the proposal here.
You need a babel preset that includes features not yet officially in the language. The babel-preset-env does not include those features.
To solve your problem, you could use something like babel-preset-stage-3 and add "stage-3" to the list of presets in your .babelrc.
Side note:
An alternative to the spread syntax for objects in ES6 is to use Object.assign
let b = Object.assign({}, a, { b: 15 });
You probably would want to add these plugins to your .babelrc. This Github issue has a lot of solutions unexpected token (rest spread operator). I am trying these out now.
{
"presets": ["react", "es2015"],
"plugins": ["transform-es2015-destructuring", "transform-object-rest-spread"]
}
npm install --save-dev babel-plugin-transform-es2015-destructuring
npm install --save-dev babel-plugin-transform-object-rest-spread
I am testing using Jest and my appication is running on Next.js... I am trying to test a page component in my Next application, but I am receiving errors that are shown in the following screenshot; The "Before" image is before I tried implementing a solution found on Stackoverflow, and the "After" is after the solution was implemented. I am still stuck and need some friendly help!
Here is also my current Jest config in my package.json
"jest": {
"setupFiles": ["./shim.js", "./setupTests.js"],
"verbose": true,
"moduleNameMapper": {
"^.+\\.(css|scss)$": "./cssStub.js"
}
}
Thanks!
I'm using CSS modules and it convenient for me to use "proxy" as if the code requires styles, jest will return a proxy, that will return the required field name instead of the value.
For example:
import * as styles from './styles.scss';
console.log(styles.someClassName);
// the proxy in that case will return a string with `someClassName` value.
All you need to configure is install
npm install --save-dev identity-obj-proxy
and add
"moduleNameMapper": {
"\\.(css|scss)$": "identity-obj-proxy",
}
to your Jest section in the package.json file.
Edit
Pay attention that according to the docs you should use <rootDir>
when you are mapping to a file.
"\\.(css|scss)$": "<rootDir>/cssStub.js.js",
My issue was silly enough that I wrongly specified my <rootDir> path. I would suggest reading the solution from this post for further details to how to resolve similar issue... Thanks all for the help!
SyntaxError with Jest and React and importing CSS files
I use React.js, Webpack, ...props syntax, arrow functions.
When I run "npm run build", I get this error:
ERROR in bundle.js from UglifyJs
SyntaxError: Unexpected token punc «(», expected punc «:» [bundle.js:77854,15]
Here is my debug.log
My webpack.config
How to run build successfully?
I found the line which causes the bug, here it is:
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';
I don't know why. :(
Without it, all my ES6 syntax works and compiled without any errors.
Any Help please
This error happens if you use have an npm dependency that has ES6 syntax. It happended to me, too, with Preact (see https://github.com/developit/preact-compat/issues/155).
You can fix it by adding the dependency explicitly to the modules that are loaded through babel, like so:
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
include: [
srcPath,
// we need to include preact-compat
// otherwise uglify will fail
// #see https://github.com/developit/preact-compat/issues/155
path.resolve(__dirname, '../../../node_modules/preact-compat/src')
]
}
]
}
In bundle.js, line 77854, character 15, there is a parenthese after a object properties name, instead of a :.
There must be something like :
{property () {}}
instead of
{property : function () {}}
Edit (thanks to #handoncloud): The first is valid ES6, and is a shorthand for the second, that is the equivalent in ES5.
The problem is, that the build does not fully support ES6.
Found it.
React-Bootstrap-Table have a dependency named React-Modal.
I installed React Modal by npm install react-modal without --save or --save-dev. So React-Modal wasn't not listed in my package.json.
Now everything is ok.
SOLUTION : npm install react-modal --save
I just started to use Babel to compile my ES6 javascript code into ES5. When I start to use Promises it looks like it's not working. The Babel website states support for promises via polyfills.
Without any luck, I tried to add:
require("babel/polyfill");
or
import * as p from "babel/polyfill";
With that I'll get the following error on my app bootstrapping:
Cannot find module 'babel/polyfill'
I searched for the module but it seems I'm missing some fundamental thing here. I also tried to add the old and good bluebird NPM but it looks like it's not working.
How to use the polyfills from Babel?
This changed a bit in babel v6.
From the docs:
The polyfill will emulate a full ES6 environment. This polyfill is automatically loaded when using babel-node.
Installation:
$ npm install babel-polyfill
Usage in Node / Browserify / Webpack:
To include the polyfill you need to require it at the top of the entry point to your application.
require("babel-polyfill");
Usage in Browser:
Available from the dist/polyfill.js file within a babel-polyfill npm release. This needs to be included before all your compiled Babel code. You can either prepend it to your compiled code or include it in a <script> before it.
NOTE: Do not require this via browserify etc, use babel-polyfill.
The Babel docs describe this pretty concisely:
Babel includes a polyfill that includes a custom regenerator runtime
and core.js.
This will emulate a full ES6 environment. This polyfill is
automatically loaded when using babel-node and babel/register.
Make sure you require it at the entry-point to your application, before anything else is called. If you're using a tool like webpack, that becomes pretty simple (you can tell webpack to include it in the bundle).
If you're using a tool like gulp-babel or babel-loader, you need to also install the babel package itself to use the polyfill.
Also note that for modules that affect the global scope (polyfills and the like), you can use a terse import to avoid having unused variables in your module:
import 'babel/polyfill';
For Babel version 7, if your are using #babel/preset-env, to include polyfill all you have to do is add a flag 'useBuiltIns' with the value of 'usage' in your babel configuration. There is no need to require or import polyfill at the entry point of your App.
With this flag specified, babel#7 will optimize and only include the polyfills you needs.
To use this flag, after installation:
npm install --save-dev #babel/core #babel/cli #babel/preset-env
npm install --save #babel/polyfill
Simply add the flag:
useBuiltIns: "usage"
to your babel configuration file called "babel.config.js" (also new to Babel#7), under the "#babel/env" section:
// file: babel.config.js
module.exports = () => {
const presets = [
[
"#babel/env",
{
targets: { /* your targeted browser */ },
useBuiltIns: "usage" // <-----------------*** add this
}
]
];
return { presets };
};
Reference:
usage#polyfill
babel-polyfill#usage-in-node-browserify-webpack
babel-preset-env#usebuiltins
Update Aug 2019:
With the release of Babel 7.4.0 (March 19, 2019) #babel/polyfill is deprecated. Instead of installing #babe/polyfill, you will install core-js:
npm install --save core-js#3
A new entry corejs is added to your babel.config.js
// file: babel.config.js
module.exports = () => {
const presets = [
[
"#babel/env",
{
targets: { /* your targeted browser */ },
useBuiltIns: "usage",
corejs: 3 // <----- specify version of corejs used
}
]
];
return { presets };
};
see example: https://github.com/ApolloTang/stackoverflow-eg--babel-v7.4.0-polyfill-w-core-v3
Reference:
7.4.0 Released: core-js 3, static private methods and partial
application
core-js#3, babel and a look into the future
If your package.json looks something like the following:
...
"devDependencies": {
"babel": "^6.5.2",
"babel-eslint": "^6.0.4",
"babel-polyfill": "^6.8.0",
"babel-preset-es2015": "^6.6.0",
"babelify": "^7.3.0",
...
And you get the Cannot find module 'babel/polyfill' error message, then you probably just need to change your import statement FROM:
import "babel/polyfill";
TO:
import "babel-polyfill";
And make sure it comes before any other import statement (not necessarily at the entry point of your application).
Reference: https://babeljs.io/docs/usage/polyfill/
First off, the obvious answer that no one has provided, you need to install Babel into your application:
npm install babel --save
(or babel-core if you instead want to require('babel-core/polyfill')).
Aside from that, I have a grunt task to transpile my es6 and jsx as a build step (i.e. I don't want to use babel/register, which is why I am trying to use babel/polyfill directly in the first place), so I'd like to put more emphasis on this part of #ssube's answer:
Make sure you require it at the entry-point to your application,
before anything else is called
I ran into some weird issue where I was trying to require babel/polyfill from some shared environment startup file and I got the error the user referenced - I think it might have had something to do with how babel orders imports versus requires but I'm unable to reproduce now. Anyway, moving import 'babel/polyfill' as the first line in both my client and server startup scripts fixed the problem.
Note that if you instead want to use require('babel/polyfill') I would make sure all your other module loader statements are also requires and not use imports - avoid mixing the two. In other words, if you have any import statements in your startup script, make import babel/polyfill the first line in your script rather than require('babel/polyfill').
babel-polyfill allows you to use the full set of ES6 features beyond
syntax changes. This includes features such as new built-in objects
like Promises and WeakMap, as well as new static methods like
Array.from or Object.assign.
Without babel-polyfill, babel only allows you to use features like
arrow functions, destructuring, default arguments, and other
syntax-specific features introduced in ES6.
https://www.quora.com/What-does-babel-polyfill-do
https://hackernoon.com/polyfills-everything-you-ever-wanted-to-know-or-maybe-a-bit-less-7c8de164e423
Like Babel says in the docs, for Babel > 7.4.0 the module #babel/polyfill is deprecated, so it's recommended to use directly core-js and regenerator-runtime libraries that before were included in #babel/polyfill.
So this worked for me:
npm install --save core-js#3.6.5
npm install regenerator-runtime
then add to the very top of your initial js file:
import 'core-js/stable';
import 'regenerator-runtime/runtime';