Angular 2:如何告诉SystemJS使用bundle?
Angular 2: How to tell SystemJS to use a bundle?
我有一个 Angular 2 RC7 应用程序,我在其中使用 SystemJS 加载 JavaScript 文件。
这是我当前的 SystemJS 配置:
(function (global) {
System.config({
defaultExtension: 'js',
defaultJSExtensions: true,
paths: {
'npm:': 'node_modules/'
},
// Let the system loader know where to look for things
map: {
// Our app is within the app folder
app: 'app',
// Angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
// Other libraries
'rxjs': 'npm:rxjs',
'ng2-translate': 'node_modules/ng2-translate'
},
// Tell the system loader how to load when no filename and/or no extension
packages: {
app: { main: './main.js', defaultExtension: 'js' },
rxjs: { defaultExtension: 'js' },
'ng2-translate': { defaultExtension: 'js' }
}
});
})(this);
现在我创建了一个名为 app.bundle.min.js
的包,其中包含我所有的应用程序逻辑,以及一个 dependencies.bundle.min.js
,其中包含使用的依赖项。
如何告诉 SystemJS 使用这些文件而不是单独导入文件?
我试过替换这个:
<script>
System.import('app').catch(function(err){
console.error(err);
});
</script>
与:
<script src="production/dependencies.bundle.min.js"></script>
<script src="production/app.bundle.min.js"></script>
在我的 index.html 中,但这不起作用。只要我将 System.import...
脚本块保留在 index.html 内,应用程序就会加载,但使用的是单个文件而不是包。
我也试过改变这个:
map: {
// Our app is within the app folder
app: 'production/app.bundle.min.js',
但这也不起作用。
这是使用 Gulp:
生成包的方式
gulp.task('inline-templates', function () {
return gulp.src('app/**/*.ts')
.pipe(inlineNg2Template({
UseRelativePaths: true,
indent: 0,
removeLineBreaks: true
}))
.pipe(tsc({
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": true,
"noImplicitAny": false,
"suppressImplicitAnyIndexErrors": true
}))
.pipe(gulp.dest('dist'));
});
gulp.task('bundle-app', ['inline-templates'], function() {
var builder = new systemjsBuilder('', 'app/configs/systemjs.config.js');
return builder
.bundle('dist/**/* - [@angular/**/*.js] - [rxjs/**/*.js]', 'production/app.bundle.min.js', {
minify: true,
mangle: true
})
.then(function() {
console.log('Build complete');
})
.catch(function(err) {
console.log('Build error');
console.log(err);
});
});
gulp.task('bundle-dependencies', ['inline-templates'], function() {
var builder = new systemjsBuilder('', 'app/configs/systemjs.config.js');
return builder
.bundle('dist/**/*.js - [dist/**/*.js]', 'production/dependencies.bundle.min.js', {
minify: true,
mangle: true
})
.then(function() {
console.log('Build complete');
})
.catch(function(err) {
console.log('Build error');
console.log(err);
});
});
gulp.task('production', ['bundle-app', 'bundle-dependencies'], function(){});
我怀疑我必须以某种方式更改我的 SystemJS 配置中的映射以指向捆绑包?我该怎么做?
根据您的 SystemJS 配置中的 map
和 packages
,
System.import('app')
转换为文件 app/main.js
的请求。但是,如果查看生成的应用程序包,您会发现该模块实际上已注册为
System.registerDynamic("dist/main.js" ...
因为包是从 dist
文件夹中的 .js
个文件生成的。
这种不匹配是您的模块无法从脚本包中加载的原因。
一个可能的解决方案是始终将 .ts
和 .js
文件保存在不同的文件夹中 - .ts
在 app
中,.js
在 [=22= 中].这样,systemjs 将只需要知道 dist
:systemjs.config.js 中唯一需要更改的部分是 app
映射:
// Let the system loader know where to look for things
map: {
// Our app is compiled to js files in the dist folder
app: 'dist',
为了检查它是否有效,我从 angular quickstart example 开始并添加了 gulpfile.js
以及这些任务:
使用 gulp-typescript 插件将打字稿编译成 dist
。
var gulp = require('gulp');
var typescript = require('typescript');
var tsc = require('gulp-typescript');
var systemjsBuilder = require('systemjs-builder');
gulp.task('tsc', function () {
return gulp.src(['app/**/*.ts', 'typings/index.d.ts'])
.pipe(tsc({
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": true,
"noImplicitAny": false,
"suppressImplicitAnyIndexErrors": true
}))
.js.pipe(gulp.dest('dist'));
});
将 systemjs 配置文件复制到 dist
文件夹中,这样它将与应用程序代码捆绑在一起并在生产中可用(这是必需的,因为您正在使用 bundle
而不是 buildStatic
)
gulp.task('bundle-config', function() {
return gulp.src('app/configs/systemjs.config.js')
.pipe(gulp.dest('dist/configs'));
});
使用 systemjs 构建器生成包:
gulp.task('bundle-app', ['bundle-config', 'tsc'], function() {
var builder = new systemjsBuilder('', 'app/configs/systemjs.config.js');
return builder
.bundle('[dist/**/*]', 'production/app.bundle.min.js', {
minify: true,
mangle: true
})
.then(function() {
console.log('Build complete');
})
.catch(function(err) {
console.log('Build error');
console.log(err);
});
});
gulp.task('bundle-dependencies', ['bundle-config', 'tsc'], function() {
var builder = new systemjsBuilder('', 'app/configs/systemjs.config.js');
return builder
.bundle('dist/**/* - [dist/**/*.js]', 'production/dependencies.bundle.min.js', {
minify: true,
mangle: true
})
.then(function() {
console.log('Build complete');
})
.catch(function(err) {
console.log('Build error');
console.log(err);
});
});
gulp.task('production', ['bundle-app', 'bundle-dependencies'], function(){});
请注意,它使用 [dist/**/*]
语法来生成没有任何依赖项的应用程序包 - 你的 gulpfile.js 中的那个是不同的并生成更大的包,其中包括一些依赖项 - 我不知道是否是有意还是无意。
然后,我根据 index.html
:
的这些更改创建了 index-production.html
删除 systemjs.config.js
的 <script>
标签 - 我们从包中导入它
为 <head>
中的捆绑包添加 <script>
标签
<script src="production/dependencies.bundle.min.js"></script>
<script src="production/app.bundle.min.js"></script>
添加内联 <script>
导入配置和应用程序模块:
<script>
System.import('dist/configs/systemjs.config.js').then(function() {
System.import('app').catch(function(err){ console.error(err); });
});
</script>
导入 'app' 模块是必要的,因为使用 bundle
生成的包不会导入任何东西,也不会 运行 任何代码 - 它们只是让所有模块以后都可以导入,不像 'sfx' 使用 buildStatic
生成的包。
此外,此脚本块需要在<my-app>
元素之后的<body>
中,否则<my-app>
元素尚未创建时app
会过早启动(或者,可以在 'document ready' 事件上调用 import('app')
)。
您可以在 github 上找到完整示例:https://github.com/fictitious/test-systemjs-angular-gulp
我有一个 Angular 2 RC7 应用程序,我在其中使用 SystemJS 加载 JavaScript 文件。
这是我当前的 SystemJS 配置:
(function (global) {
System.config({
defaultExtension: 'js',
defaultJSExtensions: true,
paths: {
'npm:': 'node_modules/'
},
// Let the system loader know where to look for things
map: {
// Our app is within the app folder
app: 'app',
// Angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
// Other libraries
'rxjs': 'npm:rxjs',
'ng2-translate': 'node_modules/ng2-translate'
},
// Tell the system loader how to load when no filename and/or no extension
packages: {
app: { main: './main.js', defaultExtension: 'js' },
rxjs: { defaultExtension: 'js' },
'ng2-translate': { defaultExtension: 'js' }
}
});
})(this);
现在我创建了一个名为 app.bundle.min.js
的包,其中包含我所有的应用程序逻辑,以及一个 dependencies.bundle.min.js
,其中包含使用的依赖项。
如何告诉 SystemJS 使用这些文件而不是单独导入文件?
我试过替换这个:
<script>
System.import('app').catch(function(err){
console.error(err);
});
</script>
与:
<script src="production/dependencies.bundle.min.js"></script>
<script src="production/app.bundle.min.js"></script>
在我的 index.html 中,但这不起作用。只要我将 System.import...
脚本块保留在 index.html 内,应用程序就会加载,但使用的是单个文件而不是包。
我也试过改变这个:
map: {
// Our app is within the app folder
app: 'production/app.bundle.min.js',
但这也不起作用。
这是使用 Gulp:
生成包的方式gulp.task('inline-templates', function () {
return gulp.src('app/**/*.ts')
.pipe(inlineNg2Template({
UseRelativePaths: true,
indent: 0,
removeLineBreaks: true
}))
.pipe(tsc({
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": true,
"noImplicitAny": false,
"suppressImplicitAnyIndexErrors": true
}))
.pipe(gulp.dest('dist'));
});
gulp.task('bundle-app', ['inline-templates'], function() {
var builder = new systemjsBuilder('', 'app/configs/systemjs.config.js');
return builder
.bundle('dist/**/* - [@angular/**/*.js] - [rxjs/**/*.js]', 'production/app.bundle.min.js', {
minify: true,
mangle: true
})
.then(function() {
console.log('Build complete');
})
.catch(function(err) {
console.log('Build error');
console.log(err);
});
});
gulp.task('bundle-dependencies', ['inline-templates'], function() {
var builder = new systemjsBuilder('', 'app/configs/systemjs.config.js');
return builder
.bundle('dist/**/*.js - [dist/**/*.js]', 'production/dependencies.bundle.min.js', {
minify: true,
mangle: true
})
.then(function() {
console.log('Build complete');
})
.catch(function(err) {
console.log('Build error');
console.log(err);
});
});
gulp.task('production', ['bundle-app', 'bundle-dependencies'], function(){});
我怀疑我必须以某种方式更改我的 SystemJS 配置中的映射以指向捆绑包?我该怎么做?
根据您的 SystemJS 配置中的 map
和 packages
,
System.import('app')
转换为文件 app/main.js
的请求。但是,如果查看生成的应用程序包,您会发现该模块实际上已注册为
System.registerDynamic("dist/main.js" ...
因为包是从 dist
文件夹中的 .js
个文件生成的。
这种不匹配是您的模块无法从脚本包中加载的原因。
一个可能的解决方案是始终将 .ts
和 .js
文件保存在不同的文件夹中 - .ts
在 app
中,.js
在 [=22= 中].这样,systemjs 将只需要知道 dist
:systemjs.config.js 中唯一需要更改的部分是 app
映射:
// Let the system loader know where to look for things
map: {
// Our app is compiled to js files in the dist folder
app: 'dist',
为了检查它是否有效,我从 angular quickstart example 开始并添加了 gulpfile.js
以及这些任务:
使用 gulp-typescript 插件将打字稿编译成
dist
。var gulp = require('gulp'); var typescript = require('typescript'); var tsc = require('gulp-typescript'); var systemjsBuilder = require('systemjs-builder'); gulp.task('tsc', function () { return gulp.src(['app/**/*.ts', 'typings/index.d.ts']) .pipe(tsc({ "target": "es5", "module": "commonjs", "moduleResolution": "node", "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "removeComments": true, "noImplicitAny": false, "suppressImplicitAnyIndexErrors": true })) .js.pipe(gulp.dest('dist')); });
将 systemjs 配置文件复制到
dist
文件夹中,这样它将与应用程序代码捆绑在一起并在生产中可用(这是必需的,因为您正在使用bundle
而不是buildStatic
)gulp.task('bundle-config', function() { return gulp.src('app/configs/systemjs.config.js') .pipe(gulp.dest('dist/configs')); });
使用 systemjs 构建器生成包:
gulp.task('bundle-app', ['bundle-config', 'tsc'], function() { var builder = new systemjsBuilder('', 'app/configs/systemjs.config.js'); return builder .bundle('[dist/**/*]', 'production/app.bundle.min.js', { minify: true, mangle: true }) .then(function() { console.log('Build complete'); }) .catch(function(err) { console.log('Build error'); console.log(err); }); }); gulp.task('bundle-dependencies', ['bundle-config', 'tsc'], function() { var builder = new systemjsBuilder('', 'app/configs/systemjs.config.js'); return builder .bundle('dist/**/* - [dist/**/*.js]', 'production/dependencies.bundle.min.js', { minify: true, mangle: true }) .then(function() { console.log('Build complete'); }) .catch(function(err) { console.log('Build error'); console.log(err); }); }); gulp.task('production', ['bundle-app', 'bundle-dependencies'], function(){});
请注意,它使用 [dist/**/*]
语法来生成没有任何依赖项的应用程序包 - 你的 gulpfile.js 中的那个是不同的并生成更大的包,其中包括一些依赖项 - 我不知道是否是有意还是无意。
然后,我根据 index.html
:
index-production.html
删除
systemjs.config.js
的<script>
标签 - 我们从包中导入它为
中的捆绑包添加<head>
<script>
标签<script src="production/dependencies.bundle.min.js"></script> <script src="production/app.bundle.min.js"></script>
添加内联
<script>
导入配置和应用程序模块:<script> System.import('dist/configs/systemjs.config.js').then(function() { System.import('app').catch(function(err){ console.error(err); }); }); </script>
导入 'app' 模块是必要的,因为使用 bundle
生成的包不会导入任何东西,也不会 运行 任何代码 - 它们只是让所有模块以后都可以导入,不像 'sfx' 使用 buildStatic
生成的包。
此外,此脚本块需要在<my-app>
元素之后的<body>
中,否则<my-app>
元素尚未创建时app
会过早启动(或者,可以在 'document ready' 事件上调用 import('app')
)。
您可以在 github 上找到完整示例:https://github.com/fictitious/test-systemjs-angular-gulp