Why should I put babel presets inside .babelrc and webpack.config.js?

Ok I am downloading a simple application. I am using flow.js. The presets that I use are babel-preset-2015, babel-preset-react and babel-preset-stage-0. I have to put the same presets inside my .babelrc and inside my webpack.config for this to work. If, for example, I pulled them out of webpack.config, I get the error message "React is not defined". If I remove .babelrc and babel-register, I get an error because I use import and Flow.js. annotations Why is this happening? If I put presets in the webpack.config file, I have to delete .babelrc or vice versa. This is what my code looks like now, when it all works (minus some files that are not important for the question).

start-dev.js

require('babel-register') require('./src/server/index.js') 

index.js

 /* @flow */ import Express from 'express' import path from 'path' import conf from '../conf/' const APP_PORT: number = conf.APP_PORT const PORT = process.env.PORT || APP_PORT const app: Express = new Express() // Middleware app.set('views', path.join(__dirname, 'views')) app.set('view engine', 'ejs') app.use(Express.static(path.join(__dirname, '../', 'client', 'dist'))) // Routes app.get('*', function (req: Object, res: Object) { res.render('index') }) app.listen(PORT, function () { console.log(`Express server is up on port ${PORT}`) }) 

app.js

 import React from 'react' import ReactDOM from 'react-dom' ReactDOM.render( <h1>First</h1>, document.getElementById('app') ) 

package.json

 { "scripts": { "start-dev": "set \"NODE_ENV=development\" && babel-node ./start-dev.js", "start": "set \"NODE_ENV=development\" && node ./start-dev.js", "flow": "./node_modules/.bin/flow check", "standard": "node_modules/.bin/standard --verbose | node_modules/.bin/snazzy" }, "dependencies": { "ejs": "^2.5.6", "express": "^4.15.2", "react": "^15.4.2", "react-dom": "^15.4.2" }, "devDependencies": { "babel-cli": "^6.24.0", "babel-core": "^6.24.0", "babel-eslint": "^7.2.1", "babel-loader": "^6.4.1", "babel-preset-es2015": "^6.24.0", "babel-preset-react": "^6.23.0", "babel-preset-stage-0": "^6.22.0", "babel-register": "^6.24.0", "eslint": "^3.18.0", "eslint-config-standard": "^7.1.0", "eslint-plugin-flowtype": "^2.30.4", "eslint-plugin-react": "^6.10.3", "flow-bin": "^0.42.0", "snazzy": "^6.0.0", "standard": "^9.0.2", "webpack": "^2.3.2" } } 

.babelrc

 { "passPerPreset": true, "presets": [ "es2015", "react", "stage-0" ] } 

webpack.config.babel.js

 'use strict' import path from 'path' const publicPath = path.resolve(__dirname, './src/client') module.exports = { devtool: '#source-maps', performance: { hints: false }, context: publicPath, entry: { bundle: './app.js' }, output: { path: path.join(publicPath, 'dist'), filename: '[name].js', publicPath: '/dist/' }, resolve: { extensions: ['.js', '.jsx'] }, module: { rules: [ { test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel-loader', options: { presets: [ 'react', 'es2015', 'stage-0' ] } } ] } } 
+5
source share
2 answers

If I put presets inside webpack.config, I could remove .babelrc or vice versa.

No, it is not. Specifying presets in the webpack configuration only affects webpack, everything else using babel (e.g. babel-node , babel-register , etc.) does not care about your webpack configuration and therefore does not see them.

Quite the contrary. This way you can remove the webpack preset options if you have .babelrc , because babel-loader uses babel under the hood, which obviously respects .babelrc .

If, for example, I delete them from webpack.config, I get a React is not defined error message.

The problem is that your .babelrc configuration .babelrc different from the configuration in the webpack configuration. Offender "passPerPreset": true . With this option, each preset is applied individually, without regard to others. And for that, order matters. From babel docs - plugin / pre-order :

Preset ordering is canceled (last to first).

This means that they will be applied in the following order: stage-0 , react , es2015 . Since they are used individually, react converts JSX to React.createElement , because react is in scope, and es2015 only converts imports to _react2.default , so react no longer defined. The whole difference between the two bundles is as follows:

 @@ -9470,7 +9470,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de // var React = require('react') // var ReactDOM = require('react-dom') -_reactDom2.default.render(React.createElement( +_reactDom2.default.render(_react2.default.createElement( 'h1', null, 'Juhuuuu' 

There is not much information about passPerPreset , but it has been flagged as experimental in the Release Notes , and you should probably avoid it at all.

Although this will work if you put the pre-installed react in the list, I would recommend removing the passPerPreset parameter if you have no particular reason to use it.

 { "presets": [ "es2015", "react", "stage-0" ] } 
+11
source

Try changing your forklift, for example

 module: { rules: [ { test: /\.jsx?$/, exclude: [/node_modules/], use: [{ loader: 'babel-loader', options: { presets: ['react','es2015', 'stage-0'] } }], } ] } 
0
source

Source: https://habr.com/ru/post/1266304/


All Articles