Should I Configure Babel Through .babelrc or WebPack? - reactjs

In my react project, webpack.config.js brings in proposal-class properties like so:
...
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
query: {
presets: ['#babel/react', '#babel/preset-env'],
plugins: ['#babel/proposal-class-properties']
}
},
}
...
By including #babel/proposal-class-properties I'm able to remove the constructors from my React components, etc.
However, the documentation shows plugin-proposal-class-properties in .babelrc as follows (and doesn't mention webpack.config.js at all):
{
"plugins": ["#babel/plugin-proposal-class-properties"]
}
whereas my .babelrc does not include any plugins at all:
{
"presets": [
["#babel/env", {
"modules": false
},
"#babel/preset-env"]
]
}
Is there any effective difference between including the plugins (such as proposal-class-properties) in webpack.config.js as compared to putting them in .babelrc?

You can configure babel through .babelrc or through the babel-loader configuration in webpack. They both work exactly the same.
However, I recommend only using .babelrc for configuring babel.
That way it can also work when you run your tests, which usually don't go through webpack and will therefore not have the webpack configuration for babel.
.babelrc:
{
"presets": ["#babel/preset-env"]
"plugins": ['#babel/plugin-proposal-class-properties', {'loose': true}]
}

Related

Unable to use the spread operator after ejecting create-react-app

I used create-react-app to create a react application.
After I run eject, I am unable to use the spread operator as follows:
//eslint-disable-next-line
const { children, ...attributes } = this.props; //Line 19
It keeps giving me this error when I run yarn start
Line 19: Parsing error: Unexpected token ..
Webpack Dev Server
I have tried adding all the presets and the transform plugin to both webpack dev server config and .babelrc but no luck
// Process JS with Babel.
{
test: /\.(js|jsx|mjs)$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
presets:['react','es2015','env',"stage-2"],
plugins: ["transform-object-rest-spread"],
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
},
},
// "postcss" loader app
And in the babel rc file as well
//.babelrc
{
"presets":["env","react","stage-2"],
"plugins": [
["transform-object-rest-spread", { "useBuiltIns": true }]
]
}
It works fine if I don't eject the script.
So the problem turned out to be eslint.
Webpack config was loading it before babel
Adding parser options fixed it.
{
test: /\.(js|jsx|mjs)$/,
enforce: 'pre',
use: [
{
options: {
formatter: eslintFormatter,
eslintPath: require.resolve('eslint'),
"extends": "airbnb",
"parserOptions":{
"ecmaFeatures": {
"experimentalObjectRestSpread": true
}
}
},
loader: require.resolve('eslint-loader'),
},
],
include: paths.appSrc,
},
Updated the #babel with this:
npm install #babel/runtime#latest did the work

How to configure Webpack with babel to recognize static properties of class?

Each of my models has its own static property, but with current configurations they are undefined.
Here is my .babelrc
{
"presets": ["#babel/preset-react","#babel/typescript","#babel/env"],
"plugins": ["#babel/plugin-proposal-class-properties", "#babel/transform-runtime","#babel/plugin-transform-classes"]
}
Webpack conf
{
test: /\.(js|jsx|mjs|ts|tsx)$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
compact: true,
},
},
P.S this is ejected configuration from create-react-app

Webpack 4 as JSX files

Is there a way to load JSX files on Webpack 4?
I tried:
module.exports = {
resolve: {
extensions: [".jsx", ".js"]
}
}
But apparently my src/index.jsx file is loaded but not processed.
What you have here is half of it. resolve.extensions lets you
require('./my-module.jsx')
without having to type in the .jsx portion. ie
require('./my-module')
However, as you noted - the source is not processed in any way so if you have syntax that needs to be transpiled such as jsx, you'll need to take care of that.
Webpack by default won't do this for you, you'll need to use babel-loader with a preset or plugin that will transform the syntax. There's a lot of tutorials how to do that but it would look something like this:
module: {
rules: [{
exclude: /node_modules/, // don't transpile node_modules
test: /\.jsx$/, // do transpile any files ending in .jsx
use: {
loader: 'babel-loader',
options: {
plugins: ['#babel/plugin-transform-react-jsx']
}
}
}]
}
you need to install
npm i #babel/preset-react --save
add this to .babelrc file inside presets array. We use loaders inside module property of the webpack.config object because loaders are effective on one type of files whereas plugins are effective on the entire bundle.
.babelrc
{
"presets": [
["#babel/preset-env", { "targets": { "esmodules": true } }],
"#babel/preset-react"
],
all webpack projects needs #babel/preset-env. you might install that as well.
}

How do I configure Webpack to support ES7 Decorators [duplicate]

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.

How to disable strict mode while bundling React using webpack

Hello I am stuck with my application, my application working fine in all other browser not in IE it's throw the error
0x800a0416 - JavaScript runtime error: Multiple definitions of a property not allowed in strict mode
I have implemented loader in webpack.config
module: {
loaders: [{
test: /\.js?$/,
exclude: /(node_modules|bower_components)/,
loaders: ['babel'],
include: path.join(__dirname, 'scripts')
}]
}
and my Package.json Script contain "build": "./node_modules/.bin/webpack --config webpack.config.production.js --progress --profile --colors", for build the bundle
If I will explicitly find use strict and remove it from bundle then it works fine so how can I remove that strict mode while create a bundle using webpack
If you're seeing that error then most likely you've got somewhere in your codebase where you're declaring multiple properties on the same object. Disabling the alarm bell just fixes the symptom.
I've found this error to pop up if I declare duplicate properties in my JSX, e.g. when doing <MyComponent className="foo" onClick={onClick} className="foobar" /> or accidentally duplicating some other property.
Find and fix the actual error instead of just suppressing the error message. IE should tell you what line it's happening on and it shouldn't be too hard to look at what's there and figure out which component has the problem.
Check out this package: https://www.npmjs.com/package/babel-plugin-transform-remove-strict-mode
I was looking for a convenient way to get rid of the 'use strict' and it seems to be doing just that.
I have include the blacklist option in my .babelrc file like
blacklist: ["useStrict"]
and it's working fine.
You have few ways around this, bottom line setting modules to false either in .babelrc or your webpack since you use webpack
webpack.mix.js
module : {
loaders : [
{
test: /\.js?/,
include: APP_DIR,
use: {
loader: 'babel-loader',
options: {
"presets": [
['es2015', {modules: false}]
],
}
},
exclude: /node_modules/
},
]
},
or .babelrc
{
"presets": [
[
"#babel/preset-env",
{
"debug": true,
"modules": false,
"forceAllTransforms": true,
"useBuiltIns": "usage"
}
]
]
}

Resources