如何捆绑 Angular 应用程序用于生产
How to bundle an Angular app for production
捆绑 Angular(版本 2、4、6 等)以在实时网络服务器上生产的最佳方法是什么。
请在答案中包含 Angular 版本,以便我们在它移至更高版本时更好地跟踪。
2.0.1 Final
使用 Gulp(TypeScript - 目标:ES5)
一次性设置
npm install
(当 direcory 是 projectFolder 时在 cmd 中 运行)
捆绑步骤
npm run bundle
(当 direcory 是 projectFolder 时在 cmd 中 运行)
bundle 生成到 projectFolder / bundles /
输出
bundles/dependencies.bundle.js
[大小:~ 1 MB(越小越好)]
- 包含 rxjs 和 angular 依赖项,而不是整个框架
bundles/app.bundle.js
[大小:取决于你的项目,我的是 ~ 0.5 MB ]
- 包含您的项目
文件结构
- projectFolder / app /(所有组件、指令、模板等)
- 项目文件夹/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(与 Quickstart guide 相同,仅显示捆绑所需的 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(与 Quickstart guide 相同,不再可用)
(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(生产)- 脚本标签的顺序很关键。将
dist-systemjs.config.js
标记放在 bundle 标记之后仍然允许程序 运行 但依赖包将被忽略,依赖项将从 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 是 bootstrap 所在的位置。
我能做到的最好了:)
2 to 13
(TypeScript) 与 Angular CLI
一次性设置
npm install -g @angular/cli
ng new projectFolder
创建一个新应用程序
捆绑步骤
ng build
(当目录为 projectFolder
时在命令行中 运行)。
flag prod
用于生产的捆绑包现在是默认的(如果需要,请参阅 Angular documentation 自定义它)。
使用以下命令Brotli compression压缩资源
for i in dist/*/*; do brotli $i; done
bundle 默认生成为 projectFolder/dist(/$projectFolder
for v6+)**
输出
大小 Angular 13.2.4
带 CLI 13.2.4
选项 CSS 不带 Angular路由
dist/main-[es-version].[hash].js
您的应用程序捆绑 [ES5 大小:132 KB 新 Angular CLI 应用程序为空,39 KB 压缩]。
dist/polyfill-[es-version].[hash].bundle.js
polyfill 依赖项 (@angular, RxJS...) 捆绑 [ES5 大小:37 KB 新 Angular CLI 应用程序为空,12 KB 压缩.
dist/index.html
您的应用程序的入口点。
dist/runtime-[es-version].[hash].bundle.js
webpack 加载器
dist/style.[hash].bundle.css
样式定义
dist/assets
从 Angular CLI 资产配置复制的资源
部署
您可以使用启动本地 HTTP 服务器的 ng serve --prod
命令获得您的应用程序的 预览 ,以便可以使用 http:/ 访问带有生产文件的应用程序/本地主机:4200。 这对于生产用途是不安全的。
对于生产用途,您必须将 dist
文件夹中的所有文件部署到您选择的 HTTP 服务器中。
Angular 2 使用 SystemJs 构建器和 gulp
的生产工作流程
Angular.io有快速入门教程。我复制了本教程并扩展了一些简单的 gulp 任务,用于将所有内容捆绑到 dist 文件夹,该文件夹可以复制到服务器并像那样工作。我尝试优化所有内容以在 Jenkis CI 上正常运行,因此 node_modules 可以缓存并且不需要复制。
Github 上带有示例应用程序的源代码:https://github.com/Anjmao/angular2-production-workflow
生产步骤
- 清理 typescripts 编译的 js 文件和 dist 文件夹
- 编译 app 文件夹中的 typescript 文件
- 使用 SystemJs 捆绑器将所有内容捆绑到 dist 文件夹,并生成用于浏览器缓存刷新的哈希值
- 使用 gulp-html-replace 将 index.html 脚本替换为捆绑版本并复制到 dist 文件夹
- 将 assets 文件夹中的所有内容复制到 dist 文件夹
Node:虽然您始终可以创建自己的构建过程,但我强烈建议使用 angular-cli,因为它具有所有需要的工作流程并且可以正常工作现在完美了。我们已经在生产中使用它,angular-cli 完全没有任何问题。
Angular CLI 1.x.x(适用于 Angular 4.x.x、5.x.x)
这支持:
- Angular 2.x 和 4.x
- 最新的 Webpack 2.x
- Angular AoT 编译器
- 路由(正常和惰性)
- SCSS
- 自定义文件捆绑(资产)
- 其他开发工具(linter、单元和端到端测试设置)
初始设置
ng new project-name --routing
您可以添加 --style=scss
以获得 SASS .scss 支持。
您可以添加 --ng4
以使用 Angular 4 而不是 Angular 2。
创建项目后,CLI 会自动为您运行npm install
。如果你想改用 Yarn,或者只是想看看项目骨架而不安装,check how to do it here.
捆绑步骤
项目文件夹内:
ng build -prod
当前版本需要手动指定--aot
,因为可以在开发模式下使用(虽然速度慢,不实用)
这还会对更小的包执行 AoT 编译(没有 Angular 编译器,而是生成编译器输出)。如果您使用 Angular 4,那么使用 AoT 的包要小得多,因为生成的代码更小。
您可以在开发模式下使用 AoT 测试您的应用程序(sourcemaps,无缩小)和 AoT by 运行ning ng build --aot
.
输出
默认输出目录是./dist
,虽然它可以在./angular-cli.json
.
中改变
可部署文件
构建步骤的结果如下:
(注意:<content-hash>
指的是文件内容的哈希/指纹,这是一种缓存破坏方式,这是可能的,因为 Webpack 自己写入了 script
标签)
./dist/assets
按原样从 ./src/assets/**
复制的文件
./dist/index.html
来自./src/index.html
,添加webpack脚本后
源模板文件可在 ./angular-cli.json
中配置
./dist/inline.js
小型 webpack 加载程序/polyfill
./dist/main.<content-hash>.bundle.js
包含生成/导入的所有 .js 脚本的主 .js 文件
./dist/styles.<content-hash>.bundle.js
当你为 CSS 使用 Webpack 加载程序时,这是 CLI 方式,它们是通过 JS 此处加载的
在旧版本中,它还创建了 gzip 版本来检查它们的大小,以及 .map
sourcemaps 文件,但由于人们不断要求删除这些文件,因此不再发生这种情况。
其他文件
在某些其他情况下,您可能会发现其他不需要的 files/folders:
./out-tsc/
来自 ./src/tsconfig.json
的 outDir
./out-tsc-e2e/
来自 ./e2e/tsconfig.json
的 outDir
./dist/ngfactory/
来自 AoT 编译器(从 beta 16 开始,不派生 CLI 就无法配置)
Angular 2 使用 Webpack(没有 CLI 设置)
1- Angular2 团队的教程
Angular2 团队发布了 tutorial 使用 Webpack
我创建了教程中的文件并将其放在一个小 GitHub seed project 中。因此您可以快速尝试工作流程。
说明:
npm 安装
npm 启动。为了发展。这将创建一个虚拟 "dist" 文件夹,该文件夹将实时加载到您的本地主机地址。
npm 运行 构建。用于生产。 “这将创建一个可以发送到网络服务器的物理 "dist" 文件夹版本。dist 文件夹是 7.8MB,但实际上只需要 234KB 就可以在网络浏览器中加载页面。
2 - Webkit 初学者工具包
这个 Webpack Starter Kit 提供了比上述教程更多的测试功能,而且似乎很受欢迎。
**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.
直到今天,我仍然认为 Ahead-of-Time 编译食谱是生产捆绑的最佳秘诀。您可以在这里找到它:https://angular.io/docs/ts/latest/cookbook/aot-compiler.html
到目前为止,我对 Angular 2 的体验是 AoT 创建了几乎没有加载时间的最小构建。最重要的是这里的问题是 - 您只需要将几个文件发送到生产环境。
这似乎是因为在编译模板 "Ahead of Time" 时,Angular 编译器将不会随生产版本一起提供。看到您的 HTML 模板标记转换为 javascript 指令也很酷,这些指令很难逆向工程到原始 HTML.
我制作了一个简单的视频,其中演示了 Angular 2 应用程序在开发与 AoT 构建中的下载大小、文件数量等 - 您可以在此处查看:
您可以在此处找到视频中使用的源代码:
"Best" 视场景而定。有时您只关心尽可能小的单个包,但在大型应用程序中您可能不得不考虑延迟加载。在某些时候,将整个应用程序作为一个包提供服务变得不切实际。
在后一种情况下,Webpack 通常是最好的方法,因为它支持代码拆分。
对于单个 bundle,我会考虑 Rollup,如果你有勇气的话,我会考虑 Closure 编译器:-)
我已经创建了我在这里使用过的所有 Angular 捆绑器的样本:http://www.syntaxsuccess.com/viewarticle/angular-production-builds
代码可以在这里找到:https://github.com/thelgevold/angular-2-samples
Angular版本:4.1.x
您可以在 github
上部署您的 angular 应用程序,使用
angular-cli-ghpages
查看 link 了解如何使用此 cli 进行部署。
部署的网站通常会存储在 github
的某个分支中
gh 页
use 可以克隆 git 分支并在您的服务器中像使用静态网站一样使用它
只需在一分钟内使用 webpack 3 设置 angular 4,您的开发和生产 ENV 包将毫无问题地准备就绪
只需按照以下 github 文档
请在当前项目目录中尝试以下 CLI 命令。它将创建 dist 文件夹包。这样您就可以上传 dist 文件夹中的所有文件进行部署。
ng build --prod --aot --base-href.
ng serve 用于为我们的应用程序提供开发服务。生产呢?如果我们查看我们的 package.json 文件,我们可以看到我们可以使用以下脚本:
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
构建脚本使用 Angular CLI 的 ng build 和 --prod 标志。让我们现在试试看。我们可以选择以下两种方式之一:
# 使用 npm 脚本
npm run build
#直接使用cli
ng build --prod
这次给我们四个文件,而不是五个。 --prod 标志告诉 Angular 使我们的应用程序更小。
捆绑 Angular(版本 2、4、6 等)以在实时网络服务器上生产的最佳方法是什么。
请在答案中包含 Angular 版本,以便我们在它移至更高版本时更好地跟踪。
2.0.1 Final
使用 Gulp(TypeScript - 目标:ES5)
一次性设置
npm install
(当 direcory 是 projectFolder 时在 cmd 中 运行)
捆绑步骤
npm run bundle
(当 direcory 是 projectFolder 时在 cmd 中 运行)bundle 生成到 projectFolder / bundles /
输出
bundles/dependencies.bundle.js
[大小:~ 1 MB(越小越好)]- 包含 rxjs 和 angular 依赖项,而不是整个框架
bundles/app.bundle.js
[大小:取决于你的项目,我的是 ~ 0.5 MB ]- 包含您的项目
文件结构
- projectFolder / app /(所有组件、指令、模板等)
- 项目文件夹/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(与 Quickstart guide 相同,仅显示捆绑所需的 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(与 Quickstart guide 相同,不再可用)
(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(生产)- 脚本标签的顺序很关键。将
dist-systemjs.config.js
标记放在 bundle 标记之后仍然允许程序 运行 但依赖包将被忽略,依赖项将从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 是 bootstrap 所在的位置。
我能做到的最好了:)
2 to 13
(TypeScript) 与 Angular CLI
一次性设置
npm install -g @angular/cli
ng new projectFolder
创建一个新应用程序
捆绑步骤
ng build
(当目录为projectFolder
时在命令行中 运行)。flag
prod
用于生产的捆绑包现在是默认的(如果需要,请参阅 Angular documentation 自定义它)。使用以下命令Brotli compression压缩资源
for i in dist/*/*; do brotli $i; done
bundle 默认生成为 projectFolder/dist(/$projectFolder
for v6+)**
输出
大小 Angular 13.2.4
带 CLI 13.2.4
选项 CSS 不带 Angular路由
dist/main-[es-version].[hash].js
您的应用程序捆绑 [ES5 大小:132 KB 新 Angular CLI 应用程序为空,39 KB 压缩]。dist/polyfill-[es-version].[hash].bundle.js
polyfill 依赖项 (@angular, RxJS...) 捆绑 [ES5 大小:37 KB 新 Angular CLI 应用程序为空,12 KB 压缩.dist/index.html
您的应用程序的入口点。dist/runtime-[es-version].[hash].bundle.js
webpack 加载器dist/style.[hash].bundle.css
样式定义dist/assets
从 Angular CLI 资产配置复制的资源
部署
您可以使用启动本地 HTTP 服务器的 ng serve --prod
命令获得您的应用程序的 预览 ,以便可以使用 http:/ 访问带有生产文件的应用程序/本地主机:4200。 这对于生产用途是不安全的。
对于生产用途,您必须将 dist
文件夹中的所有文件部署到您选择的 HTTP 服务器中。
Angular 2 使用 SystemJs 构建器和 gulp
的生产工作流程Angular.io有快速入门教程。我复制了本教程并扩展了一些简单的 gulp 任务,用于将所有内容捆绑到 dist 文件夹,该文件夹可以复制到服务器并像那样工作。我尝试优化所有内容以在 Jenkis CI 上正常运行,因此 node_modules 可以缓存并且不需要复制。
Github 上带有示例应用程序的源代码:https://github.com/Anjmao/angular2-production-workflow
生产步骤- 清理 typescripts 编译的 js 文件和 dist 文件夹
- 编译 app 文件夹中的 typescript 文件
- 使用 SystemJs 捆绑器将所有内容捆绑到 dist 文件夹,并生成用于浏览器缓存刷新的哈希值
- 使用 gulp-html-replace 将 index.html 脚本替换为捆绑版本并复制到 dist 文件夹
- 将 assets 文件夹中的所有内容复制到 dist 文件夹
Node:虽然您始终可以创建自己的构建过程,但我强烈建议使用 angular-cli,因为它具有所有需要的工作流程并且可以正常工作现在完美了。我们已经在生产中使用它,angular-cli 完全没有任何问题。
Angular CLI 1.x.x(适用于 Angular 4.x.x、5.x.x)
这支持:
- Angular 2.x 和 4.x
- 最新的 Webpack 2.x
- Angular AoT 编译器
- 路由(正常和惰性)
- SCSS
- 自定义文件捆绑(资产)
- 其他开发工具(linter、单元和端到端测试设置)
初始设置
ng new project-name --routing
您可以添加 --style=scss
以获得 SASS .scss 支持。
您可以添加 --ng4
以使用 Angular 4 而不是 Angular 2。
创建项目后,CLI 会自动为您运行npm install
。如果你想改用 Yarn,或者只是想看看项目骨架而不安装,check how to do it here.
捆绑步骤
项目文件夹内:
ng build -prod
当前版本需要手动指定--aot
,因为可以在开发模式下使用(虽然速度慢,不实用)
这还会对更小的包执行 AoT 编译(没有 Angular 编译器,而是生成编译器输出)。如果您使用 Angular 4,那么使用 AoT 的包要小得多,因为生成的代码更小。
您可以在开发模式下使用 AoT 测试您的应用程序(sourcemaps,无缩小)和 AoT by 运行ning ng build --aot
.
输出
默认输出目录是./dist
,虽然它可以在./angular-cli.json
.
可部署文件
构建步骤的结果如下:
(注意:<content-hash>
指的是文件内容的哈希/指纹,这是一种缓存破坏方式,这是可能的,因为 Webpack 自己写入了 script
标签)
./dist/assets
按原样从./src/assets/**
复制的文件
./dist/index.html
来自./src/index.html
,添加webpack脚本后
源模板文件可在./angular-cli.json
中配置
./dist/inline.js
小型 webpack 加载程序/polyfill./dist/main.<content-hash>.bundle.js
包含生成/导入的所有 .js 脚本的主 .js 文件./dist/styles.<content-hash>.bundle.js
当你为 CSS 使用 Webpack 加载程序时,这是 CLI 方式,它们是通过 JS 此处加载的
在旧版本中,它还创建了 gzip 版本来检查它们的大小,以及 .map
sourcemaps 文件,但由于人们不断要求删除这些文件,因此不再发生这种情况。
其他文件
在某些其他情况下,您可能会发现其他不需要的 files/folders:
./out-tsc/
来自./src/tsconfig.json
的outDir
./out-tsc-e2e/
来自./e2e/tsconfig.json
的outDir
./dist/ngfactory/
来自 AoT 编译器(从 beta 16 开始,不派生 CLI 就无法配置)
Angular 2 使用 Webpack(没有 CLI 设置)
1- Angular2 团队的教程
Angular2 团队发布了 tutorial 使用 Webpack
我创建了教程中的文件并将其放在一个小 GitHub seed project 中。因此您可以快速尝试工作流程。
说明:
npm 安装
npm 启动。为了发展。这将创建一个虚拟 "dist" 文件夹,该文件夹将实时加载到您的本地主机地址。
npm 运行 构建。用于生产。 “这将创建一个可以发送到网络服务器的物理 "dist" 文件夹版本。dist 文件夹是 7.8MB,但实际上只需要 234KB 就可以在网络浏览器中加载页面。
2 - Webkit 初学者工具包
这个 Webpack Starter Kit 提供了比上述教程更多的测试功能,而且似乎很受欢迎。
**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.
直到今天,我仍然认为 Ahead-of-Time 编译食谱是生产捆绑的最佳秘诀。您可以在这里找到它:https://angular.io/docs/ts/latest/cookbook/aot-compiler.html
到目前为止,我对 Angular 2 的体验是 AoT 创建了几乎没有加载时间的最小构建。最重要的是这里的问题是 - 您只需要将几个文件发送到生产环境。
这似乎是因为在编译模板 "Ahead of Time" 时,Angular 编译器将不会随生产版本一起提供。看到您的 HTML 模板标记转换为 javascript 指令也很酷,这些指令很难逆向工程到原始 HTML.
我制作了一个简单的视频,其中演示了 Angular 2 应用程序在开发与 AoT 构建中的下载大小、文件数量等 - 您可以在此处查看:
您可以在此处找到视频中使用的源代码:
"Best" 视场景而定。有时您只关心尽可能小的单个包,但在大型应用程序中您可能不得不考虑延迟加载。在某些时候,将整个应用程序作为一个包提供服务变得不切实际。
在后一种情况下,Webpack 通常是最好的方法,因为它支持代码拆分。
对于单个 bundle,我会考虑 Rollup,如果你有勇气的话,我会考虑 Closure 编译器:-)
我已经创建了我在这里使用过的所有 Angular 捆绑器的样本:http://www.syntaxsuccess.com/viewarticle/angular-production-builds
代码可以在这里找到:https://github.com/thelgevold/angular-2-samples
Angular版本:4.1.x
您可以在 github
上部署您的 angular 应用程序,使用
angular-cli-ghpages
查看 link 了解如何使用此 cli 进行部署。
部署的网站通常会存储在 github
的某个分支中
gh 页
use 可以克隆 git 分支并在您的服务器中像使用静态网站一样使用它
只需在一分钟内使用 webpack 3 设置 angular 4,您的开发和生产 ENV 包将毫无问题地准备就绪 只需按照以下 github 文档
请在当前项目目录中尝试以下 CLI 命令。它将创建 dist 文件夹包。这样您就可以上传 dist 文件夹中的所有文件进行部署。
ng build --prod --aot --base-href.
ng serve 用于为我们的应用程序提供开发服务。生产呢?如果我们查看我们的 package.json 文件,我们可以看到我们可以使用以下脚本:
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
构建脚本使用 Angular CLI 的 ng build 和 --prod 标志。让我们现在试试看。我们可以选择以下两种方式之一:
# 使用 npm 脚本
npm run build
#直接使用cli
ng build --prod
这次给我们四个文件,而不是五个。 --prod 标志告诉 Angular 使我们的应用程序更小。