默认 angular 配置:入口文件 size 高达 7MB,DOMContentload 和 load 别离为 3.22s 和 3.43 秒
1、装置 angular-builders
npm install @angular-builders/custom-webpack --save-dev
npm install @angular-devkit/build-angular --save-dev
2. 批改 angular.json 中 build 和 server 的配置
"architect": {
......
"build": {
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {"path": "./webpack.config.js"}
}
},
"serve": {
"builder": "@angular-builders/custom-webpack:dev-server",
"options": {
"customWebpackConfig": {"path": "./webpack.config.js"}
}
}
}
3. 自定义 webpack.config.js 配置
const webpack = require('webpack');
const pkg = require('./package.json');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
optimization: {
splitChunks: {chunks: 'all', // 共有三个值可选:initial( 初始模块)、async(按需加载模块) 和 all(全副模块)
minSize: 30000, // 模块超过 30k 主动被抽离成公共模块
// minChunks: 1, // 模块被援用 >= 1 次,便宰割
maxAsyncRequests: 5, // 异步加载 chunk 的并发申请数量 <=5
maxInitialRequests: 5, // 一个入口并发加载的 chunk 数量 <=3
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
angular: {
name: 'angular',
test: /[\\/]node_modules[\\/]@angular[\\/]/,
priority: -8
},
monaco_editor: {test: /[\\/]node_modules[\\/](monaco-editor)[\\/]/,
name: 'monaco-editor',
priority: -9
},
vendors: {
name: 'vendors',
test: /[\\/]node_modules[\\/]/,
priority: -10
},
// 缓存组,会继承和笼罩 splitChunks 的配置
default: {
// 模块缓存规定,设置为 false,默认缓存组将禁用
minChunks: 2, // 模块被援用 >= 2 次,拆分至 vendors 公共模块
priority: -20, // 优先级
reuseExistingChunk: true // 默认应用已有的模块
}
}
}
},
plugins: [
new webpack.DefinePlugin({APP_VERSION: JSON.stringify(pkg.version)
}),
// new BundleAnalyzerPlugin(),
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.join(__dirname, 'src/index.html'),
chunksSortMode: 'manual',
chunks: ['styles', 'runtime', 'polyfills', 'scripts', 'vendors', 'main'] // 限定程序,main.js 必须在最初
})
]
};
··这里阐明下配置
(1).BundleAnalyzerPlugin
我正文掉了,因为不想编译时候主动启动,我抉择 npm 退出 script 命令,有须要的时候执行命令生成 stat.json 并运行
"analyze": "webpack-bundle-analyzer dist/stats.json"
(2) DefinePlugin 测试 webpack.config.js 是否被引入。注:ng build 模式或 builder 为 custom-builder 才失效
app.component.ts 里申明
declare var APP_VERSION: string;
@Component({
selector: 'root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.less']
})
ngOnInit(): void {console.log('APP_VERSION:', APP_VERSION);
}
(3)最重要的是 htmlwebpackplugin
splitChunks 把最次要的 node_modules angular monaco-editor 三个包最次要的大型包都从主入口 main.js 抽出来了。
如果没有用 htmlwebpackplugin,angular.json 默认配置生成的 html,不会引入我新抽出来的 js,配置 mergeRules,mergeStrategies 都不好使。
"customWebpackConfig": {
··"path": "./webpack.config.js",
"mergeRules": {"externals": "replace"},
"mergeStrategies": {"module.rules": "prepend"},
"replaceDuplicatePlugins": true
}
最终用 htmlwebpackplugin 生成的 html,并批改 angular.json 配置, 把原 html 批改名字
"index": {
"input": "src/index.html",
"output": "index-old.html"
},
最初附上残缺的 angular.json
"architect": {
"build": {
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"outputPath": "dist/onenote",
"index": {
"input": "src/index.html",
"output": "index-old.html"
},
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets",
{
"glob": "**/*",
"input": "./node_modules/mathjax",
"output": "/"
},
{
"glob": "**/*",
"input": "./node_modules/@ant-design/icons-angular/src/inline-svg/",
"output": "/assets/"
},
{
"glob": "**/*",
"input": "./WEB-INF",
"output": "/WEB-INF/"
}
],
"styles": [
"src/styles/theme/light/antd-light.less",
"src/styles.less",
"./node_modules/highlight.js/styles/github.css",
"./node_modules/monaco-editor/min/vs/editor/editor.main.css",
"./node_modules/github-markdown-css/github-markdown.css"
],
"stylePreprocessorOptions": {
"includePaths": [
"src/styles/theme",
"src/styles/theme/dark",
"src/styles/theme/light"
]
},
"scripts": [
"node_modules/mathjax/MathJax.js",
"node_modules/systemjs/dist/s.js",
"node_modules/systemjs/dist/extras/amd.js",
"node_modules/systemjs/dist/extras/named-register.js",
"node_modules/systemjs/dist/extras/use-default.js"
],
"customWebpackConfig": {"path": "./webpack.config.js"}
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": true,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
},
"analyzer": {
"optimization": true,
"outputHashing": "all",
"sourceMap": true,
"namedChunks": true,
"extractCss": true,
"extractLicenses": true,
"vendorChunk": true,
"buildOptimizer": true,
}
}
},
"serve": {
"builder": "@angular-builders/custom-webpack:dev-server",
"options": {
"browserTarget": "onenote:build",
"customWebpackConfig": {"path": "./webpack.config.js"}
},
"configurations": {
"production": {"browserTarget": "onenote:build:production"}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {"browserTarget": "onenote:build"}
},
"test": {
"builder": "ngx-build-plus:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": ["src/styles.less"],
"scripts": [],
"assets": [
"src/favicon.ico",
"src/assets"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": ["**/node_modules/**"]
}
}
}
最终优化完后果
感觉申请有点多,下步打算退出 file-loder,url-loder 把图片转成 base64 加载,缩小申请