使用babel时需要使用js吗?
您可能需要一些模块加载器,但并不需要RequireJS。您有几种选择。以下内容将帮助您入门。
汇总是下一代JavaScript模块捆绑程序。它本身就了解ES2015模块,并将产生不需要任何模块加载器即可运行的捆绑软件。未使用的出口将从输出中删除,这称为摇树。
现在,我个人建议使用rollupjs,因为它产生最清晰的输出,并且易于设置,但是,它为答案提供了不同的方面。所有其他方法都执行以下操作:
- 用babel编译ES6代码,使用您选择的模块格式
- 将编译的模块与模块加载器并置在一起,或使用将为您遍历依赖项的捆绑器。
使用rollupjs,事情并非真的能以这种方式工作。在这里,汇总是第一步,而不是babel。默认情况下,它仅了解ES6模块。您必须提供一个入口模块,其依赖关系将被遍历和连接。由于ES6在一个模块中允许多个命名的导出,因此rollupjs足够聪明,可以删除未使用的导出,从而缩小了包的大小。不幸的是,rollupjs-s解析器无法理解> ES6语法,因此必须在汇总之前解析ES7模块,但是编译不会影响ES6导入。这是通过使用rollup-plugin-babel
具有babel-preset-es2015-rollup
预设的插件来完成的(此预设与es2015相同,但模块转换器和外部助手插件除外)。因此,如果设置正确,汇总将对您的模块执行以下操作:
- 从文件系统读取ES6-7模块
- babel插件将其编译到内存中的ES6
- 汇总分析导入和导出的ES6代码(使用橡子分析器,编译为汇总)
- 它遍历整个图,并创建一个捆绑包(捆绑包可能仍然具有外部依赖性,并且条目的导出可能以您选择的格式导出)
示例nodejs构建:
// setup by `npm i rollup rollup-plugin-babel babel-preset-es2015 babel-plugin-external-helpers --save-dev`
// build.js:
require("rollup").rollup({
entry: "./src/main.js",
plugins: [
require("rollup-plugin-babel")({
"presets": [["es2015", { "modules": false }]],
"plugins": ["external-helpers"]
})
]
}).then(bundle => {
var result = bundle.generate({
// output format - 'amd', 'cjs', 'es6', 'iife', 'umd'
format: 'iife'
});
require("fs").writeFileSync("./dist/bundle.js", result.code);
// sourceMaps are supported too!
}).then(null, err => console.error(err));
// setup by `npm i grunt grunt-rollup rollup-plugin-babel babel-preset-es2015 babel-plugin-external-helpers --save-dev`
// gruntfile.js
module.exports = function(grunt) {
grunt.loadNpmTasks("grunt-rollup");
grunt.initConfig({
"rollup": {
"options": {
"format": "iife",
"plugins": [
require("rollup-plugin-babel")({
"presets": [["es2015", { "modules": false }]],
"plugins": ["external-helpers"]
})
]
},
"dist": {
"files": {
"./dist/bundle.js": ["./src/main.js"]
}
}
}
});
}
// setup by `npm i gulp gulp-rollup rollup-plugin-babel babel-preset-es2015 babel-plugin-external-helpers --save-dev`
// gulpfile.js
var gulp = require('gulp'),
rollup = require('gulp-rollup');
gulp.task('bundle', function() {
gulp.src('./src/**/*.js')
// transform the files here.
.pipe(rollup({
// any option supported by Rollup can be set here.
"format": "iife",
"plugins": [
require("rollup-plugin-babel")({
"presets": [["es2015", { "modules": false }]],
"plugins": ["external-helpers"]
})
],
entry: './src/main.js'
}))
.pipe(gulp.dest('./dist'));
});
Babel有一个名为babelify的简洁软件包。它的用法很简单明了:
$ npm install --save-dev babelify babel-preset-es2015 babel-preset-react
$ npm install -g browserify
$ browserify src/script.js -o bundle.js \
-t [ babelify --presets [ es2015 react ] ]
或者您可以从node.js使用它:
$ npm install --save-dev browserify babelify babel-preset-es2015 babel-preset-react
...
var fs = require("fs");
var browserify = require("browserify");
browserify(["./src/script.js"])
.transform("babelify", {presets: ["es2015", "react"]})
.bundle()
.pipe(fs.createWriteStream("bundle.js"));
这将立即转换并连接您的代码。Browserify .bundle
将包括一个不错的CommonJS小型加载器,并将已编译的模块组织成函数。您甚至可以拥有相对进口。
例:
// project structure
.
+-- src/
| +-- library/
| | \-- ModuleA.js
| +-- config.js
| \-- script.js
+-- dist/
\-- build.js
...
// build.js
var fs = require("fs");
var browserify = require("browserify");
browserify(["./src/script.js"])
.transform("babelify", {presets: ["es2015", "react"]})
.bundle()
.pipe(fs.createWriteStream("dist/bundle.js"));
// config.js
export default "Some config";
// ModuleA.js
import config from '../config';
export default "Some nice export: " + config;
// script.js
import ModuleA from './library/ModuleA';
console.log(ModuleA);
要编译,只需node build.js
在项目根目录下运行即可。
使用babel编译所有代码。我建议您使用amd模块变压器(babel-plugin-transform-es2015-modules-amd
在babel 6中调用)。之后,将已编译的源代码与WebPack捆绑在一起。
WebPack 2已经发布!它了解本机ES6模块,并将使用babili -s内置的死代码消除功能执行(或模拟)树摇。目前(2016年9月),我仍然建议使用babel进行汇总,尽管我的观点可能会随着WebPack 2的第一个发行版而改变。请随时在评论中讨论您的观点。
定制编译管道
有时您希望对编译过程有更多的控制。您可以像这样实现自己的管道:
首先,您必须将babel配置为使用amd模块。默认情况下,babel会转换为CommonJS模块,在浏览器中处理起来有点复杂,尽管browserify可以很好地处理它们。
- 通天塔5:使用
{ modules: 'amdStrict', ... }
选项
- Babel 6:使用
es2015-modules-amd
插件
不要忘记打开该moduleIds: true
选项。
检查转码的生成模块名称,定义的模块和所需的模块之间经常不匹配。参见sourceRoot和moduleRoot。
最后,您必须具有某种模块加载程序,但这不是必需的requirejs。有almondjs,一个很小的需求垫片可以很好地工作。您甚至可以实现自己的:
var __modules = new Map();
function define(name, deps, factory) {
__modules.set(name, { n: name, d: deps, e: null, f: factory });
}
function require(name) {
const module = __modules.get(name);
if (!module.e) {
module.e = {};
module.f.apply(null, module.d.map(req));
}
return module.e;
function req(name) {
return name === 'exports' ? module.e : require(name);
}
}
最后,您可以将加载程序填充程序和已编译的模块连接在一起,并在其上运行uglify。
Babel的样板代码在每个模块中都有重复
默认情况下,上述大多数方法都使用babel分别编译每个模块,然后将它们串联在一起。这也是babelify所做的。但是,如果您看一下已编译的代码,就会发现babel在每个文件的开头插入了许多样板,其中大部分都是在所有文件中重复的。
为了防止这种情况,您可以使用babel-plugin-transform-runtime
插件。
require
浏览器中不存在,所以您需要使用某些构建工具,例如Require.js,Browserify或Webpack。