This article is based on the author’s previous article <

> to further optimize the practical experience sharing!

As our project grows, packaging will get slower and slower. Each package will package the third party JS again, but these third party js will not change often, how to package the third party JS only once?

Asynchronous components

Let’s start by changing the routing component to the asynchronous component. The official documentation

// src/router/index.js. exportdefault new VueRouter({
  routes: [{path: '/'.name: 'HelloWorld'.component: resolve= > require(['@/components/HelloWorld'], resolve)
    }
  ]
})
Copy the code

webpack DllPlugin

Webpack provides a plug-in, DllPlugin, for packaging infrequently changing JS separately.

  1. First of all, we havesrcCreating a Directoryvendor.jsimportThird party JS:
import 'babel-polyfill'
import Vue from 'vue'
import Vuex from 'vuex'
import VueRouter from 'vue-router'
import {sync} from 'vuex-router-sync'
import axios from 'axios'
import ElementUI from 'element-ui'
Copy the code

All you need to do here is import.

  1. inbuildCreating a Directorywebpack.dll.conf.jsConfiguration file:
var path = require('path')
var webpack = require('webpack')

var context = path.join(__dirname, '.. ')

module.exports = {
  entry: {
    vendor: ['./src/vendor.js'}, output: {// Put the js package in static directory, and copy it to dist directory during build. Path: path.join(context, dist)'static/js'),
    filename: '[name].dll.js',
    library: '[name]'
  },
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  },
  plugins: [
    new webpack.DllPlugin({
      path: path.join(context, '[name].manifest.json'),
      name: '[name]'Context: context}), / / compression js code new webpack. Optimize. UglifyJsPlugin ({compress: {warnings:false}, output: {// delete comments:false}}})]Copy the code

Json, the location of the context. json is optional, and the name must be consistent with the library in output. Resolve: copy vue$from webpack.base.conf.js. Note that dllPlugin supports only Array entries.

  1. inpackage.jsonInsert script:build:dll
"scripts": {
  "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
  "start": "npm run dev",
  "lint": "eslint --ext .js,.vue src",
  "build": "node build/build.js",
  "build:dll": "webpack --config build/webpack.dll.conf.js --progress"
}
Copy the code

Running NPM run build: DLL will generate vendor.dll.js in static/js

Here is our third party JS package, so how to use it?

webpack DllReferencePlugin

  1. Webpack providesDllReferencePlugin. Modify thebuild/webpack.base.conf.js:
const webpack = require('webpack')

module.exports = {
  ...
  plugins: [
    new webpack.DllReferencePlugin({
      // The name parameter is the same as the name parameter in dllPlugin
      name: 'vendor'.// dllplugin packages the output manifest.json
      manifest: require('.. /vendor.manifest.json'),
      // This is the same as the context in dllPlugin
      context: path.join(__dirname, '.. ')})]. }Copy the code

Note: The context must be the same as the context in the dllPlugin

  1. Modify thebuild/webpack.prod.js. Delete the configuration from the previous articleexternalsConfiguration items:
module.exports = {
  ...
  // externals: {
  // 'vue': 'Vue',
  // 'vuex': 'Vuex',
  // 'vue-router': 'VueRouter',
  // 'element-ui': 'ELEMENT'
  // }. plugins: [ ...// Remove CommonsChunkPlugin here
    // new webpack.optimize.CommonsChunkPlugin({
    // name: 'vendor',
    // minChunks (module) {
    // // any required modules inside node_modules are extracted to vendor
    // return (
    // module.resource &&
    // /\.js$/.test(module.resource) &&
    // module.resource.indexOf(
    // path.join(__dirname, '.. /node_modules')
    / /) = = = 0
    / /)
    / /}
    // }),
    // Remove CommonsChunkPlugin here
    // new webpack.optimize.CommonsChunkPlugin({
    // name: 'manifest',
    // minChunks: Infinity
    // }),. ] }Copy the code

Get rid of these two Commonschunkplugins, since we already packaged them with dllPlugin and don’t need them here.

  1. willindex.dev.htmlindex.prod.htmlMerge into one fileindex.html, remove the CDN resources and importvendor.dll.js:
<head>.<link rel="stylesheet" href="https://cdn.bootcss.com/element-ui/2.0.7/theme-chalk/index.css">
</head>

<body>
  <div id="app"></div>
  <! -- built files will be auto injected -->
  <script src="static/js/vendor.dll.js"></script>
</body>
Copy the code

Here, the element-UI style file is still CDN loaded, because we didn’t package the style in Vendor.dlL.js

  1. Modify thewebpack.dev.conf.jswebpack.prod.conf.jsInside the template file configuration:
. plugins: [ ... new HtmlWebpackPlugin({template: 'index.html'})]Copy the code
  1. Modify thesrcinsidevuex,vue-routerThe use of:
// src/router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

// src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
Copy the code

At this point, all our preparatory work is done. Next, run NPM run dev to start the local development service:

Package: NPM run build, then deploy to nginx service, start nginx service:

conclusion

The reason for placing vendor.dll.js in the static/js directory is to facilitate the use of the same path for development and distribution. To keep the js and style versions of Element-UI consistent, add less or SCSS to your project, and then add @import to your project. This will be packaged separately into your CSS.

Sample project portal: VuE-SPA-starter-kit, welcome to ridicule and star!