Angular9 自定义webpack配置拆分入口文件 优化加载速度

默认angular配置:入口文件size高达7MB,DOMContentload和load分别为3.22s和3.43秒
Angular9 自定义webpack配置拆分入口文件 优化加载速度_第1张图片
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/**"
            ]
          }
        }
      }

最终优化完结果
Angular9 自定义webpack配置拆分入口文件 优化加载速度_第2张图片
image.png
觉得请求有点多,下步打算加入file-loder,url-loder把图片转成base64加载,减少请求

你可能感兴趣的:(Angular9 自定义webpack配置拆分入口文件 优化加载速度)