为什么我必须将babel-presets放在.babelrc和webpack.config.js中? [英] why do I have to put babel-presets inside .babelrc and webpack.config.js?

查看:101
本文介绍了为什么我必须将babel-presets放在.babelrc和webpack.config.js中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的.我正在引导一个简单的应用程序.我正在使用flow.js.我使用的预设是babel-preset-2015,babel-preset-react和babel-preset-stage-0.我必须在.babelrc中和webpack.config中放入相同的预设,所有这些预设才能正常工作.例如,如果我从webpack.config中将它们移动,则会收到错误消息未定义反应".如果删除.babelrc和babel-register,则会出现错误,因为我使用import和Flow.js批注.为什么会这样呢?如果我将预设放入webpack.config中,则应该可以删除.babelrc,反之亦然.这就是我的代码现在全部正常工作的样子(减去一些对该问题不重要的文件).

Ok. I am bootstraping a simple app. I am using flow.js. Presets that I use are babel-preset-2015, babel-preset-react and babel-preset-stage-0. I have to put same presets inside my .babelrc and inside my webpack.config for it all to work. If I for example romove them from webpack.config I get an error 'React is not defined'. If I remove .babelrc and babel-register I get an error because I use import and Flow.js annotation. Why is this happening? If I put presets inside webpack.config I should be able to delete .babelrc or vice verse. This is how my code looks 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'
          ]
        }
      }
    ]
  }
}

推荐答案

如果将预设放入webpack.config中,则应该可以删除.babelrc,反之亦然.

不,不是这样.在webpack配置中指定预设只会影响webpack,使用babel的其他所有内容(例如babel-nodebabel-register等)都不会关心您的webpack配置,因此看不到它们.

No, this is not the case. Specifying the presets in the webpack config will only affect webpack, everything else that uses babel (e.g. babel-node, babel-register, etc.) will not care about your webpack config and therefore doesn't see them.

反之亦然.因此,如果有.babelrc,则可以删除webpack预设选项,因为babel-loader在后台使用babel,这显然会尊重.babelrc.

The other way around does work. So you can remove the webpack presets options if you have a .babelrc, because babel-loader uses babel under the hood, which obviously respects the .babelrc.

例如,如果我从webpack.config中将其删除,则会出现错误React is not defined.

问题是您的.babelrc配置与webpack配置中的配置不同.罪魁祸首是"passPerPreset": true.使用此选项,每个预设都单独应用,而无需考虑其他预设.因此,顺序很重要.从婴儿文档-插件/预设排序:

The problem is that your .babelrc configuration is different from the configuration in the webpack config. The culprit is "passPerPreset": true. With this option every preset is applied individually without considering the others. And for this the order matters. From the babel docs - Plugin/Preset Ordering:

预设顺序相反(从最后到第一).

Preset ordering is reversed (last to first).

这意味着将按以下顺序应用它们:stage-0reactes2015.由于它们分别应用,因此react会将JSX转换为React.createElement,因为React在范围内,而es2015则仅将导入转换为_react2.default,因此不再定义React.两个束之间的整个差异是这样的:

This means they will be applied in the following order: stage-0, react, es2015. As they are applied individually, react will transform the JSX to React.createElement, because React is in scope, and es2015 will transform just the import to _react2.default, therefore React is no longer defined. The entire diff between the two bundles is this:

@@ -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'

关于passPerPreset的信息不多,但是在

There isn't much information about passPerPreset, but it was labelled experimental in the Release notes and you should probably avoid it altogether.

尽管将react预设放在列表的首位也可以,但是我建议删除passPerPreset选项,除非您有非常特殊的理由使用它.

Although it would work if you put the react preset first in the list, I'd recommend to remove passPerPreset option, unless you have a very specific reason to use it.

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

这篇关于为什么我必须将babel-presets放在.babelrc和webpack.config.js中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆