捆绑Angular(版本2、4、6,...)以在实时Web服务器上进行生产的最佳方法是什么。
请在答案中包括Angular版本,以便在移至更高版本时可以更好地进行跟踪。
捆绑Angular(版本2、4、6,...)以在实时Web服务器上进行生产的最佳方法是什么。
请在答案中包括Angular版本,以便在移至更高版本时可以更好地进行跟踪。
Answers:
2.x, 4.x, 5.x, 6.x, 7.x, 8.x, 9.x
(TypeScript)与Angular CLInpm install -g @angular/cli
ng new projectFolder
创建一个新的应用程序ng build --prod
(当目录为时,在命令行中运行projectFolder
)
prod
用于生产的标志包(有关生产标志的选项列表,请参阅Angular文档)。
使用Brotli进行压缩使用以下命令压缩资源
for i in dist/*; do brotli $i; done
捆绑包默认生成为projectFolder / dist(/ $ projectFolder for 6)
9.0.0
带有CLI的Angular大小9.0.1
和不带Angular路由的选件CSS
dist/main-[es-version].[hash].js
您的应用程序捆绑了[ES5大小:158 KB,用于新的Angular CLI应用程序为空,压缩40 KB ]。dist/polyfill-[es-version].[hash].bundle.js
捆绑的polyfill依赖项(@angular,RxJS ...)[ES5大小:127 KB,用于新的Angular CLI应用程序为空,压缩37 KB ]。dist/index.html
您的应用程序的入口点。dist/runtime-[es-version].[hash].bundle.js
Webpack加载器dist/style.[hash].bundle.css
样式定义dist/assets
从Angular CLI资产配置复制的资源您可以使用ng serve --prod
启动本地HTTP服务器的命令来预览应用程序,以便使用http:// localhost:4200访问带有生产文件的应用程序。
对于生产用途,必须从dist
您选择的HTTP服务器中的文件夹中部署所有文件。
2.0.1 Final
使用Gulp(TypeScript-目标:ES5)npm install
(当direcory是projectFolder时以cmd运行)npm run bundle
(当direcory是projectFolder时以cmd运行)
束生成到projectFolder /束/
bundles/dependencies.bundle.js
[ 大小:〜1 MB(尽可能小)]
bundles/app.bundle.js
[ 大小:取决于您的项目,我的是〜0.5 MB ]
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);
});
});
{
"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"
}
}
(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);
var map = {
'app': 'dist/app',
};
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>
我能做的最好的:)
inline-templates
运行它内联模板,然后在创建所有的应用程序文件夹和文件的副本dist/app
。然后,如果您使用文件夹作为根目录,则在其中dist-systemjs.config.js
映射的文件夹将不存在。您不想从该文件夹运行您的应用程序吗?如果是这种情况,您将不会在根文件夹中嵌套一个文件夹。我一定在这里想念其他东西。您不需要告诉systemjs使用捆绑的文件,而不是使用该文件夹中的普通文件吗?app
dist/app
dist
dist
dist
dist
dist/app
Angular2团队发布了有关使用Webpack 的教程
我创建了教程中的文件并将其放置在一个GitHub种子项目中。因此,您可以快速尝试工作流程。
说明:
npm安装
npm开始。为了发展。这将创建一个虚拟的“ dist”文件夹,该文件夹将实时重载到您的本地主机地址。
npm运行构建。用于生产。“这将创建一个物理的“ dist”文件夹版本,然后发送到Web服务器。dist文件夹为7.8MB,但实际上仅需要234KB即可在Web浏览器中加载页面。
该Webpack入门工具包提供了比上述教程更多的测试功能,并且似乎很受欢迎。
Angular.io有快速入门教程。我复制了本教程,并扩展了一些简单的gulp任务,将所有内容捆绑到dist文件夹中,这些文件夹可以复制到服务器并像这样工作。我试图优化所有内容以使其在Jenkis CI上正常工作,因此可以缓存node_modules,而无需复制。
Github上的示例应用程序的源代码: https //github.com/Anjmao/angular2-production-workflow
生产步骤Node:虽然您总是可以创建自己的构建过程,但是我强烈建议使用angular-cli,因为它具有所有必需的工作流程,并且现在可以完美运行。我们已经在生产中使用它,而angular-cli完全没有任何问题。
这支持:
ng new project-name --routing
您可以添加--style=scss
对SASS .scss的支持。
您可以添加--ng4
使用Angular 4而不是Angular 2。
创建项目后,CLI将自动npm install
为您运行。如果您想改用Yarn,或者只想查看项目骨架而不进行安装,请在此处查看操作方法。
在项目文件夹中:
ng build -prod
在当前版本中,您需要指定 --aot
手动,因为它可以在开发模式下使用(尽管由于运行缓慢而无法使用)。
这还将对更小的捆绑包(没有Angular编译器,而是生成的编译器输出)执行AoT编译。如果您使用Angular 4,则使用AoT的捆绑包会更小,因为生成的代码会更小。
您可以通过在开发模式下使用AoT(源地图,无缩小)和AoT来测试您的应用,方法是运行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
./dist/main.<content-hash>.bundle.js
./dist/styles.<content-hash>.bundle.js
在较旧的版本中,它还创建了压缩版本以检查其大小和.map
sourcemaps文件,但是由于人们不断要求删除这些文件,因此不再发生这种情况。
在某些其他情况下,您可能会发现其他不需要的文件/文件夹:
./out-tsc/
./src/tsconfig.json
的outDir
./out-tsc-e2e/
./e2e/tsconfig.json
的outDir
./dist/ngfactory/
<content-hash>
从产品包中删除,该怎么办。它可能会导致在获取最新的捆绑软件时出现问题?
直到今天,我仍然发现《提前编译》食谱是生产捆绑的最佳方法。您可以在这里找到它:https : //angular.io/docs/ts/latest/cookbook/aot-compiler.html
到目前为止,我对Angular 2的经验是AoT创建了最小的构建,几乎没有加载时间。最重要的是这里的问题-您只需要将几个文件发送到生产环境即可。
这似乎是因为Angular编译器不会随生产版本一起提供,因为模板是“提前”编译的。看到HTML模板标记转换为javascript指令(将其反向工程为原始HTML十分困难)也很酷。
我制作了一个简单的视频,演示了在开发vs AoT构建中Angular 2应用程序的下载大小,文件数等-您可以在此处查看:
您可以在此处找到视频中使用的源代码:
**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="https://stackoverflow.com/">
</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.
您可以github
使用
angular-cli-ghpages部署您的angular应用程序
请查看链接以找到如何使用此cli进行部署。
已部署的网站将被存储在某个分支的github
典型
gh页
use可以克隆git分支,并像在服务器中使用静态网站一样使用它
“最佳”取决于场景。有时候,您只关心最小的单个捆绑包,但是在大型应用程序中,您可能不得不考虑延迟加载。在某个时候,将整个应用程序作为一个捆绑包提供是不切实际的。
在后一种情况下,Webpack通常是最好的方法,因为它支持代码拆分。
对于单个捆绑包,如果您觉得很勇敢,可以考虑使用汇总,或Closure编译器:-)
我已经创建了我在这里使用过的所有Angular捆绑器的示例:http : //www.syntaxsuccess.com/viewarticle/angular-production-builds
该代码可以在这里找到: https //github.com/thelgevold/angular-2-samples
角度版本:4.1.x
只需在一分钟内用webpack 3设置angular 4,您的开发和生产ENV捆绑包将准备就绪,没有任何问题,只需遵循以下github doc
ng服务作品,用于为开发目的服务我们的应用程序。生产呢?如果我们查看package.json文件,可以看到可以使用以下脚本:
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
构建脚本使用带有--prod标志的Angular CLI的ng构建。让我们现在尝试。我们可以通过以下两种方式之一进行操作:
#使用npm脚本
npm run build
#直接使用cli
ng build --prod
这次我们得到的是四个文件,而不是五个。--prod标志告诉Angular使我们的应用程序更小。