takeaway

After learning four sections, we can say that we have a deep understanding of Webpack, I believe you can also according to the content of their own website for a series of packaging.

If you’ve followed me here since the first session, you’re my old webpack buddy. You’ll also learn a lot of interesting things, such as:

  • The Library’s packaging
  • Configuring request forwarding (proxy cross domain)
  • Eslint/Typescript configuration
  • Multi-page packaging
  • Webpack performance optimization
  • Common specifications package configuration items

let’s go!

The Library’s packaging

Ordinary packaging

Let’s say we want to write a library file for ourselves and others to use, so how do we package our library files?

Since github has submitted the first four sections of content, in order not to affect the learning of new partners, I have formed the habit of creating new files. Here I will create a new folder and re-use Webpack to build my own library.

Create a new Library directory, then generate the default configuration and make some simple changes.

Json {"name": "library", "version": "1.0.0", "description": "this is my library", "main": "index.js", "scripts": { }, "keywords": [], "author": "jsxin", "license": "ISC" } // install npm install webpack webpack-cli --saveCopy the code

If this step is too much for you, I suggest you take a look at my basic use of WebPack and take a few minutes to see what I’m doing (shock! A man did this with webpack).

As usual, our own js files will be placed under SRC.

// math.js export function add(a, b) { return a + b } export function minus(a, b) { return a - b } export function multiplication(a, b){ return a * b } export function division(a, b){ return a / b } // string.js export function join(a, b){ return a + ' ' + b } // index.js import * as math from './math' import * as str from './string' The console. The log (math. The add (1, 3))Copy the code

Create webpack.config.js and write the packing rules. Then add your own script to package.json

// webpack.config.js
const path = require('path')
module.exports = {
  entry: {
    main: './src/index.js'
  },
  output: {
    filename: 'library.js',
    path: path.resolve(__dirname, 'dist')
  }
}

// package.json
"build": "npx webpack"
Copy the code

After a simple configuration, we can use the NPM run build command to package, and then generate the dist directory. To verify our packaging, we will manually create index.html under the dist directory

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, Initial - scale = 1.0 "> < title > packaging field < / title > < / head > < body > < script SRC =". / main. Js "> < / script > < / body > < / HTML >Copy the code

And then we run it with the live-server, and it gives us a 4 in the console, which is nice.

Packaging library

However, as we said before, we need to package a library file, which is also used by others. In Vue and React, we introduce a library.

import xx from 'xx'
Copy the code

So how did he find our library file address according to XX?

We’ll start by exporting our two logical files in index.js.

// index.js
import * as math from './math'
import * as str from './string'

export default { math, str }
Copy the code

And then we run our file in the package configuration and import it by any means.

const path = require('path')
module.exports = {
  mode: 'production',
  entry: {
    main: './src/index.js'
  },
  output: {
    filename: 'library.js',
    path: path.resolve(__dirname, 'dist'),
    libraryTarget: 'umd',
    library: 'library'
  }
}
Copy the code

In libraryTarget, we use UMD, which means we can import by module, package import, etc

import library from 'library'
const library = require('library')
require(['library'],()=>{})
script src = ''
...
Copy the code

Library, mount window,window.liarbry, global in NodeJS, etc

It will be used with library, which will be the name we use.

Do not package the double reference library

We’re ready to use library, but we’re not done yet. If I wanted to change my String.js at this point, I’d like to use the LoDash library to redo my Join method.

// install
npm install lodash --save

// string.js
import _ from 'lodash'

export function join(a, b){
  _.join([a,b],' ')
}
Copy the code

At this point, when we pack, we’re up to 72KB. What if someone else uses loDash when they’re using our library?

import lodash from 'lodash'
import library from 'library'

Copy the code

So there will be two copies of LoDash, and when there is a LoDash we should not pack this file into our library.

externals: 'lodash',
Copy the code

That way, when loDash is detected, it won’t be packaged into our library.

Others should simply introduce LoDash above the business code when using it.

Package Ts files

If you have read section 2, you will encounter the end of the ts/ TSX file, so we will go back to the verification, use the specified loader to package, let’s see what we will use.

npm install ts-loader typescript -D
Copy the code

Ts-loader packages our TS files, typescript reads our TS code, and the two definitely want to mix. After the installation, we directly configure packaging.

module:{
    rules: [{
      test: /\.(ts|tsx)/,
      use: ['ts-loader'],
      exclude: /node_modules/
    }]
  }
Copy the code

Exclude is a TS file in node_modules, so I don’t package it, and that’s pretty much it.

Ok, an error was reported that a tsconfig.json file was missing, we created it in the root directory.

{
  "compilerOptions": {
    "outDir": "./dist",
    "module": "ES6", 
    "target": "ES5", 
    "allowJs": true 
  }
}
Copy the code
  • OutDir: When webpack is packaged, the compilation directory is placed in the dist directory
  • Module: Es Module is used
  • Target: Packaged into ES5 syntax
  • AllowJs: Allows js files to be introduced in TS

Pack again, nice.

WebpackDevServer implements request forwarding

Cross-domain, as is often the case with the front end, if you have the soul to ask – what is cross-domain?

.

Let’s install AxiOS for our request.

npm install axios -S
Copy the code

And then a little show, gavasulpte

import axios from 'axios'

axios.get('https://www.fastmock.site/mock/13a9249208c0dbcf0e5f7cd2000f89ff/lists/lists')
  .then(res => {
    console.log(res)
  })
Copy the code

It’s nice to get the data, but normally it should be cross-domain, but the back end helps you with access restrictions.

So how do we solve the cross-domain access problem ourselves?

Going back to the basic configuration in Section 3, let’s start with a little bit of the configuration we talked about earlier.

devServer: {
    contentBase: './dist',
    open: true,
    port: 8080,
    hot: true,
    hotOnly: true,
    proxy: {
      '/api': 'https://www.fastmock.site/mock/'
    }
  },
Copy the code

This allows us to proxy our interface to a specific website, which is a common cross-domain solution in VUE, so it looks like webPack is the solution.

Configuration Eslint

What is Eslint

ESLint is an open source JavaScript code inspection tool designed to standardize team code. (Some explanations…)

Eslint installs and initializes

npm install eslint -D

npx eslint --init
Copy the code

Then post my choice…

This will generate a.eslintrc.js file in my root directory

Eslint code checks

This can be used if you want to check code specifications

npx eslint file/dir
Copy the code

Of course, this would be too cumbersome to detect, so we can also directly install the eslint plugin in vscode and it will be red if your code is not standard. Then the mouse move up can be directly prompted the reason, we can modify it.

Here is the esLint official website direct link

Eslint-loader

If we were to package ESLint, we would download the Loader first because it would tell us how to package the file.

npm install eslint-loader --save-dev
Copy the code

And then check the code, which we usually do for js files

// webpack.config.js
{
      test: /\.js$/,
      exclude: /node_modules/,
      use: ['babel-loader','eslint-loader']
    }
Copy the code

But this time we are packaged, or would like a command-line prompt an error, we so we can add a configuration in the devserver, if there is a problem, he will give us in the browser pop-up a layer of black, to tell us the problem, believes that many developers with the vue framework is not unfamiliar to this layer.

overlay: true,
Copy the code

Ok, so we’ve combined WebPack with ESLint and WebPackDevServer.

Webpack performance optimization

How to improve packaging speed

On some large projects, we load so many resources that we have to speed up the packaging of the project.

  1. Keep up with technology iterations

We can upgrade the webpack version, node, NPM/YARN version, why should we upgrade these tools? Webpack will be optimized internally when it is updated, and since WebPack is based on Node, node will run more efficiently. NPM/YARN When we introduce packages, new code dependencies may be judged faster etc. So it’s essential that we keep up with the iterations of technology.

  1. As few modules as possible do not apply to loader

For example, when configuring ESLint, I will ignore node_modules, which means that when we encounter code in the node_modules folder, we will not detect it, so we will only consider our own code, which will be much more efficient, since third-party code is mostly compiled.

  1. Rational use of plug-ins

It’s better to use the one officially verified, because we can’t guarantee the stability of the performance of the third party, and it may affect our packaging efficiency.

  1. The resolve parameter is properly configured

In React, we usually end with JSX, but if we just use React, we can also use JS, so how do we not write the suffix and let it recognize automatically? We can use the resolve configuration item.

Added in webpack.config.js

resolve: {
    extensions: ['.js', '.jsx']
  },
Copy the code

So if he doesn’t find the JS file, he will automatically look for the JSX file. But we usually just configure some logical files.

In addition, we often import a folder, and it will automatically import files like index.js for us. How do we configure the name of the file we want to enter?

resolve: {
    extensions: ['.js', '.jsx'],
    mainFiles: ['index', 'child']
  },
Copy the code

But this is just a demonstration, so you don’t normally configure it this way.

There’s another alias setting that you can keep an eye on, and I’m sure you know how it works.

alias: {
      axin: path.resolve(__dirname,'')
    }
Copy the code
  1. Use the DLLPLUGIN to speed up packaging

Package the third party module only once to generate a vendor.js. If you use a third party module, go to vendor.js. Since the files of third-party modules don’t change very often, we generate a file the first time and save it. In this way, the later packaging will not be analyzed, which can save a lot of resources.

  1. Control package file size

  2. Thread -loader, Parallel -webpack,happypack multi-process packaging.

  3. Use sourceMap wisely (more detailed, slower packaging)

  4. Analyze the packaging results with STATS

  5. Development environment memory compilation (memory reads are much faster than hard drive reads)

  6. Remove useless plug-ins from the development environment

.

Multi-page packaging

Current mainstream frameworks, such as Vue and React, are single-page applications, while older websites, such as jquery and Zepto, involve multiple pages.

Start by creating two new page files. home.html,list.html

As mentioned earlier, the generated file uses a plugin for WebPack called html-webpack-plugin

So we just need to configure it in plugins.

New htmlPlugin({template: './home.html', filename: 'home.html', // generated filename chunks: New htmlPlugin({template: './list.html', filename: 'list.html',}),Copy the code

This completes multi-page packaging.