默认angular配置:入口文件size高达7MB,DOMContentload和load别离为3.22s和3.43秒
1、装置 angular-builders
npm install @angular-builders/custom-webpack --save-devnpm 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加载,缩小申请