默认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加载,缩小申请