在生产环境中使用babel-node是否可行?

88

我一直在使用babel-node和browserify以及babelify转换来开发网站,以支持ES6语法。

我想知道,在生产环境中,我能否像这样运行:babel-node server而不是node server?还有哪些其他选项可以让我在node中运行ES6呢?

以下是我用于构建和启动开发环境的命令:

// npm run build
browserify -t [babelify] client.js > public/js/bundle.js",

// npm start
babel-node server.js"

这是我的开发依赖项

"babel": "^4.0.1",
"babelify": "^5.0.3",
"browserify": "^8.0.3"
4个回答

117

对于客户端代码,你正在做正确的事情。使用babelify将其转换并发送到客户端。


对于服务器端代码,我会使用babel-cli进行常规构建。

根据http://babeljs.io/docs/setup/#babel_register的说明,babel-register不适合生产环境使用——因为要求钩子主要用于简单的情况。

对于 Babel 6+

从Babel 6开始,默认情况下不包含任何转换。因此,让我们首先安装babel-clibabel-preset-es2015

$ npm install --save-dev babel-cli babel-preset-es2015

在你的.babelrc文件中添加一个转换 - 这是我们上面下载的prest模块。查看预设的完整列表,看看哪个(些)最适合你。

{
  "presets": ["es2015"]
}
在你的package.json文件中添加一个build脚本。在src下放置输入文件,而build目录则是转换后的输出文件。
"scripts": {
  "build": "babel src -d build"
}

那就开始建造吧!

$ npm run build

然后运行你的代码。此时,你应该执行 build 目录中的文件。

$ npm start

对于 Babel <= 5,只需使用 require 钩子即可。

require("babel/register");

所有需要使用扩展名为.es6, .es, .jsx.js的node模块都将被Babel转换。此外,polyfill也会自动引入。

你可以继续保留ES6源代码,并使用node server.js来执行它们。


根据您的评论,似乎您遇到了一些问题。请特别注意上面黄色部分的内容。您的第一个文件只能是ES5,由node本身运行。所有后续需要的模块将通过Babel进行转换...

以下是典型设置的示例:

server.js

// only ES5 is allowed in this file
require("babel/register");

// other babel configuration, if necessary

// load your app
var app = require("./app.js");

app.js

// this file will be loaded through babel
// you can now use ES6 here and in every other include

点燃它!

$ node server.js

9
实际上,我刚刚尝试过在我的server.js文件中加入 require("babel/register")一行代码,在运行 node server.js 命令时出现了错误:Unexpected reserved word: import ...,因此看起来这个方法并没有起作用。 - svnm
1
@steveniseki,我的更新应该演示如何启动和运行事物。 - Mulan
如果有人想查看示例,可以在这里找到使用React Router,Babel和Alt的示例项目:https://github.com/goatslacker/isomorphic-react-examples/tree/master/react-router/react-router-movies。我将使用它们来制作一个真实的网站。这个示例项目现在可以通过node server.js :) 运行。 - svnm
4
同时它改为了 require("babel-register"); .. 不管怎样我得到了 "Unexpected token import" 的错误信息.. - smotru
对于客户端,移动 Web 应用程序可以吗?我只是担心编译文件的大小,因为我可能还会使用 React。 - Tinple
显示剩余4条评论

59

我刚刚写了一篇关于这个主题的博客文章

Babeljs CLI文档警告如下:

babel-node不适用于生产环境

您不应在生产中使用babel-node。它会导致不必要的负担,由于缓存存储在内存中,会有很高的内存使用率。 您还将始终体验到启动性能惩罚,因为整个应用程序需要即时编译。

这是一个示例,说明您可以如何设置npm脚本以使用Node而不是babel-node运行您的应用程序。

"scripts": {
  "clean": "rm -rf build && mkdir build",
  "build-css": "node-sass scss/app.scss public/css/app.css",
  "build-server": "babel -d ./build ./server -s",
  "build": "npm run clean && npm run build-css && npm run build-server",
  "lint": "eslint source/ --quiet",
  "start": "node ./build/index.js",
  "debug": "node --debug ./build/index.js",
  "test": "for i in $(ls tests/); do babel-node \"./tests/${i}\" | faucet ; done",
  "validate": "npm run lint; npm run test && npm outdated --depth 0"
},

您可以在博客文章上找到更多详细信息。


3
自从Node 4.0开始支持ES6,我们还需要使用babel来编译代码吗? - lvarayut
8
@LVarayut 是的,根据特性需要,服务器端仍需要使用 Babel。Node v4.0.0 不支持所有的 ES6 特性(尤其是通过 import/export 语法的模块)。请参阅 https://nodejs.org/en/docs/es6/ 以获取更多有关该主题的信息,或在终端中键入 node --v8-options | grep "in progress" 来获取未实现的 ES6 特性列表。 - jbmusso
14
Babel 不仅支持 ES6,还支持 ESNext。因此,它会不断地添加来自 ES7 和最新 TC39 规范稳定的功能。 - cuadraman

15

在生产中使用babel-node需要权衡利弊。

  • babel-node会增加0.5秒到1秒的启动成本,但如果您的应用程序是长时间运行的服务器,则这种启动成本不会太重要。
  • 尝试测量额外的内存消耗。例如,对于我的应用程序(读取和处理时间序列数据),仅增加了20MB。根据您的情况,这可能或可能不重要。

另一方面,

  • 直接使用babel-node简化了开发 - 您不需要“构建”脚本,并且不需要单独的src/libdist目录
  • 如果您从本地文件import,您将从src/myutils还是lib/myutils导入?使用babel-node可以消除这个问题。

我只使用Babel来支持模块。现在,V8刚刚在2017年1月10日发布了对模块的支持。希望我们能在几个月内在Node下看到带有标志的模块支持,使我使用Babel的原因变得无意义。


10

@cuadraman的答案比@naomik更准确。

简要回答你的问题:不,你不应该直接调用babel-nodebabel-node是一个私有库,被babel-cli所使用。

官方教程中包含了你需要的一切,让你在node上跑起来(不是浏览器端!): https://github.com/babel/example-node-server。请仔细阅读!我发现很多误导性的博客教程使用的方法繁琐,而我觉得这篇文章最容易跟随。

Bonus: 与许多人认为的相反,所有的转码工作都可以本地安装完成(使用npm install --save-dev babel-cli nodemon babel-preset-es2015 babel-preset-stage-2)。不需要全局安装Babel或任何辅助模块!非常巧妙。


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