如何捆绑一个angular度的应用程序的生产

我想在这个线程中跟踪和更新最新的最好的(也是最简单的)方法来将Angular(版本2,4,…)捆绑到一个实时Web服务器上进行生产。

请在答案中包含Angular版本,以便在更新的版本中进行更好的跟踪。

2.x, 4.x, 5.x (TypeScript)和Angular CLI 1.5.0

OneTime设置

  • npm install -g @angular/cli
  • ng new projectFolder创build一个新的应用程序

捆绑步骤

  • ng build --prod (当目录是projectFolder时,在命令行中运行)

    用于生产的标志prod包(请参阅包含在生产标志中的选项列表的Angular文档 )。

  • 使用Brotli压缩使用以下命令压缩资源

    for i in dist/*; do brotli $i --output $i.br; done

bundle默认生成为projectFolder / dist /

产量

  • dist/main.[hash].bundle.js您的应用程序捆绑了[大小:148 KB,新的Angular CLI应用程序为空, 35 KB压缩]。
  • dist/polyfill.[hash].bundle.jsdist/polyfill.[hash].bundle.js依赖关系(@angular,RxJS …)捆绑[size:60 KB,对于新的Angular CLI应用程序为空,压缩为17 KB ]。
  • dist/index.html您的应用程序的入口点。
  • dist/inline.[hash].bundle.js webpack loader
  • dist/style.[hash].bundle.css样式定义
  • 从Angular CLI资产configuration复制的dist/assets资源

部署

您可以使用ng serve --prod命令来启动本地HTTP服务器,以便使用http:// localhost:4200可以访问具有生产文件的应用程序,从而获得应用程序的预览。

对于生产使用情况,您必须从您select的HTTP服务器的dist文件夹中部署所有文件。

2.0.1 Final使用Gulp(TypeScript – 目标:ES5)


OneTime设置

  • npm install (当direcory是projectFolder时,在cmd中运行)

捆绑步骤

  • npm run bundle (当direcory是projectFolder时,在cmd下运行)

    生成的捆绑包将projectFolder / bundles /

产量

  • bundles/dependencies.bundle.js [ size:〜1 MB (尽可能小)]
    • 包含rxjs和angular度依赖关系,而不是整个框架
  • bundles/app.bundle.js [ 大小:取决于你的项目 ,我的是bundles/app.bundle.js MB ]
    • 包含您的项目

文件结构

  • projectFolder / app / (所有组件,指令,模板等)
  • projectFolder / gulpfile.js
 var gulp = require('gulp'), tsc = require('gulp-typescript'), Builder = require('systemjs-builder'), inlineNg2Template = require('gulp-inline-ng2-template'); gulp.task('bundle', ['bundle-app', 'bundle-dependencies'], function(){}); gulp.task('inline-templates', function () { return gulp.src('app/**/*.ts') .pipe(inlineNg2Template({ useRelativePaths: true, indent: 0, removeLineBreaks: true})) .pipe(tsc({ "target": "ES5", "module": "system", "moduleResolution": "node", "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "removeComments": true, "noImplicitAny": false })) .pipe(gulp.dest('dist/app')); }); gulp.task('bundle-app', ['inline-templates'], function() { // optional constructor options // sets the baseURL and loads the configuration file var builder = new Builder('', 'dist-systemjs.config.js'); return builder .bundle('dist/app/**/* - [@angular/**/*.js] - [rxjs/**/*.js]', 'bundles/app.bundle.js', { minify: true}) .then(function() { console.log('Build complete'); }) .catch(function(err) { console.log('Build error'); console.log(err); }); }); gulp.task('bundle-dependencies', ['inline-templates'], function() { // optional constructor options // sets the baseURL and loads the configuration file var builder = new Builder('', 'dist-systemjs.config.js'); return builder .bundle('dist/app/**/*.js - [dist/app/**/*.js]', 'bundles/dependencies.bundle.js', { minify: true}) .then(function() { console.log('Build complete'); }) .catch(function(err) { console.log('Build error'); console.log(err); }); }); 
  • projectFolder / package.json (与快速入门指南相同,只显示了需要捆绑的devDependencies和npm-scripts)
 { "name": "angular2-quickstart", "version": "1.0.0", "scripts": { *** "gulp": "gulp", "rimraf": "rimraf", "bundle": "gulp bundle", "postbundle": "rimraf dist" }, "license": "ISC", "dependencies": { *** }, "devDependencies": { "rimraf": "^2.5.2", "gulp": "^3.9.1", "gulp-typescript": "2.13.6", "gulp-inline-ng2-template": "2.0.1", "systemjs-builder": "^0.15.16" } } 
  • projectFolder / systemjs.config.js (与快速入门指南相同,在此不再可用)
 (function(global) { // map tells the System loader where to look for things var map = { 'app': 'app', 'rxjs': 'node_modules/rxjs', 'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api', '@angular': 'node_modules/@angular' }; // packages tells the System loader how to load when no filename and/or no extension var packages = { 'app': { main: 'app/boot.js', defaultExtension: 'js' }, 'rxjs': { defaultExtension: 'js' }, 'angular2-in-memory-web-api': { defaultExtension: 'js' } }; var packageNames = [ '@angular/common', '@angular/compiler', '@angular/core', '@angular/forms', '@angular/http', '@angular/platform-browser', '@angular/platform-browser-dynamic', '@angular/router', '@angular/router-deprecated', '@angular/testing', '@angular/upgrade', ]; // add package entries for angular packages in the form '@angular/common': { main: 'index.js', defaultExtension: 'js' } packageNames.forEach(function(pkgName) { packages[pkgName] = { main: 'index.js', defaultExtension: 'js' }; }); var config = { map: map, packages: packages }; // filterSystemConfig - index.asp's chance to modify config before we register it. if (global.filterSystemConfig) { global.filterSystemConfig(config); } System.config(config); })(this); 
  • projetcFolder / dist-systemjs.config.js (只显示与systemjs.config.json的区别)
 var map = { 'app': 'dist/app', }; 
  • projectFolder / index.html (production) – 脚本标记的顺序非常重要。 在bundle标签之后放置dist-systemjs.config.js标签仍然允许程序运行,但是依赖捆绑包将被忽略,依赖关系将从node_modules文件夹加载。
 <!doctype html> <html lang="en"> <head> <meta charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <base href="/"/> <title>Angular</title> <link rel="stylesheet" type="text/css" href="style.css"/> </head> <body> <my-app> loading... </my-app> <!-- Polyfill(s) for older browsers --> <script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/zone.js/dist/zone.min.js"></script> <script src="node_modules/reflect-metadata/Reflect.js"></script> <script src="node_modules/systemjs/dist/system.js"></script> <script src="dist-systemjs.config.js"></script> <!-- Project Bundles. Note that these have to be loaded AFTER the systemjs.config script --> <script src="bundles/dependencies.bundle.js"></script> <script src="bundles/app.bundle.js"></script> <script> System.import('app/boot').catch(function (err) { console.error(err); }); </script> </body> </html> 
  • projectFolder / app / boot.ts是引导的地方。

我能做的最好的:)

带有Webpack的Angular 2(没有CLI设置)

1-由Angular2团队的教程

Angular2团队发布了使用Webpack的教程

我创build了一个小的GitHub种子项目 ,并将其从教程中放置。 所以你可以快速尝试工作stream程。

说明

  • npm安装

  • npm开始 。 为了发展。 这将创build一个虚拟的“dist”文件夹,将在您的本地主机地址上重新生成。

  • npm运行构build 。 用于生产。 “这将创build一个物理”dist“文件夹版本,可以发送到一个web服务器,dist文件夹为7.8MB,但实际上只需要234KB就可以在网页浏览器中加载页面。

2 – 一个Webkit入门工具包

这个Webpack初学者工具包提供了比上面的教程更多的testingfunction,看起来很受欢迎。

使用SystemJs构build器和gulp的Angular 2生产工作stream程

Angular.io有快速启动教程。 我复制了本教程,并扩展了一些简单的一揽子任务,将所有内容捆绑到可以复制到服务器的dist文件夹中,并像这样工作。 我试图优化一切,以在Jenkis CI上正常工作,因此node_modules可以被caching,不需要被复制。

Github上带有示例应用程序的源代码: https : //github.com/Anjmao/angular2-production-workflow

生产步骤

  1. 清洁打字稿编译js文件和dist文件夹
  2. 编译应用程序文件夹内的打字稿文件
  3. 使用SystemJs捆绑器将所有内容绑定到dist文件夹,并为浏览器caching刷新生成散列值
  4. 使用gulp-html-replace将index.html脚本replace为捆绑版本并复制到dist文件夹
  5. 将assets文件夹内的所有内容复制到dist文件夹

节点 :虽然你总是可以创build自己的构build过程,但我强烈build议使用angular-cli,因为它具有所有需要的工作stream程,并且现在可以完美运行。 我们已经在生产中使用它,并且根本没有任何问题。

Angular CLI 1.xx(适用于Angular 4.xx,5.xx)

这支持:

  • Angular 2.x和4.x
  • 最新的Webpack 2.x
  • Angular AoT编译器
  • 路由(正常和懒惰)
  • SCSS
  • 自定义文件捆绑(资产)
  • 其他开发工具(linter,单元和端到端testing设置)

初始设置

新的项目名称 - 路由

您可以为SASS --style=scss支持添加--style=scss

你可以添加--ng4来使用Angular 4而不是Angular 2。

创build项目后,CLI会自动运行npm install 。 如果您想要使用Yarn,或者只是想在没有安装的情况下查看项目骨架, 请检查如何在此处执行此操作 。

捆绑步骤

在项目文件夹里面:

 ng build -prod

在当前版本中,您需要手动指定 – 因为它可以在开发模式下使用(尽pipe由于速度慢,这是不实际的)。

这也为更小的bundle执行AoT编译(没有Angular编译器,而是生成编译器输出)。 如果您使用Angular 4,由于生成的代码更小,所以使用AoT的捆绑包要小得多。
你可以用开发模式(sourcemaps,no minification)和AoT来testing你的应用程序,方法是运行ng build --aot

产量

默认输出目录是./dist ,虽然它可以在./angular-cli.json更改。

可部署的文件

构build步骤的结果如下:

(注意: <content-hash>指的是文件内容的散列/指纹,这意味着caching清除的方式,这是可能的,因为Webpack自己写script标记)

  • ./dist/assets
    ./src/assets/**复制的文件来自./src/assets/**
  • ./dist/index.html
    ./src/index.html添加webpack脚本
    源模板文件可以在./angular-cli.jsonconfiguration
  • ./dist/inline.js
    小webpack装载机/ polyfill
  • ./dist/main.<content-hash>.bundle.js
    包含所有生成/导入的.js脚本的主要.js文件
  • ./dist/styles.<content-hash>.bundle.js
    当你使用CSS的Webpack加载器,这是CLI的方式,他们在这里加载通过JS

在旧版本中,它还创build了gzip版本来检查它们的大小和.map源文件的文件,但这不再发生,因为人们一直要求删除这些文件。

其他文件

在某些其他情况下,您可能会发现其他不需要的文件/文件夹:

  • ./out-tsc/
    来自./src/tsconfig.jsonoutDir
  • ./out-tsc-e2e/
    来自./e2e/tsconfig.jsonoutDir
  • ./dist/ngfactory/
    从AoT编译器(如果不是从beta 16开始就不能configurationCLI)

到今天为止,我还是把“时代前瞻”的食谱作为生产捆绑的最佳配方。 你可以在这里find它: https : //angular.io/docs/ts/latest/cookbook/aot-compiler.html

到目前为止,我对于Angular 2的体验是,AoT创build了几乎没有加载时间的最小的构build。 而最重要的是,这里的问题是关于 – 你只需要运送一些文件到生产。

这似乎是因为Angular编译器不会随着模板被编译为“时间前面”而与生产版本一起发货。 将HTML模板标记转换为javascript指令也很酷,这些指令很难将其反向工程化为原始HTML。

我已经做了一个简单的video,我展示了下载文件的大小,文件数量等一个Angular 2应用程序在开发VS AOT构build – 你可以在这里看到:

https://youtu.be/ZoZDCgQwnmQ

您可以在这里findvideo中使用的源代码:

https://github.com/fintechneo/angular2-templates

  **Production build with - Angular Rc5 - Gulp - typescripts - systemjs** 1)con-cat all js files and css files include on index.html using "gulp-concat". - styles.css (all css concat in this files) - shims.js(all js concat in this files) 2)copy all images and fonts as well as html files with gulp task to "/dist". 3)Bundling -minify angular libraries and app components mentioned in systemjs.config.js file. Using gulp 'systemjs-builder' SystemBuilder = require('systemjs-builder'), gulp.task('system-build', ['tsc'], function () { var builder = new SystemBuilder(); return builder.loadConfig('systemjs.config.js') .then(function () { builder.buildStatic('assets', 'dist/app/app_libs_bundle.js') }) .then(function () { del('temp') }) }); 4)Minify bundles using 'gulp-uglify' jsMinify = require('gulp-uglify'), gulp.task('minify', function () { var options = { mangle: false }; var js = gulp.src('dist/app/shims.js') .pipe(jsMinify()) .pipe(gulp.dest('dist/app/')); var js1 = gulp.src('dist/app/app_libs_bundle.js') .pipe(jsMinify(options)) .pipe(gulp.dest('dist/app/')); var css = gulp.src('dist/css/styles.min.css'); return merge(js,js1, css); }); 5) In index.html for production <html> <head> <title>Hello</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta charset="utf-8" /> <link rel="stylesheet" href="app/css/styles.min.css" /> <script type="text/javascript" src="app/shims.js"></script> <base href="/"> </head> <body> <my-app>Loading...</my-app> <script type="text/javascript" src="app/app_libs_bundle.js"></script> </body> </html> 6) Now just copy your dist folder to '/www' in wamp server node need to copy node_modules in www. 

“最佳”取决于情况。 有时候你只关心尽可能小的单一包,但在大型应用程序中,你可能不得不考虑延迟加载。 在某些时候,将整个应用程序作为一个单独的包提供服务是不切实际的。

在后一种情况下,Webpack通常是支持代码拆分的最好方法。

对于单个包,我会考虑Rollup,或Closure编译器,如果你感觉很勇敢:-)

我已经创build了我曾经在这里使用过的所有Angular捆绑器的示例: http : //www.syntaxsuccess.com/viewarticle/angular-production-builds

代码可以在这里find: https : //github.com/thelgevold/angular-2-samples

Angular版本:4.1.x

你可以使用angular-cli-ghpages在github上部署你的angular度应用程序

请查看链接以查找如何使用此cli进行部署。

部署的网站通常会存储在github某个分支中

GH-页

使用可以克隆git分支,并使用它像你的服务器中的静态网站

只需在一分钟内将webpack 3设置为angular 4,您的开发和生产环境包就会变得没有任何问题,只需按照以下github文档

https://github.com/roshan3133/angular2-webpack-starter

我也面临着准备生产准备捆绑的同样的问题。 我在package.json中添加了以下代码行

 "build:prod": "webpack --config config/webpack.prod.js --progress --profile --bail", 

并用npm调用它

npm run build:prod

它做了给我生产准备好JS和它的各自的映射文件的把戏。