Project final packaging optimization

Posted by web.designer.iq on Sun, 31 Oct 2021 10:59:41 +0100

Packaging Optimization - Overview

Project development completed

pack:

  • Package with webpack (put. Vue,. JS,. Less --------- >. JS,. CSS,. HTML)

  • The command npm run build is provided in the project

Packaging Optimization:

  • On the premise of ensuring the availability of functions, let our files be as small as possible

  • On the premise of ensuring the availability of functions, let our pages display faster

After packaging, you will get the dist directory. If you want to double-click index.html, you need to configure it in vue.config.js in advance: vue.config.js

{
    publicPath: './'
}

Packaging Optimization - route lazy loading

problem

{
    path: '/login',
    component: () => import('@/views/login/index'),
    hidden: true
  },

What does the above component: () = > Import ('@ / views / login / index') mean?

How is it different from the writing below?

const Login = import('@/views/login/index')
{
    path: '/login',
    component: Login,
    hidden: true
  },

What is routing lazy loading

A route to a component represents a page. Lazy loading means that the resources corresponding to this component are loaded only when the route enters this page.

Magic annotation in route lazy loading

You can manually set the name of this file by specifying webpackChunkName in the comment. The following is an example.

components = () => import(/* webpackChunkName:"login"*/ "../component/Login.vue");

Summary

  • Before lazy loading without setting the route: all the components corresponding to all pages will be packaged into one. js file

  • Set after the routing page is loaded: all the components corresponding to the page will be packaged into an independent. js file, and will be loaded only after entering the routing page.

Packaging Optimization - package size analysis

target

Analyze the package size of the developed application

Packet size analysis

We have integrated functions and written many components, which will eventually be packaged into a pile of files (there will be many. js files in the js directory). What is the size of each package?

We can use the performance analysis tool provided by Vue cli to package and analyze all the functions we have developed. It is very simple to use

npm run preview -- --report

This command will perform dependency analysis from our portal main.js to analyze the size of each package, which is convenient for us to observe and optimize

After executing this command, we will see the following similar output in the console

visit: http://localhost:9526/report.html

As shown in the figure, the larger the box, the larger the file occupied by the file, and the larger the file, the higher the requirements for network bandwidth and access speed, which is the direction of our optimization.

Package optimization - remove the console log

In vue.config.js, configure:

chainWebpack(config) {
    config.optimization.minimizer('terser').tap((args) => {
      args[0].terserOptions.compress.drop_console = true
      return args
    })
}

webpack configuration exclusion packaging - overall analysis

review

Packaging process: start from main.js and package by webpack

put questions to

Do we need to package all the third-party libraries into our own projects?

unwanted!

The xlsx package is very large (715K), and such plug-ins do not need to be updated for a long time, so there is no need to package them!

thinking

  1. When packing, don't type these bags in

  1. Introduce these packets from the network

webpack configuration excluding packaging - packaging slimming

target

By configuring Vue cli, some packages that are not normally used are excluded from the package file.

For example, let webpack not package vue xlsx and element

Mode of use

First find vue.config.js and add the external item as follows:

configureWebpack: {
  // Configure the title of the page for a single page application
  // Omit other
  externals: {
     /**
      * externals Object property resolution.
      *  Basic format:
      *     'Package name ':' name introduced in project '
      *  
    */
    'vue': 'Vue',
    'element-ui': 'ElementUI',
    'xlsx': 'XLSX'
  },
    
    
  resolve: {
    alias: {
      '@': resolve('src')
    }
  }
}

When we run the package again, we will find that the volume of the package has been greatly reduced: the above three packages are no longer in the package target file.

webpack configuration excludes packaging - reference network resources

target

Make relevant configuration: introduce other packages into index.html through public network resources

Specific configuration - effective in production environment

Note that when developing a project, file resources can still be from the local node_modules. Only when the project is online can external resources be used. At this point, we can use environment variables to distinguish. The details are as follows:

In the vue.config.js file:

let externals = {}
let cdn = { css: [], js: [] }
const isProduction = process.env.NODE_ENV === 'production' // Determine whether it is a production environment
if (isProduction) {
  externals = {
      /**
      * externals Object property resolution:
      * 'Package name ':' name introduced in project '
    */
      'vue': 'Vue',
      'element-ui': 'ELEMENT',
      'xlsx': 'XLSX'
  }
  cdn = {
    css: [
      'https://Unpkg. COM / element UI / lib / theme talk / index. CSS' / / element UI CSS style sheet
    ],
    js: [
      // vue must at first!
      'https://unpkg.com/vue@2.6.12/dist/vue.js', // vuejs
      'https://unpkg.com/element-ui/lib/index.js', // element-ui js
      'https://cdn.jsdelivr.net/npm/xlsx@0.16.6/dist/xlsx.full.min.js', // xlsx
    ]
  }
}

webpack external configuration item

configureWebpack: {
  // Configure the title of the page for a single page application
  name: name,
+ externals: externals,
  resolve: {
    alias: {
      '@': resolve('src')
    }
  }
}

Inject CDN configuration into html template

Then inject it into index.html through HTML webpack plugin:

In vue.config.js, set

chainWebpack(config) {
  config.plugin('preload').tap(() => [
    {
      rel: 'preload',
      fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
      include: 'initial'
    }
  ])
  // Omit other
  
  // Inject cdn variables (executed during packaging)
+  config.plugin('html').tap(args => {
+    args[0].cdn = cdn // Configure cdn to plug-in
+    return args
+  })
  // Omit other
}

Find public/index.html and inject css and js successively by configuring CDN Config.

Modify the head as follows:

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= webpackConfig.name %></title>
​
      <!-- Import style -->
+      <% for(var css of htmlWebpackPlugin.options.cdn.css) { %>
+        <link rel="stylesheet" href="<%=css%>">
+        <% } %>
​
​
    <!-- introduce JS -->
+    <% for(var js of htmlWebpackPlugin.options.cdn.js) { %>
+      <script src="<%=js%>"></script>
+    <% } %>
  </head>

Pack and check the effect

npm run build:prod

Check whether css and js are imported in the generated index.html

Change publicPath

publicPath: './',

Open it again, and you can double-click dist/index.html to view the effect

Summary of overall thinking

Understanding CDN

put questions to

Are the network resources cited above reliable? Is there any other address available?

CDN

The full name of CDN is called "Content Delivery Network", and it is called content distribution network in Chinese. We use it to improve access speed.

1. Free: public CDN

2. Purchase cloud services

  after

Putting some static resources: css,. js, pictures and videos on a third-party CDN server can speed up the access speed.

Benefits of using CDN in front-end projects

  1. Reduce the package volume packaged by the application

  2. Accelerate access to static resources

Deploying applications in nodejs environment

target

Pack the packaged code online (local simulation)

The front end modifies the baseUrl in the production environment

The front end modifies the baseUrl of the production environment

.env.production

VUE_APP_BASE_API = 'http://ihrm-java.itheima.net'

Repackage

Deploying projects using the koa framework

So far, we have completed the development process of a front-end engineer. According to the normal practice, the O & M / back-end will deploy our code to Alibaba cloud's nginx service. For us, we can deploy it to the local nodejs environment

  1. Create web service folder hrServer

  2. Under this folder, initialize npm

    npm init -y

  3. Install the server frame koa (express or egg can also be used)

    npm install koa koa-static

  4. Create a new public directory in hrServer, and copy the contents of dist directory packaged in the previous section to hrServer/public

  5. Create app.js in the root directory. The code is as follows

    const Koa  = require('koa')
    const serve = require('koa-static');
    ​
    const app = new Koa();
    app.use(serve(__dirname + "/public")); //Static code under public
    app.listen(3333, () => {
      console.log('Start of human resources project: 3333 port')
    })

history routing mode - be familiar with two routing modes

target

Understand the routing modes of two single page applications and their differences

Two routing modes for single page applications

hash mode

Hash mode: use the hash of the URL to simulate a complete URL, and there will be "#" in the displayed network path

Although the hash appears in the URL, it will not be included in the HTTP request and has no impact on the back end. Therefore, there will be no problem refreshing after changing the hash

Example of hash mode: http://localhost:8080/#/home http://localhost:8080/#/user

Principle: hashChange

history mode

history mode: beautified hash mode. The path does not contain "#". history api dependent on Html5

Because the address is changed, the back-end will be requested according to the modified address during refresh. The back-end configuration processing is required to map the address access, otherwise 404

Example of history mode: http://localhost:8080/home http://localhost:8080/user

principle: popState, pushState()

vue project modify routing mode

Change the routing mode from hash to history

Up to now, we have been using hash mode and packaging. We try to use history mode

Changing to history mode is very simple. You only need to change the mode type of the route to history. In src/router/index.js

// Create routing instance
const createRouter = () => new Router({
  mode: 'history', // require service support
  scrollBehavior: () => ({ y: 0 }),
  // Specify routing rules
  routes: [
    ...constantRoutes // Static routing, home page
  ]
})

After configuration, our access path will run normally without adding # sign. This is because the webpack is configured to handle the history mode by default

Deploying applications in nodejs environment - solving history

problem

There is an error when the code packaged in history mode is placed on the server for operation: the page will be lost as soon as the browser is refreshed

reason

First run

Refresh again

Why does the hash mode refresh not report an error

Solve the problem of history page access

Install koa Middleware

npm install koa2-connect-history-api-fallback #Middleware specialized in history mode

Registration Middleware

const Koa  = require('koa')
const serve = require('koa-static');
const { historyApiFallback } = require('koa2-connect-history-api-fallback');
const app = new Koa();
// This sentence means that all requests except the interface are sent to index.html
app.use(historyApiFallback({ 
  whiteList: ['/api']
}));  // whiteList here means white list
​
app.use(serve(__dirname + "/public")); //Static code under public
​
app.listen(3333, () => {
  console.log('Start of human resources project')
})

At this time, the problem of refreshing 404 is solved (Note: if you click login, remember to clear the cookies and then test)

Solve the cross domain problem of production environment in nodejs environment

problem

At this time, we click log in, and the interface does not work. We need to configure the cross domain in the production environment. The principle is the same as that we configured with Vue cli before. They are all forwarded through the intermediate server to proxy the real interface

Modify environment variables

.env.production

VUE_APP_BASE_API = '/api'

Install cross domain proxy Middleware

hr-serve

npm install koa2-proxy-middleware

Configure spanning agents

const Koa  = require('koa')
const serve = require('koa-static');
const { historyApiFallback } = require('koa2-connect-history-api-fallback');
const proxy = require('koa2-proxy-middleware')
const app = new Koa();
​
app.use(proxy({
  targets: {
    '/api/(.*)': {
        target: 'http://IHRM Java. Itheima. Net ', / / back end server address
        changeOrigin: true
    }
  }
}))
// This sentence means that all requests except the interface are sent to index.html
app.use(historyApiFallback({ 
  whiteList: ['/api']
}));  // whiteList here means white list
app.use(serve(__dirname + "/public")); //Static code under public
​
app.listen(3333, () => {
  console.log('Start of human resources project')
})

Topics: Javascript Vue.js Webpack