如何使用 React 和 Webpack 设置 Babel 6 stage 0

IT技术 reactjs config ecmascript-6 webpack babeljs
2021-05-06 01:10:14

我对文档的理解

我看到 Babel 6 现在有三个预设:es2015、react 和 stage-x。我读到我可以.babelrc像这样设置它们

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

或直接在 package.JSON 中,如下所示:

{
  ...,
  "version": x.x.x,
  "babel": {
    "presets": ["es2015", "react", "stage-0"]
  },
  ...,
}

我可以进一步将 babel-loader 与 webpack 一起使用,如下所示:

loader: 'babel?presets[]=es2015'


我的问题

因此,为了编译一切又好又干净,我将babel-loader刚刚更新为可与 Babel6 一起使用的所有内容添加到 webpack 配置中,如下所示:

module.exports = function(options) {
  var jsLoaders = ['babel?presets[]=es2015'];
  [...]
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loaders: jsLoaders
      },
      {
        test: /\.jsx$/,
        exclude: /node_modules/,
        loaders: options.production ? jsLoaders : ['react-hot'].concat(jsLoaders)
      },
      [...]


现在,当我没有 .babelrc设置 root 或预设选项的情况下进行编译时package.JSON,即仅使用 webpack 配置中设置的 babel-loader es2015 预设,我在我的 React 组件类中收到关于静态 propTypes 的意外标记错误:

ERROR in ./app/components/form/index.jsx
Module build failed: SyntaxError: /Library/WebServer/Documents/yarsk.test/app/components/form/index.jsx: Unexpected token (19:19)
  17 | // ES6 React Component:
  18 | export default class SurveyForm extends Component {
> 19 |   static propTypes = {
     |                    ^

在 GitHub 上,我被告知这是一个stage-1功能,即transform-class-properties. 所以我想stage-0马上实施
但是
当我通过像上面那样添加.babelrc或定义来package.JSON这样做时,我得到了一个非常奇怪的构建失败错误:

ERROR in ./app/components/form/index.jsx
Module build failed: Error: /Library/WebServer/Documents/yarsk.test/app/components/form/index.jsx: We don't know what to do with this node type. We were previously a Statement but we can't fit in here?
    at NodePath.insertAfter (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/path/modification.js:181:13)
    at NodePath.replaceWithMultiple (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/path/replacement.js:92:8)
    at handleClassWithSuper (/Library/WebServer/Documents/yarsk.test/node_modules/babel-plugin-transform-class-constructor-call/lib/index.js:80:10)
    at PluginPass.Class (/Library/WebServer/Documents/yarsk.test/node_modules/babel-plugin-transform-class-constructor-call/lib/index.js:101:11)
    at newFn (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/visitors.js:233:27)
    at NodePath._call (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/path/context.js:72:18)
    at NodePath.call (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/path/context.js:44:17)
    at NodePath.visit (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/path/context.js:102:12)
    at TraversalContext.visitQueue (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/context.js:151:16)
    at TraversalContext.visitSingle (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/context.js:111:19)
    at TraversalContext.visit (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/context.js:195:19)
    at Function.traverse.node (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/index.js:139:17)
    at NodePath.visit (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/path/context.js:106:22)
    at TraversalContext.visitQueue (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/context.js:151:16)
    at TraversalContext.visitMultiple (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/context.js:106:17)
    at TraversalContext.visit (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/context.js:193:19)
    at Function.traverse.node (/Library/WebServer/Documents/yarsk.test/node_modules/babel-traverse/lib/index.js:139:17)
 @ ./app/index.jsx 9:0-28

或者简而言之: Module build failed: Error: /.../index.jsx: We don't know what to do with this node type. We were previously a Statement but we can't fit in here?

这就是我被困的地方。当我能够像这样使用 babel-loader 进行编译并且一切正常时,我使用 Babel5 编写了这个组件:

loader: 'babel?optional[]=runtime&stage=0

现在我正在编译提到的错误。

  • 这是一个babel-loader问题,还是一个babel问题?
  • 我必须在哪里配置stage-0才能不抛出错误?


更新

当使用预设集进行编译并使用提到的类导出错误的解决方法(在创建类之前不得导出类)时,设置预设的顺序会更改错误消息。当我stage-0第一次设置时,现在的错误是'this' is not allowed before super() (This is an error on an internal node. Probably an internal error) 当我把stage-0第二个或第三个放在上面时,我会收到有关语法错误的消息。


最新的

有关这些错误的最新进展,请参阅我的帖子phabricator 上的新 babel 问题跟踪器了解更多信息。(基本上编译从 6.2.1 开始是固定的,但现在还有其他事情发生)

本文中提到的所有错误在 Babel 6.3.x 中都已完全修复。如果您仍然遇到问题,请更新您的依赖项。

4个回答

我在这里遇到的两个非常严重的错误,即具有静态属性的 ES6 类的直接导出和 ES6 构造函数的问题在该线程的答案中进行了讨论,可以在 GitHub 上在这里明确找到(导出错误)和这里(构造函数错误)(GitHub 问题跟踪器已关闭,问题、错误和请求已移至此处。)

这些都是官方确认的错误,自 Babel 6.3.17 以来已修复

(也许更早一两个,而不是在 6.3.x 之前,这是我使用的版本,一切都像使用 Babel5 一样工作。祝大家编码愉快。)


(记录:)

因此,如果您在 CLI 中收到以下错误消息:

We don't know what to do with this node type. We were previously a Statement but we can't fit in here?

您可能正在使用这样的静态属性或以类似的方式导出 ES6 类(请注意,这似乎不再与正在扩展的类相关联,而是与具有静态属性的类相关联)

import React, { Component, PropTypes } from 'react'

export default class ClassName extends Component {
  static propTypes = {...}
  // This will not get compiled correctly for now, as of Babel 6.1.4
}

Stryzhevskyi和 GitHub 上的几个人提到的简单解决方法

import React, { Component, PropTypes } from 'react'

class ClassName extends Component {
  static propTypes = {...}
}
export default ClassName // Just export the class after creating it



第二个问题是关于以下错误:

'this' is not allowed before super() (This is an error on an internal node. Probably an internal error)

尽管是Dominic Tobias 指出的合法规则但这是一个已确认的错误,其中似乎具有自己属性的扩展类会抛出此消息或类似消息。至于现在我还没有看到任何解决方法。出于这个原因,很多人现在(从 6.1.4 开始)回滚到 Babel5。

据说这个问题在 Babel 6.1.18 的发布中得到了修复(见上面的 GitHub 问题),但是人们,包括我在内,仍然看到同样的问题正在发生。


还需要注意,现在在您加载预设通天塔的顺序stage-xreact并且es2015似乎是重要的,可能会改变你的输出。


从 Babel 6.2.1 开始

这两个错误都已修复,代码编译正常。但是......还有另一个可能会影响很多使用 react 的人,它ReferenceError: this hasn't been initialised - super() hasn't been called在运行时抛出参考这里敬请关注...


自 Babel 6.3.17 起完全修复

(也许更早一两个,而不是在 6.3.x 之前,这是我使用的版本,一切都像使用 Babel5 一样工作。祝大家编码愉快。)

尝试用这样的结构替换你的导出:

class SurveyForm extends Component {/*implementation*/}
export default SurveyForm

是一个使用 Babel 6、React、Webpack 和 Sequelize 的工作示例:

https://github.com/BerndWessels/react-webpack

基本上这是 .babelrc

{
  "presets": [
    "es2015",
    "react",
    "stage-0"
  ],
  "env": {
    "development": {
      "plugins": [
        "babel-relay-plugin-loader",
        [
          "react-transform",
          {
            "transforms": [
              {
                "transform": "react-transform-hmr",
                "imports": [
                  "react"
                ],
                "locals": [
                  "module"
                ]
              },
              {
                "transform": "react-transform-catch-errors",
                "imports": [
                  "react",
                  "redbox-react"
                ]
              }
            ]
          }
        ]
      ]
    },
    "production": {
      "plugins": [
        "babel-relay-plugin-loader"
      ]
    }
  }
}

这些是module版本

babel-core@6.3.17
babel-loader@6.2.0
babel-plugin-react-transform@2.0.0-beta1
babel-preset-es2015@6.3.13
babel-preset-react@6.3.13
babel-preset-stage-0@6.3.13

这对我行得通。

遇到同样的问题后,我能够使用下面的 WebPack 配置使其与 React 一起工作。

module.exports = {
  entry: './app/Index.js',
  output: { path: __dirname, filename: 'dist/bundle.js' },
  module: {
    loaders: [
        {
            test: /\.js$/,
            loader: 'babel',
            query: {
                presets: ['react']
            }
        }
    ]
  }
};

我还需要安装 babel-preset-react。

npm install --save-dev babel-preset-react

编辑:当然,如果您也在编写 ES6,您可能还需要包含 ES2015 预设。

Babel 预设可以在这里找到:https : //github.com/babel/babel/tree/development/packages