如何使用 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-x
、react
和 es2015
的顺序似乎很重要,并且可能会改变您的输出。
从 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 如何仅在某些路由上需要外部库?
如何在不使用 create-react-app 且仅使用我自己的 Webpack 的情况下设置 package.json 进行部署?