babelify + browserify-rails + react,Uncaught SyntaxError:意外的令牌导入

24
我正在使用 browserify-rails + babelify 来转译一个 React + Rails 项目中的 jsx。
我非常困惑为什么在 components.js(React 的挂载点)中需要 // require('');。如果删除该行注释,则会出现 "SyntaxError: Unexpected token import" 错误。
目前,我还不知道为什么一行注释会影响转译。我也不确定这是 React、babelify、browserify、browserify-rails 还是 Rails 资产管道的问题。
请参考 https://github.com/sidazhou/react_rails_skeleton/tree/v0.0.1 获取完整代码库。 components.js
// require(''); // somehow this is necessary, why?! Otherwise we get: "SyntaxError: Unexpected token import"
import React from 'react';
import ReactDOM from 'react-dom';
import Widgets from './components/Widgets.jsx';

ReactDOM.render( <Widgets />, document.getElementById('react_component') );

package.json

{
  "name": "react-sample",
  "dependencies": {
    "babel-preset-es2015": "^6.3.13",
    "babel-preset-react": "^6.3.13",
    "babelify": "^7.2.0",
    "browserify": "^12.0.1",
    "browserify-incremental": "^3.0.1",
    "history": "^1.13.1",
    "material-ui": "^0.13.4",
    "react": "^0.14.3",
    "react-dom": "^0.14.3",
    "react-router": "^1.0.2",
    "react-tap-event-plugin": "^0.2.1"
  },
  "engines": {
    "node": ">= 0.10"
  }
}

application.rb

config.browserify_rails.commandline_options = "-t [ babelify --presets [ es2015 react ] ]"

你介意试用一下更新版本的Babel吗?自从6.3.13以来,他们已经修改了解析器,我想知道它是否可以解决你的问题。 - Jeremy Rodi
使用 {"babel-preset-es2015": "^6.5.0", "babel-preset-react": "^6.5.0"} 并没有帮助解决问题。 - Sida Zhou
一个空行也可以吗?还是唯一有效的只有注释掉的 require(''); - Jeremy Rodi
空行不起作用,// rquire(''); 不起作用,// require() 起作用。感觉越来越像解析器在某个地方出错了。 - Sida Zhou
我想说似乎有些东西在文件传递给Babel之前对其进行了修改;不过我需要更深入地研究才能确定。明天我可能会有时间全面检查一下。 - Jeremy Rodi
1个回答

3

关于这个问题,browserify-rails存在一个未解决的问题:

#124 transforms are only applied to files loaded with require()

我试图通过引用一些发布的帖子来总结这个主题(他是browserify-rails的作者)。

cymen 于2015年12月10日发表了评论:

尝试调试的一个方法是在源代码中添加注释// require// module.exports。这样能解决问题吗?当然,我们希望添加检测es6(import等)的正确修复程序。

cymen 于2015年12月18日发表了评论:

重新阅读您的初始帖子后,简单的解决方案就是让application.js需要应用程序并启动它--只是不要在其中使用ES6或任何其他东西。这将使您达到目标,而无需大量操作。稍后,当您摆脱资产管道时(理想情况下),您将更多地控制编译并可以将其重新整理回主文件中(如果需要的话)。但是,为什么要与这样的小问题斗争呢?

mockdeep(他提出了这个问题)于2015年12月18日发表了评论:

是的,我们正在这样做。我们在application.js中定义了一些全局变量。这只是一个令人惊讶的问题,并不一定会在Chrome或Firefox上测试时出现,因为它们都支持许多ES6功能。

但是,为什么要摆脱资产管道呢?似乎它在预编译资产方面提供了非常可靠的价值。

cymen于2015年12月18日发表了评论:

因为资产管道正在成为反范式。browserify-rails存在的唯一原因是资产管道使JavaScript开发距离当前最佳实践约-5年。虽然browserify-rails可以工作,但在某个时候,直接转到browserify或webpack要容易得多。

因此,我的观点是,browserify-rails最适合从传统JavaScript迁移到CommonJS,然后跳出资产管道。

当然,每个人都可以根据自己的需求使用它。将页面刷新与资产构建连接起来是有益的。对于习惯于使用Rails的Ruby开发人员,这种简单的“工作方式”是有意义的。虽然通过Procfile,很容易启动webpack / browserify以监视资产并根据需要重新编译。因此,我理解有各种用例。

cymen在2015年12月18日发表了评论:

我换了雇主,现在直接使用webpack(我喜欢--之前的工程师做出了这个选择,而且运行良好,我认为browserify也不错)。但是我正在开发客户端Web应用程序,因此我们的后端通常是基于Ruby的API,运行Sinatra(使用NodeJS进行一些服务端渲染)。

我的前任雇主一段时间使用browserify-rails,但我认为他们已经离开了资产管道。我不确定(我还没有机会与那些仍在该项目上工作的人详细讨论过)。

其中一个问题是运行browserify-rails所需的时间特别长,尤其是在低端MacBook上(Airs,旧13英寸)。使用browserify-rails 2.x,如果我们可以绕过使用Tilt作为中介(就像我们在browserify-rails 1.x上所做的那样),直接使用Sprockets,我认为我们有更好的机会保持性能高。实际上,Sprockets缓存应该足够好,以至于我们可能可以摆脱browserify-incremental(它正在缓存browserify构建以尝试保持性能--但现在随着2.x中的Sprockets缓存和browserify-incremental中的缓存,这可能太复杂了)。

那是他对该问题的最后一条评论(3个月前)。因此,您已经拥有的解决方法是目前可用的最佳解决方案(直到有人在browserify-rails中实现ES6检测为止)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接