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

Posted

技术标签:

【中文标题】如何使用 React 和 Webpack 设置 Babel 6 阶段 0【英文标题】:How to set up Babel 6 stage 0 with React and Webpack 【发布时间】:2016-02-01 00:15:54 【问题描述】:

我对文档的理解

我看到 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'

我的问题

所以为了编译干净整洁的所有内容,我将刚刚更新为可与 Babel6 一起使用的 babel-loader 添加到 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)
      ,
      [...]

现在,当我在 root 中编译 without .babelrc 或在 package.JSON 中设置的预设选项时,即仅在 webpack 配置中设置了 babel-loader es2015 预设时,我收到一个关于静态 propTypes 的意外令牌错误我的 React 组件类:

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 放在第二或第三时,我会从上面收到有关语法错误的消息。

最新

有关这些错误的最新进展see my post 或the new babel issue tracker on phabricator 了解更多信息。 (从 6.2.1 开始基本编译已修复,但现在还有其他事情发生)

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

【问题讨论】:

我对 gulp 也有同样的问题。我尝试在 .babelrc 和 babelify.configure 中配置 stage-0 预设,但没有用。 最新的 babel-core@6.9.0 好像有这个问题。是回归错误吗? @sglai 除了不是很具体,我在 babel-core@6.9.0 上,我的代码编译良好,此后没有太大变化。请参考 phabricator 或打开一个新问题。 【参考方案1】:

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

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

【讨论】:

这是confirmed bug in 6.0.14 的解决方法,其中直接导出扩展类会引发关于节点类型的奇怪错误。可悲的是,这对我不起作用。当我将所有预设添加到 babel 并将导出移到底部时,我解决了这个问题,但仍然收到关于 Missing class properties transform. 的语法错误,据我所知,它应该包含在 stage-0 中。 @Marian 你找到“缺少类属性转换”错误的修复了吗? @redmoon7777 尝试实现上述解决方法或将 babel 升级到最新版本并使用预设顺序。我现在是这样加载的:'babel?presets[]=es2015&presets[]=react&presets[]=stage-0' 所以第 0 阶段首先被加载,现在我被其他 Babel6 错误困住了......但对于这个它有帮助。 预设顺序非常很重要。我先有stage-0,必须最后移动它,然后是es2015。 对于任何未来的读者,只是想确认@SergiuParaschiv 所说的是正确的。先设置es2105,最后放stage。【参考方案2】:

在遇到同样的问题后,我可以使用下面的 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

【讨论】:

OP 已经在使用这些预设,这是关于在 stage-0 支持下使用它们 正如多米尼克所说,我已经在.babelrc中加载了"presets": ["es2015", "react", "stage-0"] 这样做我得到一个错误:“无法在加载器列表中定义'查询'和多个加载器”【参考方案3】:

你试过了吗?:

presets: [
    plugins: [
        'transform-class-properties'
    ]
, 'stage-0', 'es2015', 'react']

【讨论】:

是的,我试过了,最后不管放在哪里都没有用。 只是补充一下 - 在构造函数中调用 super 之前不能使用它,这很正常 我正在研究这条规则,但我仍然很难正确理解它,因为升级到 Babel6 时没有更改相同的代码,并且 Babel5 根本没有抛出任何错误.由于这与我最初的问题无关,因此我将打开另一个问题。谢谢。 在调用构造函数并创建实例之前,没有“this”的概念,也许编译器正在修复代码 Actually the 'this before super error' appears to be yet another issue in Babel6【参考方案4】:

我在这里遇到的两个相当严重的错误,即具有静态属性的 ES6 类的直接导出和 ES6 构造函数的问题在该线程的答案中进行了讨论 ,可以在 GitHub 上明确找到这里(导出错误)和这里(构造错误)(GitHub 问题跟踪器已关闭,issues, bugs and requests have moved here。)

这些都是官方确认的错误,自 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

简单的解决方法as mentioned by 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)

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

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


另外请注意,目前您加载 babel 预设 stage-xreactes2015 的顺序似乎很重要,并且可能会改变您的输出。


从 Babel 6.2.1 开始

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

自 Babel 6.3.17 以来完全修复

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

【讨论】:

这听起来有道理,但我已经将所有 babel 组件更新到 6.5.0,它仍然说不支持装饰器。 .babelrc 指向 stage-0,但是唉... 您是否尝试过使用预设的加载顺序?加载顺序仍然会改变行为。此外,我的函数设置中的两个非常具体的错误肯定已经解决,这与直接导出扩展的 ES6 类和静态 propTypes 有关。您可能想在 babel phabricator 上打开另一个问题甚至更好的问题(上面的链接)。 顺序没有区别,但我的解决方案是安装babel-plugin-transform-decorators-legacy并将transform-decorators-legacy作为插件添加到.babelrc文件中。有关更多详细信息,请参阅此答案:***.com/a/34210231/270968【参考方案5】:

你试过只使用stage-1吗?

使用查询属性对我有用。

```
module: 
  loaders: [
    test: /\.jsx?$/, 
    loader: 'babel',
    query: 
      presets: ['es2015', 'stage-1', 'react']
    
  ]

```

当然,我无法在package.json 中使用.babelrc 和babel 选项。还在想办法babel-*v6.0

【讨论】:

如果您查看 stage-0 预设 babeljs.io/docs/plugins/preset-stage-0 的文档 - 它指出它还包括预设 1、2 和 3 中的所有插件。 @danecando 我错过了“所有插件”部分。谢谢你。仍在尝试弄清楚 babel 6 是如何工作的。 相信我@sajinshrestha,你并不孤单。仅在 webpack 和 babel 之间,我就有 30 个依赖项来获得一个平均的“通用”react/flux 应用程序框架。 -_- 数字越小,您包含的功能越多,数字越大的每个功能都包含在下一个较低的功能中。 stage-3 的功能包含在 stage-2 等中。有点离题,但我真的发现设置起来并不难,只是这是一个主要的版本更改,我想自然会有一些错误要查找和清理干净。【参考方案6】:

Here 是 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"
      ]
    
  

这些是模块版本

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

这对我有用。

【讨论】:

感谢您的设置 Christine,我没有时间更新我的文章,提到的错误确实从 6.3.x 开始修复,关于这个线程的一切都很好。感谢分享。

以上是关于如何使用 React 和 Webpack 设置 Babel 6 阶段 0的主要内容,如果未能解决你的问题,请参考以下文章

如何制作一个可以在 React Application 中使用的 webpack 库?

使用 React 和 Webpack 设置 Airbnb ESLint

使用 React Router 和 Webpack 2 如何仅在某些路由上需要外部库?

CORS 与 React、Webpack 和 Axios

如何在不使用 create-react-app 且仅使用我自己的 Webpack 的情况下设置 package.json 进行部署?

Jest 遇到了意外的令牌(React、Typescript、Babel、Jest 和 Webpack 设置)