我如何实际部署Angular 2 + Typescript + systemjs应用程序?

在angular.io上有一个使用typecript和systemjs的快速入门教程。 现在我已经运行了miniapp,我将如何去创build可部署的东西? 我什么都找不到任何信息。

我是否需要额外的工具,System.config中的其他设置?

(我知道我可以使用webpack&创build一个bundle.js,但是我想用教程中使用的systemjs)

有人可以用这个设置共享他们的构build过程(Angular 2,TypeScript,systemjs)

在这个级别上理解的关键是使用下面的configuration,你不能直接编译JS文件。

在TypeScript编译器configuration中:

{ "compilerOptions": { "emitDecoratorMetadata": true, "experimentalDecorators": true, "declaration": false, "stripInternal": true, "module": "system", "moduleResolution": "node", "noEmitOnError": false, "rootDir": ".", "inlineSourceMap": true, "inlineSources": true, "target": "es5" }, "exclude": [ "node_modules" ] } 

在HTML中

 System.config({ packages: { app: { defaultExtension: 'js', format: 'register' } } }); 

事实上,这些JS文件将包含匿名模块。 匿名模块是一个使用System.register的JS文件,但没有将模块名称作为第一个参数。 当systemjs被configuration为模块pipe理器时,这就是打字稿编译器默认生成的内容。

因此,要将所有模块都放到一个JS文件中,您需要在TypeScript编译器configuration中利用outFile属性。

你可以使用下面的内容来做到这一点:

 const gulp = require('gulp'); const ts = require('gulp-typescript'); var tsProject = ts.createProject('tsconfig.json', { typescript: require('typescript'), outFile: 'app.js' }); gulp.task('tscompile', function () { var tsResult = gulp.src('./app/**/*.ts') .pipe(ts(tsProject)); return tsResult.js.pipe(gulp.dest('./dist')); }); 

这可以结合一些其他处理:

  • 丑化编译的TypeScript文件的东西
  • 创build一个app.js文件
  • 为第三方库创buildvendor.js文件
  • 创build一个boot.js文件来导入引导应用程序的模块。 该文件必须包含在页面的末尾(当所有的页面被加载时)。
  • 要更新index.html来考虑这两个文件

gulp任务中使用以下依赖项:

  • 一饮而尽,CONCAT
  • 吞掉-HTMLreplace
  • 一饮而尽,打字稿
  • 一饮而尽,丑化

以下是一个示例,以便适应。

  • 创buildapp.min.js文件

     gulp.task('app-bundle', function () { var tsProject = ts.createProject('tsconfig.json', { typescript: require('typescript'), outFile: 'app.js' }); var tsResult = gulp.src('app/**/*.ts') .pipe(ts(tsProject)); return tsResult.js.pipe(concat('app.min.js')) .pipe(uglify()) .pipe(gulp.dest('./dist')); }); 
  • 创buildvendors.min.js文件

     gulp.task('vendor-bundle', function() { gulp.src([ 'node_modules/es6-shim/es6-shim.min.js', 'node_modules/systemjs/dist/system-polyfills.js', 'node_modules/angular2/bundles/angular2-polyfills.js', 'node_modules/systemjs/dist/system.src.js', 'node_modules/rxjs/bundles/Rx.js', 'node_modules/angular2/bundles/angular2.dev.js', 'node_modules/angular2/bundles/http.dev.js' ]) .pipe(concat('vendors.min.js')) .pipe(uglify()) .pipe(gulp.dest('./dist')); }); 
  • 创buildboot.min.js文件

     gulp.task('boot-bundle', function() { gulp.src('config.prod.js') .pipe(concat('boot.min.js')) .pipe(uglify()) .pipe(gulp.dest('./dist')); }); 

    config.prod.js只包含以下内容:

      System.import('boot') .then(null, console.error.bind(console)); 
  • 更新index.html文件

     gulp.task('html', function() { gulp.src('index.html') .pipe(htmlreplace({ 'vendor': 'vendors.min.js', 'app': 'app.min.js', 'boot': 'boot.min.js' })) .pipe(gulp.dest('dist')); }); 

    index.html如下所示:

     <html> <head> <!-- Some CSS --> <!-- build:vendor --> <script src="node_modules/es6-shim/es6-shim.min.js"></script> <script src="node_modules/systemjs/dist/system-polyfills.js"></script> <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="node_modules/rxjs/bundles/Rx.js"></script> <script src="node_modules/angular2/bundles/angular2.dev.js"></script> <script src="node_modules/angular2/bundles/http.dev.js"></script> <!-- endbuild --> <!-- build:app --> <script src="config.js"></script> <!-- endbuild --> </head> <body> <my-app>Loading...</my-app> <!-- build:boot --> <!-- endbuild --> </body> </html> 

注意System.import('boot'); 必须在主体的最后完成,等待所有的app组件从app.min.js文件注册。

我在这里没有描述处理CSS和HTML缩小的方法。

你可以使用angular2-cli build命令

 ng build -prod 

https://github.com/angular/angular-cli/wiki/build#bundling

使用-prod标志通过ng build -prodng serve -prod ng build -prod ng serve -prod所有依赖关系捆绑到单个文件中 ,并利用树形结构抖动技术。

更新

这个答案是在angular2在rc4时提交的

我曾经在angular-cli beta21和angular2 ^ 2.1.0上再次尝试过,并且按照预期工作

这个答案需要用你可以使用的angular-cli来初始化应用程序

 ng new myApp 

或在现有的一个

 ng init 

您可以使用带有Gulp和SystemJS-Builder的 SystemJS在Typescript中构build一个Angular 2(2.0.0-rc.1)项目。

以下是如何构build,捆绑和缩小英雄之旅运行2.0.0-rc.1( 全部源 , 现场示例 )的简化版本。

gulpfile.js

 var gulp = require('gulp'); var sourcemaps = require('gulp-sourcemaps'); var concat = require('gulp-concat'); var typescript = require('gulp-typescript'); var systemjsBuilder = require('systemjs-builder'); // Compile TypeScript app to JS gulp.task('compile:ts', function () { return gulp .src([ "src/**/*.ts", "typings/*.d.ts" ]) .pipe(sourcemaps.init()) .pipe(typescript({ "module": "system", "moduleResolution": "node", "outDir": "app", "target": "ES5" })) .pipe(sourcemaps.write('.')) .pipe(gulp.dest('app')); }); // Generate systemjs-based bundle (app/app.js) gulp.task('bundle:app', function() { var builder = new systemjsBuilder('public', './system.config.js'); return builder.buildStatic('app', 'app/app.js'); }); // Copy and bundle dependencies into one file (vendor/vendors.js) // system.config.js can also bundled for convenience gulp.task('bundle:vendor', function () { return gulp.src([ 'node_modules/jquery/dist/jquery.min.js', 'node_modules/bootstrap/dist/js/bootstrap.min.js', 'node_modules/es6-shim/es6-shim.min.js', 'node_modules/es6-promise/dist/es6-promise.min.js', 'node_modules/zone.js/dist/zone.js', 'node_modules/reflect-metadata/Reflect.js', 'node_modules/systemjs/dist/system-polyfills.js', 'node_modules/systemjs/dist/system.src.js', ]) .pipe(concat('vendors.js')) .pipe(gulp.dest('vendor')); }); // Copy dependencies loaded through SystemJS into dir from node_modules gulp.task('copy:vendor', function () { gulp.src(['node_modules/rxjs/**/*']) .pipe(gulp.dest('public/lib/js/rxjs')); gulp.src(['node_modules/angular2-in-memory-web-api/**/*']) .pipe(gulp.dest('public/lib/js/angular2-in-memory-web-api')); return gulp.src(['node_modules/@angular/**/*']) .pipe(gulp.dest('public/lib/js/@angular')); }); gulp.task('vendor', ['bundle:vendor', 'copy:vendor']); gulp.task('app', ['compile:ts', 'bundle:app']); // Bundle dependencies and app into one file (app.bundle.js) gulp.task('bundle', ['vendor', 'app'], function () { return gulp.src([ 'app/app.js', 'vendor/vendors.js' ]) .pipe(concat('app.bundle.js')) .pipe(uglify()) .pipe(gulp.dest('./app')); }); gulp.task('default', ['bundle']); 

这是我的Angular 2的MEA2N样板: https : //github.com/simonxca/mean2-boilerplate

这是一个简单的样板,用tsc把东西放在一起。 (实际上使用grunt-ts ,其核心是tsc命令。)没有Wekpack等。

不pipe你是否使用咕噜声,这个想法是:

  • 把你的应用程序写在一个名为ts/的文件夹中(例如: public/ts/
  • 使用tsc将您的ts/文件夹的目录结构镜像到一个js/文件夹中,只需在index.html中的js/文件夹中引用文件即可。

为了让grunt-ts工作(对于普通的tsc,gulp等应该有一个等效的命令),你在你的tsconfig.json有一个名为"outDir": "../js"的属性,并在你的gruntfile.js与:

 grunt.initConfig({ ts: { source: {tsconfig: 'app/ts/tsconfig.json'} }, ... }); 

然后运行grunt ts ,它会将你的应用程序public/ts/并镜像到public/js/

那里。 超级简单易懂。 不是最好的方法,但一个好的开始。

我发现为systemJs捆绑angular rc1最简单的方法是使用systemjs-buildersystemjs-builder

 gulp.task('bundle', function () { var path = require('path'); var Builder = require('systemjs-builder'); var builder = new Builder('/node_modules'); return builder.bundle([ '@angular/**/*.js' ], 'wwwroot/bundle.js', { minify: false, sourceMaps: false }) .then(function () { console.log('Build complete'); }) .catch(function (err) { console.log('Build error'); console.log(err); }); }); 

正如在注释中指出的那样,systemJs在使用moduleId: module.id捆绑组件时目前遇到了问题

https://github.com/angular/angular/issues/6131

当前的build议(angular2 rc1)似乎是使用显式path,即moduleId: '/app/path/'

我在后端使用expressjs来服务我的ng2项目。 你可以从我的github页面检查它: https : //github.com/echonax/ng2-beta-and-test-framework

在Angular.io网站下,在高级/部署部分下,build议最简单的部署方式是“将开发环境复制到服务器”。

  1. 请阅读以下部分:尽可能简单的部署。 最后的项目文件显示在代码部分。 请注意,它已经设置了代码来从networking(而不是从本地npm_modules文件夹)加载npm包文件。

  2. 确保它在本地计算机上运行(npm start)。 然后在项目文件夹下,将'/ src'子文件夹下的所有内容复制到您设置的S3存储桶中。 您可以使用拖放进行复制,在此过程中,您可以select为文件select权限设置,确保将其设置为“可读”给“所有人”。

  3. 在“属性”选项卡下,find“静态网站托pipe”面板,选中“使用该存储区托pipe网站”选项,并将Index.html指定为Index文档和Error文档。

  4. 点击静态网站端点,您的项目就会运行!