1. Webpack introduction and related knowledge

Webpack – JavaScript application module packaging tool.

1.1 Core Concepts:

Webpack has four core concepts:

  • Entry

    Single entry — Single page application

    Multi-entry – Multi-page application

  • Output = output

    Path: Output path (must be an absolute path) path.resolve

    Filename: indicates the output filename

  • loaders

    Compile the file

  • Plugins

    Webpack feature extensions

1.2 Related knowledge (Node.js & ES6 modularization)

1.2.1 Node. Js

Node.js is the server version of javascript, and Webpack relies on Node.js to perform packaging and compression.

1.2.2 ES6 Modularization

1.2.2.1 export export

// Export one or more variables (functions)export let a = 1;
export const b = 2;
export function fn(){
    console.log('fn'} // Export an objectlet a = 1;
const b = 2;
function fn(){
    console.log('fn')}export{ a, b, fn }; // Export the default member -- only one can be exported, and this is the default imported memberexport default let a = 1;
Copy the code

1.2.2.2 import import

// Import all members (as -- rename imported values) import * as name from'xxx'; // Import default members import a from'xxx'; // Import only: import CSS or function import'xxx'; // Async importlet a =import("./util");
Copy the code

2. Start using Webpack — Build your project

2.1 Creating a Project

npm init
npm i webpack webpack-cli --save-dev
Copy the code

Initialize the project and install the Webpack dependencies so that you can run the Webpack command from the command line.

2.2 webpack configuration

Create and configure webpack.config.js

  • Single entry | single output

    Create a new one in the root directorysrcFolder, newindex.jsFile.

Index. Js file:

console.log('index')
Copy the code

Webpack. Config. Js file

const path = require('path')
module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'main.min.js'}}Copy the code
  • Multiple entry | multiple output

    Create a new one in the root directorysrcFolder, newindex.jshome.jsFile.

Index. Js file:

console.log('index')
Copy the code

Home. Js file:

console.log('home')
Copy the code

Webpack. Config. Js file

const path = require('path')
module.exports = {
  entry: {
    index: './src/index.js',
    home: './src/home.js',
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].min.js'//name is the name of the corresponding entry file}}Copy the code

2.3 Node Command Configuration

Configure the package.json file to verify the basic configuration

  • Modify thescriptProperties:
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"."build": "webpack"
},
Copy the code
  • runnpm run buildperformwebpackCommand to verify the input and output configurations.

    Generated in the root directorydistFolder, which has the corresponding file generation.

    Multiple entry

2.4 File Import

Importing a packed JS file in index. HTML Method 1: Manually Importing Create index. HTML and manually import the JS file.

<! DOCTYPE html> <html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

</body>
<script src='./dist/index.min.js'></script>
<script src='./dist/home.min.js'></script>
</html>
Copy the code

Open index.html, now that you have successfully imported compiled index.min.js and home.min.js, execute the code inside.

3. Plugins — Extend webpack functionality

Webpack is already available, but it is cumbersome to manually reference js files every time you change the code and recompile it, so let’s take a look at webpack plugins for ease of development.

3.1 Automatically generate HTML

The htML-webpack-plugin can generate new HTML files by the specified HTML template, and automatically introduce the required JS and other content.

1) Run NPM I html-webpack-plugin –save-dev to install dependencies.

2) Create the index.ejs file

<! DOCTYPE html> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
    <title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
</body>
</html>
Copy the code

3) Modify webpack.config.js configuration:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path')
module.exports = {
  entry: {
    index: './src/index.js',
    home: './src/home.js',
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].min.js'}, plugins: [new HtmlWebpackPlugin({// package output HTML title:'New HTML', // Generate HTML title minify: {// compress HTML file removeComments:true// collapseWhitespace in HTMLtrue// Delete whitespace and newline characters minifyCSS:true// compress inline CSS}, filename:'index.html'// The generated file name template:'index.ejs'// Generate HTML file from this template})]}Copy the code

4) Re-run the NPM run build to generate a new dist package, which will generate a new index.html file and automatically introduce the index.min.js file.

Automatically is introduced into


<! DOCTYPE html><html><head><meta http-equiv="Content-type" content="text/html; charset=utf-8"><title>New HTML</title></head><body><div id="root"></div><script type="text/javascript" src="index.min.js"></script><script type="text/javascript" src="home.min.js"></script></body></html>
Copy the code

3.2 Deleting Old Files

Delete the old files before packaging again

3.2.1 Changing the Configuration

Modify webpack.config.js to change the output index.html file name to something else, such as indexNew.html

image



npm run build
dist


image



index.html
clean-webpack-plugin
webpack.config.js
output.path

3.2.2 Installing Dependencies

Run NPM install clean-webpack-plugin –save-dev to install dependencies.

3.2.3 validation

Modify the webpack.config.js configuration.

image



npm run build
dist


image



indexNew.html

3.3 Automatically open the browser and support hot update

3.3.1 Installing Dependencies

npm i open-browser-webpack-plugin webpack-dev-server --save-dev

3.3.2 Changing the Configuration

Modify the webpack.config.js configuration as follows:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin')
const OpenBrowserPlugin = require('open-browser-webpack-plugin'// open browser const path = require('path')
module.exports = {
  entry: {
    index: './src/index.js',
    home: './src/home.js',
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].min.js'}, plugins: [new HtmlWebpackPlugin({// package output HTML title:'New HTML', // Generate HTML title minify: {// compress HTML file removeComments:true// collapseWhitespace in HTMLtrue// Delete whitespace and newline characters minifyCSS:true// compress inline CSS}, filename:'index.html'// The generated file name template:'index.ejs'// Generate HTML files from this template}), // By default, this plug-in will delete all files in the webpack output.path directory. new CleanWebpackPlugin(), new OpenBrowserPlugin({ url:'http://localhost:8080'}})]Copy the code

3.3.3 Changing the node command

Modify package.json to add start so that running NPM run start directly executes webpack-dev-server.

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"."start": "webpack-dev-server"."build": "webpack"
  },
Copy the code

We do the test

Execute NPM run start:

1) The browser will automatically open http://localhost:8080;

2) Modify the index.js file, save the file, and the browser will automatically refresh and update the content.

3.4 Code debug location — sourcemap

After compiling and packaging, the code is very different from the source code, which is not easy to debug.

Source-map solves this problem, generating.map files for easy error location debugging.

How to start: Add a configuration line to webpack.config.js: devtool: “source-map”

const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin')
const OpenBrowserPlugin = require('open-browser-webpack-plugin'// open browser const path = require('path')
module.exports = {
  entry: {
    index: './src/index.js',
    home: './src/home.js',
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].min.js'}, plugins: [new HtmlWebpackPlugin({// package output HTML title:'New HTML', // Generate HTML title minify: {// compress HTML file removeComments:true// collapseWhitespace in HTMLtrue// Delete whitespace and newline characters minifyCSS:true// compress inline CSS}, filename:'index.html'// The generated file name template:'index.ejs'// Generate HTML files from this template}), // By default, this plug-in will delete all files in the webpack output.path directory. new CleanWebpackPlugin(), new OpenBrowserPlugin({ url:'http://localhost:8080'})], // pre-compile file debugging devtool:"source-map"
}
Copy the code

As above, ok. It can be tested by printing or other means.

4. loader

Loader — File compilation.

4.1 ES6 & React compile — babel-loader

Babel is a JavaScript compiler that Webpack uses to compile ES6. Here we will create a React project, so we will also add the React dependency configuration.

4.1.1 Installation Dependencies

Yarn add Babel babel-core [email protected] babel-env babel-preset- preset-react note: Now install babel-core and babel-loader directly, the installed version of babel-core and babel-loader will not be the same, so I specified the version of babel-loader during the installation to avoid this problem.

4.1.2 Changing the Configuration

Modify webpack.config.js as follows:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin')
const OpenBrowserPlugin = require('open-browser-webpack-plugin'// open browser const path = require('path')
module.exports = {
  entry: {
    index: './src/index.js',
    home: './src/home.js',
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].min.js'}, plugins: [new HtmlWebpackPlugin({// package output HTML title:'New HTML', // Generate HTML title minify: {// compress HTML file removeComments:true// collapseWhitespace in HTMLtrue// Delete whitespace and newline characters minifyCSS:true// compress inline CSS}, filename:'index.html'// The generated file name template:'index.ejs'// Generate HTML files from this template}), // By default, this plug-in will delete all files in the webpack output.path directory. new CleanWebpackPlugin(), new OpenBrowserPlugin({ url:'http://localhost:8080' })
  ],
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/i,
        use: [{
          loader: "babel-loader",
          options: {
            presets: ["env"."react"],
          }
        }],
        exclude: /node_modules/
      }
    ]
  }
}
Copy the code

4.1.3 Modifying files

Change index.js and home.js files to react syntax home.js files

import React, { Component } from 'react';

export default class Home extends Component {

  render() {
    return (
      <div style={{backgroundColor: '#0f0'}}> home page </div> ); }}Copy the code

Index. Js file

import React from 'react';
import { render } from 'react-dom';
import Home from './home';

render(<Home/>, document.getElementById('root'));
Copy the code

At this point, the page looks like this:


image


As shown, the React syntax compiles successfully.

4.2 Handling CSS Files — style-loader & CSS-loader

4.2.1 Modifying files

Create the index.css file

.container {
    background-color: aquamarine
}
Copy the code

Modify the home.js file as follows:

import React, { Component } from "react";
import './index.css'

export default class Home extends Component {
  render() {
    return (
      <div className="container"> home page </div> ); }}Copy the code

NPM run start restarts the project.

image

4.2.2 Installing Dependencies

npm i style-loader css-loader --save-dev

4.2.3 Changing the Configuration

Modify the webpack.config.js configuration as follows:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin')
const OpenBrowserPlugin = require('open-browser-webpack-plugin'// open browser const path = require('path')
module.exports = {
  entry: {
    index: './src/index.js',
    home: './src/home.js',
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].min.js'}, plugins: [new HtmlWebpackPlugin({// package output HTML title:'New HTML', // Generate HTML title minify: {// compress HTML file removeComments:true// collapseWhitespace in HTMLtrue// Delete whitespace and newline characters minifyCSS:true// compress inline CSS}, filename:'index.html'// The generated file name template:'index.ejs'// Generate HTML files from this template}), // By default, this plug-in will delete all files in the webpack output.path directory. new CleanWebpackPlugin(), new OpenBrowserPlugin({ url:'http://localhost:8080' })
  ],
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/i,
        use: [{
          loader: "babel-loader",
          options: {
            presets: ["env"."react"],
          }
        }],
        exclude: /node_modules/
      },
      {
        test: /\.css$/ I, // Loader use: ['style-loader'.'css-loader'}]}}Copy the code

Added loader for.css files to process.css files.

image



Note:

  • Css-loader: reads and compiles CSS files imported from JS
  • Style-loader: create one in HTML<style></style>Tag, which contains the CSS style resolved by CSS-loader.
  • In webPack configuration, the style-loader must precede the CSS-loader and the sequence cannot be changed. That is, the STYle-loader must be processed by the CSS-loader before the style-loader.

4.3 Processing LESS Files — less-loader

4.3.1 Changing files

Create index.less file as follows:

.container {
    background-color: aquamarine
}
Copy the code

Modify the home.js file as follows:

import React, { Component } from "react";
import './index.less'

export default class Home extends Component {
  render() {
    return (
      <div className="container"> home page </div> ); }}Copy the code

4.3.2 Installing Dependencies

npm i less less-loader --save-dev

4.3.3 Changing the Configuration

Change webpack.config.js configuration, add less file parsing under module/rules:

{
    test: /\.less$/, // Loader use: ['style-loader'.'css-loader'.'less-loader']}Copy the code

4.3.4 validation

Restart the project, the less file takes effect, and the page looks like this:


image

4.4 Adding the Browser prefix postCSs-loader and autoprefixer

Autoprefixer determines which browser prefixes need to be added according to the usage of the browser. Postcss-loader adds browser prefixes according to the autoprefixer result.

4.4.1 Changing files

Modify the index.less file as follows:

.container {
    background-color: aquamarine;
    transform: rotate(0deg);
    transition-duration: 1000ms;
}
.container:hover {
    background-color: aquamarine;
    transform: rotate(360deg)
}
Copy the code

4.4.2 Installing Dependencies

npm i less postcss-loader autoprefixer --save-dev

4.4.3 Changing the Configuration

To modify the webpack.config.js configuration and add postCSS-loader resolution to CSS and less files, there are two ways:

1) Specify the configuration of postCSS-loader in modele/rules of webpack.config.js

{
    test: /\.css$/, // Loader use: ['style-loader'.'css-loader', {
        loader: 'postcss-loader',
        options: {
        plugins: [require('autoprefixer'}}]}, {test: / \. (less | CSS) $/, / / for less suffix file Settings loader use: ['style-loader'.'css-loader'.'less-loader', {
      loader: 'postcss-loader',
      options: {
        plugins: [require('autoprefixer')]]}}}Copy the code

2) Modify webpack.config.js and create postcss.config.js separately to modify the webpack.config.js file and add the following configuration to modele/rules:

{
    test: /\.css$/, // Loader use: ['style-loader'.'css-loader'.'postcss-loader'] {},test: / \. (less | CSS) $/, / / for less suffix file Settings loader use: ['style-loader'.'css-loader'.'less-loader'.'postcss-loader']}Copy the code

Postcss. Config. Js file

module.exports = {
    plugins: [require('autoprefixer')]}Copy the code

I prefer the first option to avoid creating too many configuration files and causing confusion.

4.4.4 validation

Restart the project and view the browser element. The style prefix has been added successfully.

image



Note:

1) Add the.broserslistrc file for configuration

Last 3 version // Support the last three versions of each version >2% // more than 2% of usersCopy the code

2) Add properties to package.json file for configuration without creating a new file

  "browserslist": [
    "last 5 version"."1%" >
  ]
Copy the code

The result is as follows:


image


Re-prefix our CSS styles according to the set rules.

4.5 Processing images — file-loader & url-loader

4.5.1 Introducing images

Create an images folder under SRC and add bg.png images

image


Modify the index.less file as follows:

.container {
    width: 100%;
    height: 600px;
    background: url('./images/bg.png');
    background-size: 100%;
    background-repeat: no-repeat;
}
Copy the code

If the project is restarted, the following error will be reported:

image

4.5.2 Installing Dependencies — file-loader

You need to configure the corresponding Loader to parse images.

Run NPM I file-loader –save-dev to install dependencies.

4.5.3 Changing the Configuration — file-loader

Change the webpack.config.js configuration and add the following configuration under modole/rule:

{
    test: / \. (PNG | JPG jpeg | | GIF) $/, / / for PNG |. JPG |. Jpeg |. GIF suffix set image loader use: [{loader:'file-loader',
      options: {
        outputPath: 'imgs/', // Relative to output.path output directory}}]}Copy the code

If the project is restarted, the image is successfully introduced, and the effect is as follows:

image

File-loader can parse the imported images in a project, output the images to the corresponding path according to the configuration, and modify the reference path in the packaged file to point to the packaged file.

4.5.4 Installing Dependencies — url-loader

For image references, url-loader encapsulates file-loader. If the limit attribute is added, if the file size is larger than the limit value, file-loader will be called to process the file. If the file size is smaller than the limit value, the file will be converted to Base64 to reduce the number of file requests. Install urL-loader dependencies

npm i url-loader --save-dev

4.5.5 Changing the Configuration — url-loader

Change the webpack.config.js configuration and add the following configuration under modole/rule:

{
        test: / \. (PNG | JPG jpeg | | GIF) $/, / / for PNG |. JPG |. Jpeg |. GIF suffix set image loader use: [{loader:'url-loader',
          options: {
            outputPath: 'imgs/'// The output directory relative to output.pathlimit: 8*1024 // If the value is greater than this value, the file is processed by file-loader and packaged into IMGS. If the value is less than this value, the file is converted to Base64 to reduce file request times}}]}Copy the code

Restart the project, the image is referenced successfully, execute NPM run build, and it can be found that the image larger than 8K will be packaged into the folder dist/ IMGS, and the image smaller than 8K will not be packaged output, but converted to Base64.

image

4.6 Processing text — file-loader & url-loader

4.6.1 Introducing fonts

< font style = “box-sizing: border-box; color: RGB (50, 50, 50); line-height: 20px; font-size: 14px! Important; word-break: normal; word-break: normal;”

image

@font-face{
    font-family: "digital";
    src: url(./digital-7.ttf);
}
.container {
    width: 100%;
    height: 600px;
    background: url('./images/bgimg.jpg');
    background-size: 100%;
    background-repeat: no-repeat;
    font-family: "digital"
}
Copy the code

After saving the project to compile, the following error will be reported:

image

4.6.2 Changing the Configuration

The same as the image, you need to configure the corresponding URL-loader to unpack the text, modify the webpack.config.js configuration, add the following configuration under modole/rule:

{
    test: / \. (eot | SVG | the vera.ttf | woff | woff2) $/, / / for eot | SVG | the vera.ttf | woff | woff2 suffix font loader use: [{loader:'url-loader',
        options: {
        outputPath: 'fonts/'// The output directory relative to output.pathlimit: 4*1024 // If the value is greater than this, file-loader will still handle it and package it into fonts. If the value is smaller than this, it will be base64 to reduce file request times}}]}Copy the code

Restart the project and the font is referenced successfully with the following effect:

image


You can test whether the limit setting is valid by changing the limit value and repackaging it.

5. Development/production model

5.1 Differences in development/production modes

  • Development mode requires debugging and automatically opens the browser, while production mode does not
  • In production mode, the package directory needs to be set and compression needs to be enabled. Ignore errors.

This distinction requires two Settings.

5.1.1 setting process. The env. NODE_ENV

In webpack.config.js, you can do different configurations by determining the value of env

Modify package.json to set process.env.node_env:

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"."start": "webpack-dev-server --env.development"."build": "webpack --env.production"."eslint": "eslint --init"
  },
Copy the code

Root directory new config folder, and in the following new webpack. Production. The config and webpack. Development. The config file.

Webpack. Config. Js file

const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin')
const OpenBrowserPlugin = require('open-browser-webpack-plugin'// open browser const path = require('path')

module.exports = function(env, argv) {
  console.log('env', env)
  env = env || { development: true }

  return {
    entry: {
      index: './src/index.js',
    },
    module: {
      rules: [
        {
          test: /\.(js|jsx)$/i,
          use: [{
            loader: "babel-loader",
            options: {
              presets: ["env"."react"],
            }
          }],
          exclude: /node_modules/
        },
        {
          test: /\.css$/ I, // Loader use: ['style-loader'.'css-loader', {
            loader: 'postcss-loader',
            options: {
              plugins: [require('autoprefixer'}}]}, {test: / \. (less | CSS) $/, / / for less suffix file Settings loader use: ['style-loader'.'css-loader'.'less-loader', {
            loader: 'postcss-loader',
            options: {
              plugins: [require('autoprefixer'}}]}, {test: / \. (PNG | JPG jpeg | | GIF) $/, / / for PNG |. JPG |. Jpeg |. GIF suffix set image loader use: [{loader:'url-loader',
            options: {
              outputPath: 'imgs/'// The output directory relative to output.pathlimit: 8*1024 // If the value is greater than this value, the file is processed by file-loader and packaged into IMGS. If the value is less than this value, the file is converted to Base64 to reduce the number of file requests}}]}, {test: / \. (eot | SVG | the vera.ttf | woff | woff2) $/, / / for eot | SVG | the vera.ttf | woff | woff2 suffix font loader use: [{loader:'url-loader',
            options: {
              outputPath: 'fonts/'// The output directory relative to output.pathlimit: 4*1024 // If the value is greater than this, file-loader will still handle it and package it into fonts. If the value is smaller than this, it will be base64 to reduce the number of file requests. env.production ? require('./config/webpack.production.config') : require('./config/webpack.development.config')}}Copy the code

5.1.2 Set webpack mode to determine the optimization level of Webpack.

Mode There are three modes:

  • None: no optimization
  • Development: Outputs debugging information
  • Production: Maximum optimization, compression enabled, error ignored

Webpack. Production. The config file

const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin')
const OpenBrowserPlugin = require('open-browser-webpack-plugin'// open browser const path = require('path')
module.exports = {
    mode: 'production',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'main.min.js'}, plugins: [new HtmlWebpackPlugin({// package output HTML title:'New HTML'Minify: {// Compress the HTML file removeComments:true// collapseWhitespace in HTMLtrue// Delete whitespace and newline characters minifyCSS:true// compress inline CSS}, filename:'index.html'// The generated file name template:'index.ejs'// Generate HTML files from this template}), // By default, this plug-in will delete all files in the webpack output.path directory. new CleanWebpackPlugin() ] }Copy the code

Webpack. Development. The config file

const HtmlWebpackPlugin = require('html-webpack-plugin');
const OpenBrowserPlugin = require('open-browser-webpack-plugin'// open browser const path = require('path')
module.exports = {
    mode: 'development',
    output: {
      filename: 'main.js'//name is the name of the corresponding entry file}, // pre-compile file debugging devtool:"source-map", plugins: [new HtmlWebpackPlugin({// package output HTML title:'New HTML', // Generate HTML title minify: {// compress HTML file removeComments:true// collapseWhitespace in HTMLtrue// Delete whitespace and newline characters minifyCSS:true// compress inline CSS}, filename:'index.html'// The generated file name template:'index.ejs'}), new OpenBrowserPlugin({url:'http://localhost:8080'}})],Copy the code


At the end of eggs

Welcome to pay attention to my public number – the front of the stage, instant access to more front-end technology, but also to get the front end of a large group of many well-known Internet friends, front-end technology update too fast, can not be out of date, common learning, common progress!