1. Use scenario of externals

It prevents packages from being packaged into bundles, and instead obtains these extension dependencies externally at runtime

In other words: the externals configuration item tells Webpack which modules are used in the code to build that need not be packaged, meaning that these templates are provided by the external environment and Webpack can ignore them when packaging

Usage scenario: Therefore, as long as the project is built with WebPack, when the project scale reaches a certain extent, it is necessary to treat the large and basically unchanged third-party package as externals, so as to reduce the size of the entry JS file and shorten the loading time of the first screen. Reduce the dependency package size

Specific use: very simple, two steps (webpack configuration declaration externals, HTML CDN introduction), as shown below, more visible official documentation

Why externals

1, the premise

  • The WebPack analysis tool used
    • Webpack-bundle-analyzer: Visualizes the size of a web package output file using an interactive scalable tree
    • vue ui:vuecli3built-inwebpackAnalysis tools (usevuecli3Set up project available)
  • Available CDN service provider
    • BootCDN
    • unpkg

Use one of the two tools, both are Webpack analysis tools, here is the use of the two tools

2. Analysis of examples of real business projects

The relevant data in this paper is a practical business project in my work, which is built by Vuecli3

(1) VUE UI analysis

Execute at the command line of the business projectvue ui, one will open in the browserhttp://localhost:8000/, click Task > Build > Execute, you can see after executionnpm run buildThe execution time36s, resource volume10.5 M, where the dependent volume8.3 M, proportion of resources72 + %Take a closer look at the dependencies below to see themecharts,element-uiMore than 1M in volume,gojsIt’s not too big

(2) Webpack-bundle-Analyzer analysis
/ / installation
npm install --save-dev webpack-bundle-analyzer
Copy the code
/ / reference
// vue.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
  configureWebpack: {
       // The BundleAnalyzerPlugin is only used in development environments
      plugins: [[...new.// Other plug-ins],... (process.env.NODE_ENV ! = ="production"
                ? [new BundleAnalyzerPlugin()]
                : [])
      ],
  }
}
Copy the code

Start the project and open it in a browserhttp://127.0.0.1:8888/As follows, you can see the dependency packagesvue uiConsistent,echarts,element-ui,gojsLarge volume; andapp.jsLarge volume, increase the length of the first screen

3. How to use externals

The larger third-party packages are separated into externals, which we chose to handle axios, Element-UI, echarts, vue, and Gojs

// vue.config.js
module.exports = {
    publicPath,
    configureWebpack: {
        externals: {
            axios: "axios"."element-ui": "ELEMENT".echarts: "echarts".vue: "Vue".gojs: "go"}},}Copy the code

Key is the package name installed in package.json. Value is the value of the global variable that the package is actually registered or exposed. The formatting shows that the registered value is ELEMENT and depends on vUE; The other packages do the same

Third-party packages do not directly use CDN. Find the package version in node_modules or CDN and copy it to the public/js directory, as shown in the following figure

The entrance to the HTMLCDN throughhtml-webpack-pluginImport by injection rather than manually in HTML as followsManual injection

<html>
  <body id="<%= VUE_APP_NAME %>">
    <div id="app"></div>
    <script
        type="text/javascript"
        src="< % = BASE_URL % > js/vue. @ 2.5.21. Min. Js." "
    ></script>
    <script
        type="text/javascript"
        src="< % = BASE_URL % > js/[email protected]"
    ></script>.</body>
</html>
Copy the code

First address information are relevant to the CDN is hanged in htmlWebpackPlugin. Options. The CDN

We here is vuecli3 writing method, directly with webpack writing method can see htmlWebpackPlugin

// vue.config.js
const appName = process.env.VUE_APP_NAME;
const publicPath = ` /${appName}/ `;

const cdn = {
    js: [
        `${publicPath}Js/vue. @ 2.5.21. Min. Js `.`${publicPath}Js/[email protected] `.`${publicPath}Js/[email protected] `.`${publicPath}Js/[email protected] `.`${publicPath}Js/[email protected] `]};module.exports = {
    publicPath,
    chainWebpack: config= > {
        config.plugin("html").tap(args= > {
            args[0].cdn = cdn;
            returnargs; }); }}Copy the code

Vue must be introduced before element-UI, otherwise an error will be reported

<html>
  <body id="<%= VUE_APP_NAME %>">
    <div id="app"></div>
    <% for (var i in htmlWebpackPlugin.options.cdn &&
    htmlWebpackPlugin.options.cdn.js) { %>
    <script
        type="text/javascript"
        src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"
    ></script>The < %} % ></body>
</html>
Copy the code

4. Verification of externals

When vue UI is executed again, it can be seen that the execution time of NPM run build is reduced to 12s, shortened by 24s, and the resource volume is 9M, wherein the dependency volume is 3.8m, reduced by 8.3-3.8= 4.5m, accounting for 54+%. A closer look at the dependencies below shows that echarts, Element-UI are over 1M in size, and Gojs is also quite large

Webpack-bundle-analyzer analysis results show that the related package sizes are the samevue uiConsistent results. In the development environment,app.jsThe volume has also decreasedAfter deployment to production, you can see below that the chunk-vendor.js volume is246kbDown to41kb, network request duration by3.73 sTo reduce the185ms

  • useexternalsbefore

  • useexternalsafter