这里讲讲,angular2在生产模式下用webpack2进行打包的方法:
//使用rollup打包还是比较坑的,功能及插件上都不如webpack, 关键不支持代码分离,导致angular里的lazy loader将无法使用。
具体步骤:
angular=>aot=>webpack(Tree shaking&& Uglify)
angular=>aot:
首先你需要的依赖:
"@angular/compiler" "@angular/compiler-cli" "@angular/platform-browser"。
npm install 安装他们。
以下是目录结构:
... ./package.json ./tsconfig.aot.json ./tsconfig.json ./webpack.pro.config.js ./src/ |--./main.ts |--./main.aot.ts |--./app.module.ts |--./router.module.ts |--./app.component.ts |--./child/ |--./child.module.ts |--./child.component.ts
准备一个tsconfig.aot.json:
{ "compilerOptions": { "module": "es2015", "moduleResolution": "node", "declaration": true, "target": "es5", "noImplicitAny": false, "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "typeRoots": [ "./node_modules/@types" ], "lib": [ "dom", "es2015" ] }, "angularCompilerOptions": { //这是aot.json独有的,genDir:"." ,示意,生成的NgFactory文件放于原文件路径内。你也可以genDir:‘aot‘,放在aot文件内,但我建议你放在原路径里。 "genDir": ".", "skipMetadataEmit":true }, "files":[ "src/app.module.ts", //从app.module.ts这个文件开始进行编译。 "src/child/child.module.ts" //这是lazy loader模块,因为是惰性加载模块,而没有在原模块中import或require它,所以需要单独编译。 ], "compileOnSave": false, "exclude": [ "node_modules", "src/polyfill.ts" ] }
接下来运行npm run ngcStart; // package.json : "ngcStart": "ngc -p tsconfig-aot.json"
你会发现 src/文件内生成了许多*.ngfactory.ts , 这些就是提供给生产环境,最终使用的angular文件。自此预编译完成。
(.js文件可以删除它,‘rimraf src/*.js src/*/*.js‘。)
aot=>webpack:
我们需要从main.aot.ts来引导这些aot文件,这是main.aot.ts文件(别从main.ts引导):
import { platformBrowser } from ‘@angular/platform-browser‘; import { AppModuleNgFactory } from ‘./app.module.ngfactory‘; platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);
好了,下面是webpack的配置:
{ /....../ entry:{ ‘main‘:‘./src/main.aot.ts‘ }, output:{ path:‘dest‘, filename:‘[name].bundle.js‘, chunkFilename:‘[id].chunk.js‘ }, module:{ rules:[ {test: /\.ts$/,use:[ ‘awesome-typescript-loader‘, //我建议你用awesome-typescript-loader进行ts加载。 ‘angular2-template-loader‘, ‘angular2-webpack2-lazy-children-loader‘ //这是针对lazy loader 的插件,后面会单独说 ]}, {test:/\.json$/,use:‘json-loader‘}, {test:/\.html$/,use:‘raw-loader‘}, {test:/\.(jpg|png|gif)/,use:‘file-loader?name=[path][name].[ext]‘} ] } plugins:[ /..../ new webpack.optimize.UglifyJsPlugin({ /*mini化,并进行treeShaking. 虽然这个treeShaking存在一个问题。不过目前我并没有一个好办法,也没那多时间了. babili-webpak-plugin虽然shaking掉了class,但文件大小好像并没变化。 而rollup的treeShaking非常出色,最后得到的文件比webpack UglifyJsPlugin要小几十KB。可是这东西,不好用。:( */ compress:{warnings:true} }) ] }
最后得到的main.bundle.js就是我们想要的主文件了。
0.chunk.js是child.module所对应的文件。
main.bundle.js 200~400KB 大小。比起不经过aot得到的mini文件(1MB多)小了很多。最后gz压缩,可以控制在100KB左右。最小可以50KB。
-----------------------------------
说说‘angular2-webpack2-lazy-children-loader’
我们这样使用lazy loader:
loadChildren:‘ child.module#ChildModule‘
可是aot编译后的文件名字成了child.module.ngfactory.ts,
里面的变量成了ChildModuleNgFactory。所以为了生产模式,你需要改写成:
loadChildren:‘ child.module.ngfactory#ChildModuleNgFactory‘
如果你手动更改了,那么,你可以继续使用‘angular-router-loader’在webpack中进行加载。
但使用‘angular2-webpack2-lazy-children-loader’在于,它会自动判断,并在加载时replace这段string。所以你,在生产或者开发模式都可写成你原本的格式了。
------------------------------
可以下载尝试:https://github.com/zhantewei2/angular-aot-webpack