从 ES6 模块生成 browserify 输出和 System.register() 模块?
Generating both browserify output & System.register() modules from ES6 modules?
我已经按照 2ality 的最终语法示例编写了 ES6 模块,没有 .js
后缀。
我还将模块组织成 vendor/project 目录层次结构和模块命名方案,因为 System.register()
模块格式有效地将已注册的模块放入同一命名空间。
问题如下,如果我引用2ality的例子:
//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//------ main.js ------
import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5
以上直接在浏览器中运行良好,例如 traceur and es6-module-loader (see example-es6-modules.html
)。当遇到 import
声明时,.js
后缀似乎会自动附加到文件名,并加载 lib.js
。只要配置 System.paths
指向 vendor/project 目录的顶部,就可以直接在浏览器中执行 ES6 模块。
当使用 SystemJS builder (see example-system-register.html
). As long as baseURL
is set to the top of the vendor/project hierarchy (see builder.js 捆绑到单个 System.register()
模块格式文件时,以上内容也能正常工作。生成模块时,模块将以 vendor/project 前缀命名。
问题是当我尝试为 browserify, when carrying out the transform both traceur
and es6ify
的输入生成 CommonJS 模块时,没有在 import
声明中为文件名附加 .js
后缀,导致错误以下几行:
$ cd src/es6
$ traceur --out ./out.js --modules commonjs gso/eonjs/EonJS.js
Error: File not found '/home/ ... /src/es6/gso/eonjs/MomentRecurRule'
以上错误是因为traceur没有在'gso/eonjs/MomentRecurRule'
导入声明中添加.js
后缀。否则会找到该文件。
如果 ES6 模块被转译为单独的 CommonJS 模块,browserify 会报告相同的错误,无法找到要导入的文件 - browserify 也不会类似地自动为导入文件名添加 .js
后缀。
接下来的问题是,ES6 模块在浏览器中执行没有问题,加载时也捆绑了 System.register()
模块,但如何转换为浏览器可执行文件?
相对路径的 browserify API 别名模块 ID:
var browserify = require('browserify');
var b = browserify();
b.add('./index.js');
b.require('./gso/eonjs/EonJS.js', { expose: 'gso/eonjs/EonJS' });
b.require('./gso/eonjs/AbstractRecurRule.js', { expose: 'gso/eonjs/AbstractRecurRule' });
b.require('./gso/eonjs/MomentRecurRule.js', { expose: 'gso/eonjs/MomentRecurRule' });
b.require('./gso/eonjs/RRuleRecurRule.js', { expose: 'gso/eonjs/RRuleRecurRule' });
b.require('./gso/eonjs/RecurRuleContainer.js', { expose: 'gso/eonjs/RecurRuleContainer' });
b.require('./gso/eonjs/Occurrence.js', { expose: 'gso/eonjs/Occurrence' });
b.bundle().pipe(process.stdout);
快速浏览 CommonJS 以类似于 System.import()
的方式解析模块 ID 字符串(参见 RrequireJS Load JavaScript Files)。但是 browserify 需要这个额外的别名步骤。
grunt-browserify 任务:
browserify: {
options: { // https://github.com/substack/node-browserify#browserifyfiles--opts
require: [
'./src/commonjs/build/gso/eonjs/EonJS.js:gso/eonjs/EonJS',
'./src/commonjs/build/gso/eonjs/AbstractRecurRule.js:gso/eonjs/AbstractRecurRule',
'./src/commonjs/build/gso/eonjs/MomentRecurRule.js:gso/eonjs/MomentRecurRule',
'./src/commonjs/build/gso/eonjs/RRuleRecurRule.js:gso/eonjs/RRuleRecurRule',
'./src/commonjs/build/gso/eonjs/RecurRuleContainer.js:gso/eonjs/RecurRuleContainer',
'./src/commonjs/build/gso/eonjs/Occurrence.js:gso/eonjs/Occurrence'
]
},
debug: {
debug: true,
src: './index.js',
dest: 'src/browserify/eonjs-traceur-debug.js'
},
},
我已经按照 2ality 的最终语法示例编写了 ES6 模块,没有 .js
后缀。
我还将模块组织成 vendor/project 目录层次结构和模块命名方案,因为 System.register()
模块格式有效地将已注册的模块放入同一命名空间。
问题如下,如果我引用2ality的例子:
//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//------ main.js ------
import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5
以上直接在浏览器中运行良好,例如 traceur and es6-module-loader (see example-es6-modules.html
)。当遇到 import
声明时,.js
后缀似乎会自动附加到文件名,并加载 lib.js
。只要配置 System.paths
指向 vendor/project 目录的顶部,就可以直接在浏览器中执行 ES6 模块。
当使用 SystemJS builder (see example-system-register.html
). As long as baseURL
is set to the top of the vendor/project hierarchy (see builder.js 捆绑到单个 System.register()
模块格式文件时,以上内容也能正常工作。生成模块时,模块将以 vendor/project 前缀命名。
问题是当我尝试为 browserify, when carrying out the transform both traceur
and es6ify
的输入生成 CommonJS 模块时,没有在 import
声明中为文件名附加 .js
后缀,导致错误以下几行:
$ cd src/es6
$ traceur --out ./out.js --modules commonjs gso/eonjs/EonJS.js
Error: File not found '/home/ ... /src/es6/gso/eonjs/MomentRecurRule'
以上错误是因为traceur没有在'gso/eonjs/MomentRecurRule'
导入声明中添加.js
后缀。否则会找到该文件。
如果 ES6 模块被转译为单独的 CommonJS 模块,browserify 会报告相同的错误,无法找到要导入的文件 - browserify 也不会类似地自动为导入文件名添加 .js
后缀。
接下来的问题是,ES6 模块在浏览器中执行没有问题,加载时也捆绑了 System.register()
模块,但如何转换为浏览器可执行文件?
相对路径的 browserify API 别名模块 ID:
var browserify = require('browserify');
var b = browserify();
b.add('./index.js');
b.require('./gso/eonjs/EonJS.js', { expose: 'gso/eonjs/EonJS' });
b.require('./gso/eonjs/AbstractRecurRule.js', { expose: 'gso/eonjs/AbstractRecurRule' });
b.require('./gso/eonjs/MomentRecurRule.js', { expose: 'gso/eonjs/MomentRecurRule' });
b.require('./gso/eonjs/RRuleRecurRule.js', { expose: 'gso/eonjs/RRuleRecurRule' });
b.require('./gso/eonjs/RecurRuleContainer.js', { expose: 'gso/eonjs/RecurRuleContainer' });
b.require('./gso/eonjs/Occurrence.js', { expose: 'gso/eonjs/Occurrence' });
b.bundle().pipe(process.stdout);
快速浏览 CommonJS 以类似于 System.import()
的方式解析模块 ID 字符串(参见 RrequireJS Load JavaScript Files)。但是 browserify 需要这个额外的别名步骤。
grunt-browserify 任务:
browserify: {
options: { // https://github.com/substack/node-browserify#browserifyfiles--opts
require: [
'./src/commonjs/build/gso/eonjs/EonJS.js:gso/eonjs/EonJS',
'./src/commonjs/build/gso/eonjs/AbstractRecurRule.js:gso/eonjs/AbstractRecurRule',
'./src/commonjs/build/gso/eonjs/MomentRecurRule.js:gso/eonjs/MomentRecurRule',
'./src/commonjs/build/gso/eonjs/RRuleRecurRule.js:gso/eonjs/RRuleRecurRule',
'./src/commonjs/build/gso/eonjs/RecurRuleContainer.js:gso/eonjs/RecurRuleContainer',
'./src/commonjs/build/gso/eonjs/Occurrence.js:gso/eonjs/Occurrence'
]
},
debug: {
debug: true,
src: './index.js',
dest: 'src/browserify/eonjs-traceur-debug.js'
},
},