Webpack babel 6 ES6 decorators - javascript

I've got a project written in ES6 with webpack as my bundler. Most of the transpiling works fine, but when I try to include decorators anywhere, I get this error:
Decorators are not supported yet in 6.x pending proposal update.
I've looked over the babel issue tracker, and haven't been able to find anything on it there, so I'm assuming I'm using it wrong. My webpack config (the relevant bits):
loaders: [
{
loader: 'babel',
exclude: /node_modules/,
include: path.join(__dirname, 'src'),
test: /\.jsx?$/,
query: {
plugins: ['transform-runtime'],
presets: ['es2015', 'stage-0', 'react']
}
}
]
I have no trouble with anything else, arrow functions, destructuring all work fine, this is the only thing that doesn't work.
I know I could always downgrade to babel 5.8 where I had it working a while ago, but if there's any way to get this working in the current version (v6.2.0), it would help.

This Babel plugin worked for me:
https://github.com/loganfsmyth/babel-plugin-transform-decorators-legacy
npm i --save-dev babel-plugin-transform-decorators-legacy
.babelrc
{
"presets": ["es2015", "stage-0", "react"],
"plugins": [
["transform-decorators-legacy"],
// ...
]
}
or
Webpack
{
test: /\.jsx?$/,
loader: 'babel',
query: {
cacheDirectory: true,
plugins: ['transform-decorators-legacy' ],
presets: ['es2015', 'stage-0', 'react']
}
}
React Native
With react-native you must use the babel-preset-react-native-stage-0 plugin instead.
npm i --save babel-preset-react-native-stage-0
.babelrc
{
"presets": ["react-native-stage-0/decorator-support"]
}
Please see this question and answer for a complete explanation.

After spending 5 minutes on the babeljs slack webchat, I found out that decorators are broken in the current version of babel (v6.2). The only solution seems to be to downgrade to 5.8 at this time.
It would also seem they moved their issue tracker from github to https://phabricator.babeljs.io
I write all this down, since after hours of searching I have found the current documentation very poor and lacking.

Installing only babel-plugin-transform-decorators-legacy didn't work for me (I have a configuration using enzyme along with karma). Turns out installing transform-class-properties: transform-class-properties and also making sure that the legacy plugin is before the transform class plugin as per the docs in transform-decorators-legacy finally made it work for me.
I'm also not using a .babelrc file, but adding this to my karma.conf.js file worked for me:
babelPreprocessor: {
options: {
presets: ['airbnb', 'es2015', 'stage-0', 'react'],
plugins: ["transform-decorators-legacy", "transform-class-properties"]
}
}
I also added it to my loaders:
loaders: [
{
test: /\.js$/,
loader: 'babel',
exclude: path.resolve(__dirname, 'node_modules'),
query: {
presets: ['airbnb', 'es2015', 'stage-0', 'react'],
plugins: ["transform-decorators-legacy", "transform-class-properties"]
}
},

You just need a transform decorators plugin: http://babeljs.io/docs/plugins/transform-decorators/

If you upgraded your project from Babel 6 to Babel 7, then you want to install #babel/plugin-proposal-decorators.
If you want to support legacy decorators as used in Babel 5, you need to configure your .babelrc as follows:
plugins: [
['#babel/plugin-proposal-decorators', { legacy: true }],
['#babel/plugin-proposal-class-properties', { loose: true }],
]
Ensure #babel/plugin-proposal-decorators comes before #babel/plugin-proposal-class-properties in the case that you are making use of the latter.

Related

How can I use Node.js CommonJS modules in ES6 import/export modules using babel or webpack?

I'm sorry if this is a duplicate (I looked hard using the search tool but nothing came close). Anyone has any ideas how to transpile Node.js CommonJS modules so they can be used within an ES6 import/export project?
I know there's #babel/plugin-transform-modules-commonjs which transpiles ES6 modules into CommonJS form, but I think I'm in need of the opposite. The reason I need this is I have a config file written using Node's module.exports syntax that needs to be imported within a React project built with babel using ES6 modules, but I get a Uncaught TypeError: Cannot assign to read only property 'exports' of object error. Any ideas would be greatly appreciated.
Here's my babelrc.js file:
module.exports = {
presets: ['#babel/preset-env', '#babel/preset-react'],
plugins: [
['#babel/plugin-proposal-class-properties', { loose: true }],
['#babel/plugin-transform-runtime', { regenerator: true }],
'#babel/plugin-syntax-dynamic-import',
'#babel/plugin-proposal-optional-chaining'
],
env: {
production: {
plugins: [
[
"transform-react-remove-prop-types",
{ removeImport: true }
],
]
}
}
}
And my webpack config babel loader rule:
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true,
cacheCompression: false,
envName: isModeProduction ? 'production' : 'development'
}
}
]
},
Thanks to #Thomas Sablik's comment, I found out this was a known webpack issue.
And after poking round and looking up this error, I found this answer on another Stack Overflow which helped me fix it by adding "sourceType": "unambiguous" to my babel configuration.
https://stackoverflow.com/a/56283408/2942765
Thank you Thomas.

Use Template Strings with webpack [Javascript]

I'm fairly new to webpack, and when compiling my code I came across this error.
ERROR in Error: Child compilation failed:
Module build failed (from ../node_modules/html-loader/index.js):
Error: Line 539: Unexpected identifier
And this is the line that its referring too.
return `background: linear-gradient(to bottom right, ${this.gradientStart}, ${this.gradientEnd});`
Is it possible to allow Template Strings in Webpack?
This is the inside of my webpack config
const html = {
test: /\.(html)$/,
// exclude: /\.html$/,
use: [
{
loader: 'html-loader',
options: {
interpolate: true,
},
},
],
};
Template strings are a feature of es2015. Webpack does not understand es2015 by default to ensure compatibility with as many legacy devices as possible. You need to use a loader that will transpile es2015 into an older version of javascript. You can use "babel-loader" with the preset webpack environment that has support for many features of modern javascript.
You need to download #babel/core & #babel/preset-env for webpack by running the following command:
npm install --save-dev -D babel-loader #babel/core #babel/preset-env webpack
You need to add the following to your webpack.config.js
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
}
]
},

webpack babel loader with eslint loader

I'm using webpack babel-loader with es-lint like so
{
test: /\.(js)$/,
exclude: /node_modules/,
use: ['babel-loader', 'eslint-loader'],
},
however in the babel-loader i see on webpack that i have to pass options like so
options: {
presets: ['#babel/preset-env']
}
but since i'm using an array of loaders i can't use this option, or since i'm using eslint with babel loader i don't need this #babel/preset env ?
You may still want to use #babel/preset even with eslint-loader
#babel/preset-env is a smart preset that allows you to use the latest JavaScript without needing to micromanage which syntax transforms (and optionally, browser polyfills) are needed by your target environment(s). This both makes your life easier and JavaScript bundles smaller! (source)
The eslint-loader will make all code bundled by Webpack syntax checked by eslint (following your eslint config).
You can either keep babel configuration in a separate file .babelrc.json:
{
presets: [
'#babel/preset-env'
]
}
or use the webpack configuration:
use: [{
loader: 'babel-loader',
options: { presets: ['#babel/preset-env'] },
}, {
loader: 'eslint-loader'
}]

How to resolve 'class constructor cannot be invoked without new' error when building with svelte, babel, and webpack

I'm trying to get svelte, webpack, and babel to work together. I am producing the minified bundle, however, this bundle is throwing errors upon loading it up in the browser. This needs to be compatible with IE11 while using ES6 syntax.
I get
Class constructor I cannot be invoked without 'new'
The pertinent parts of my webpack looks as follows
{
test: /\.(js|jsx|mjs|svelte)?$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
configFile: path.resolve(__dirname, 'babel.config.js')
}
}
]
},
{
test: /\.svelte$/,
exclude: /node_modules/,
use: {
loader: "svelte-loader",
options: {
emitCss: false,
hotReload: false
},
},
},
babel.config is as follows
module.exports = {
plugins: [
'#babel/plugin-proposal-class-properties',
'angularjs-annotate',
'lodash'
],
presets: [
['#babel/preset-env', {
useBuiltIns: 'usage',
corejs: { version: 3, proposals: true }
}],
'#babel/preset-react'
]
};
The svelte file itself is pretty basic
<script>
export let name = "World";
</script>
<h1>Hello {name}!</h1>
UPDATE
I can get it to run by excluding transform-classes in babel config
exclude: ['transform-classes'],
However, this of course breaks IE11.
You will need to update the webpack-cli and html-webpack-plugin versions in your package.json:
"webpack-cli": "^4.5.0",
"html-webpack-plugin": "^5.1.0",
Then, delete your node_modules and package-lock.json files and run a new npm install
Simply do this:
$ yarn remove webpack-cli && yarn add --dev webpack-cli
This will remove the old cli version, re-install the new one and compile everything afresh. Problem solved

Babel 6 presets specified in .babelrc not working

as the title suggests, basically according to the docs, with the new Babel 6 we are now supposed to pass in plugins/presets since by default it would not do anything with our code.
So I created a .babelrc file in my project directory with the following (just like in the docs)
{
"presets": ["es2015"]
}
However this would not work.
Since I'm using webpack and babel-loader, I came across a different answer that suggested to put something like this in the webpack config:
{
test: /\.js$/, exclude: /node_modules/, loader: "babel", query: {
presets: ["es2015"]
}
}
And this works.
So my question is whether this is a bug in the new Babel or there is something obviously wrong that I'm missing? I used to use Babel 5 and Webpack, and I was able to specify the babel config in .babelrc no problem...
Thanks in advance
EDIT: The problem only occurred when running the eslint loader before the babel loader. However just updated to latest babel-loader 6.2.0 and everything is working again.
module: {
preLoaders: [
{ test: /\.js$/, exclude: /node_modules/, loader: "eslint"}
],
loaders: [
{ test: /\.js$/, exclude: /node_modules/, loader: "babel"},
{ test: /\.css$/, exclude: /node_modules/, loader: "style!css!postcss"}
It seems to be a problem with babel-loader. It should be fixed in release 6.1.0.
You can see the release/v6.1.0 summary:
* release/v6.1.0:
Update CHANGELOG.md and package.json
Set source file name relative to options.sourceRoot
Allow babelrc to be specified for cache purposes
Add BABEL_ENV || NODE_ENV to default cacheIdentifier
So updating babel-loader will suffice.

Categories

Resources