Logo Vincent
返回文章列表

一篇文章学会Webpack5.x

Web
一篇文章学会Webpack5.x

【前言】

Web前端构建离不开webpack,

众所周知webpack的配置很多很复杂,

甚至可以设置“webpack配置工程师”,

本文抓住webpack核心概念,

和业务开发中常用配置进行讲解,

争取一篇文章学会webpack使用和配置。

【常用文档】

webpack官网

webpack手册:可以按文档一步一步学习

webpack概念: webpack常用的概念

webpack配置: 查询webpack的配置项

【讲解模式】

由于要快速上手webpack,所以不和其他文章一样从概念讲起,

而是直接从实战代码讲起,实战代码: https://github.com/insistime/webpack-guides

可以直接clone到本地,

git clone git@github.com:insistime/webpack-guides.git ./webpack-guides

操作过程如下

1.checkout到对应的tag,例如0.0.4这个tag

git checkout 0.0.4

2.安装依赖,不同代码依赖不同

npm i

3.对照代码看讲解

4.自己练习

【安装】

webpack是构建工具,

所以安装的时候,做为devDependencies安装即可

npm i -D webpack webpack-cli

安装完后的效果

  "devDependencies": {
    "webpack": "^5.59.0",
    "webpack-cli": "^4.9.1"
  },

代码见: https://github.com/insistime/webpack-guides/tree/0.0.4

【entry和output】

entry:入口,可以配置单个或者多个入口

output:输出,配置输出的文件名,位置等

这里的例子,

entry为src文件夹下的index.js文件,

输出到dist文件夹下的main.js文件

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

代码见: https://github.com/insistime/webpack-guides/tree/0.0.4

【配置文件】

webpack使用一般都依赖webpack配置文件,

这里新建一个webpack.config.js文件,

内容如上entry和output示例

代码见: https://github.com/insistime/webpack-guides/tree/0.0.4

【构建脚本】

安装完webpack,准备好配置文件后如何构建呢,

需要在package.json内配置一个脚本,如下

  "scripts": {
    "build": "webpack --config webpack.config.js"
  },

然后执行

npm run build

效果如下

代码见: https://github.com/insistime/webpack-guides/tree/0.0.4

【测试效果】

这里手动创建一个html,测试效果,可以直接双击打开

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Getting Started</title>
  </head>
  <body>
    <script src="main.js"></script>
  </body>
</html>

打开后效果

代码见: https://github.com/insistime/webpack-guides/tree/0.0.4

【小结】

到这里,学习了

1.webpack-安装

2.webpack-配置文件

3.webpack-构建

4.webpack-entry

5.webpack-output

代码见: https://github.com/insistime/webpack-guides/tree/0.0.4

文件结构如下

【module】

webpack的理念是所有web前端开发过程中使用到的资源都是模块(module),

所以可以通过webpack的配置,

在web前端代码内加载和使用几乎任何资源,

例如这里,js内引入了css,png,xml等资源

import _ from 'lodash';
import './style.css';
import Icon from './icon.png';

import Data from './data.xml';
import Notes from './data.csv';

import toml from './data.toml';
import yaml from './data.yaml';
import json from './data.json5';

console.log(toml.title); // output `TOML Example`
console.log(toml.owner.name); // output `Tom Preston-Werner`

console.log(yaml.title); // output `YAML Example`
console.log(yaml.owner.name); // output `Tom Preston-Werner`

console.log(json.title); // output `JSON5 Example`
console.log(json.owner.name); // output `Tom Preston-Werner`

function component() {
  const element = document.createElement('div');

  // Lodash, now imported by this script
  element.innerHTML = _.join(['Hello', 'webpack'], ' ');
  element.classList.add('hello');

  // Add the image to our existing div.
  const myIcon = new Image();
  myIcon.src = Icon;

  element.appendChild(myIcon);

  console.log(Data);
  console.log(Notes);

  return element;
}

document.body.appendChild(component());

代码见: https://github.com/insistime/webpack-guides/tree/0.0.9

【loader】

而加载资源,大部分需要通过loader进行加载,

例如加载css文件需要style-loader和css-loader,

      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },

而loader都不是webpack内置的,

所以这里使用之前需要先安装对应的loader

npm i -D style-loader css-loader

这里只是一个开头,

后续你会发现使用webpack需要安装很多依赖

代码见: https://github.com/insistime/webpack-guides/tree/0.0.9

【asset】

webpack也发现了依赖多的这个问题,

将一些最常见的依赖内置到了webpack中,

在webpack5.x中,内置了一些loader,

例如之前的file-loader,url-loader,raw-loader,

在webpack5.x内对应:asset/resource,asset/inline,assets/source,

所以在webpack5.x下,图片和字体的配置方式如下

      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset/resource',
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource',
      },

代码见: https://github.com/insistime/webpack-guides/tree/0.0.9

【小结】

到这里,学习了

1.webpack-module

2.webpack-loader

3.webpack-asset

代码见: https://github.com/insistime/webpack-guides/tree/0.0.9

文件结构如下

【plugin】

在上述第一个小结内,html文件是手动生成的,

这个过程比较麻烦,

webpack的plugin机制很好的解决了这个问题,

这里要讲到的plugin:html-webpack-plugin,

没错,在使用之前,你依然需要安装它

npm i -D html-webpack-plugin

然后配置

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
    index: './src/index.js',
    print: './src/print.js',
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: 'Output Management',
    }),
  ],
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist'),
    clean: true,
  },
};

构建后,你会发现dist文件夹中自动生成了html文件,

这里简单对比一下loader和plugin

loader:为webpack加载资源的工具,

plugin:为拓展webpack能力的工具,

这些能力一般都是非核心能力

代码见: https://github.com/insistime/webpack-guides/tree/0.1.3

【再看entry和output】

你会发现上述的例子生成了两个js文件,

并且js文件名字也做了修改,

这里依赖entry的改动,如下

  entry: {
    index: './src/index.js',
    print: './src/print.js',
  },

和output的改动,如下

  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist'),
    clean: true,
  },

可以看到entry变为了两个入口,

output的filename使用了[name]代表原文件名,

output添加了clean属性,代码每次构建前清理dist文件夹

代码见: https://github.com/insistime/webpack-guides/tree/0.1.3

【小结】

到这里,学习了

1.webpack-plugin

2.webpack-entry,多个入口

3.webpack-output,[name]

4.webpack-output,clean

代码见: https://github.com/insistime/webpack-guides/tree/0.1.3

【mode】

上述代码构建虽然没什么问题,

但是总有一些提示,如下

这个提示也很明确,没有设置mode,

webpack的mode就是告诉webpack应该使用哪种模式,

比如development或者production,详见: https://webpack.js.org/configuration/mode/#mode-development

不同点大概是是否压缩,构建到内存还是构建到文件等

这里设置一个mode,如下

  mode: 'development',

再次构建,可以看到已经没有上述提示了

代码见: https://github.com/insistime/webpack-guides/tree/0.1.8

【watch】

webpack本身自带watch功能,不需要额外安装依赖,

添加watch脚本

"watch": "webpack --config webpack.config.js --watch"

执行watch脚本

修改src下的文件,发现webpack会自动重新构建

所以watch的能力是监听文件变动,并自动构建

代码见: https://github.com/insistime/webpack-guides/tree/0.1.8

【watch实践】

到这里会发现一个问题,之前打开html文件都是手动双击打开,

也就是预览html效果是通过file协议直接浏览器打开的,

而不是http服务器的模式打开,

实践中需要一个server跑起来html文件,

这里暂时使用pm2代替,

pm2的使用可以看这篇文章:一篇文章学会pm2

安装pm2

npm i -g pm2

运行html文件

cd dist
pm2 serve .

pm2会运行一个server,内容是dist文件夹下的内容

可以看到使用的8080端口,

这样本地可以通过8080端口访问了

到这里watch的实践如下

1.npm run watch

2.pm2运行dist文件夹

3.访问8080端口查看效果

4.修改src下文件

5.刷新页面看效果

代码见: https://github.com/insistime/webpack-guides/tree/0.1.8

【devServer】

那使用webpack,还需要配一个pm2吗,

其实,webpack已经为你提供了一个开发时使用的server了

安装依赖

npm i -D webpack-dev-server

添加配置

  devServer: {
    static: './dist',
  },

添加脚本

    "start": "webpack serve --open",

运行devServer

webpack-dev-server做了哪些事情呢

1.构建文件

2.启动一个server,运行dist下文件

3.打开浏览器

4.监听文件变化

相当于webpack-dev-server是watch+pm2的合集,

详见: https://www.npmjs.com/package/webpack-dev-server

到这里开发实践修改为

1.npm run start

2.访问8080查看效果

3.修改src下文件

4.刷新页面查看效果

代码见: https://github.com/insistime/webpack-guides/tree/0.1.8

【小结】

到这里,学习了

1.webpack-mode

2.webpack-watch

3.webpack-devServer

代码见: https://github.com/insistime/webpack-guides/tree/0.1.8

【code splitting】

如果有两个js文件都引入了一个公共的js库,例如lodash,

目前的代码构建后的效果如下

发现两个文件都很大,因为两个文件都包含了lodash这个js库

代码见: https://github.com/insistime/webpack-guides/tree/0.1.9

如何提取这个公共的js库呢,修改配置

  optimization: {
    splitChunks: {
      chunks: 'all',
    },
  },

再次执行,发现已经将lodash抽取出来了

代码见:  https://github.com/insistime/webpack-guides/tree/0.2.0

【小结】

到这里,学习了

1.webpack-code splitting

代码见:  https://github.com/insistime/webpack-guides/tree/0.2.0

【基础总结】

后续webpack还有一些概念,

比如caching,tree shaking,production等等,

但这些都是调优部分的能力,目前基础使用已经ok了,

在做下总结,学习了

1.webpack-安装

2.webpack-配置文件

3.webpack-构建

4.webpack-entry

5.webpack-output

6.webpack-module

7.webpack-loader

8.webpack-asset

9.webpack-plugin

10.webpack-mode

11.webpack-watch

12.webpack-devServer

13.webpack-code splitting

【react】

webpack基础学习完毕,后续基本两个方向

1.对生产环境的webpack配置进行优化

2.开发实践中使用webpack,比如react的项目如何使用webpack

这里准备一个简单的react代码,用来演示

const React = require('react');
const ReactDOM = require('react-dom');

ReactDOM.render(<h1>Helloo, world!</h1>, document.getElementById('root'));

安装依赖

-- react
npm i react react-dom

-- babel
npm i -D babel-loader @babel/core @babel/preset-react

修改配置

  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: { presets: ["@babel/preset-react"] }
      },
    ],
  },

构建成功

代码见: https://github.com/insistime/webpack-guides/tree/1.0.3

【sass】

除了react,一些css框架的使用也必不可少,

这里用sass为例,演示在webpack内如何配置,

代码多引入了一个scss文件,如下

安装依赖

npm i -D sass sass-loader css-loader style-loader

修改配置

      {
        test: /\.scss$/i,
        use: [
          "style-loader",
          "css-loader",
          "sass-loader",
        ],
      },

构建成功

代码见: https://github.com/insistime/webpack-guides/tree/1.0.4

【小结】

到这里,学习了

1.webpack-react配置

2.webpack-sass配置

【问题】

到这里,你会发现一个问题,

在开发实践中webpack依赖很多其他npm包,类似这样

  "devDependencies": {
    "@babel/core": "^7.17.5",
    "@babel/preset-react": "^7.16.7",
    "babel-loader": "^8.2.3",
    "css-loader": "^6.7.1",
    "html-webpack-plugin": "^5.5.0",
    "imports-loader": "^3.1.1",
    "sass": "^1.49.9",
    "sass-loader": "^12.6.0",
    "style-loader": "^3.3.1",
    "webpack": "^5.65.0",
    "webpack-cli": "^4.9.1",
    "webpack-dev-server": "^4.6.0",
    "webpack-merge": "^5.8.0"
  },

假设你在维护5个这样的项目,

那意味着有5份类似的依赖,

拿html-webpack-plugin这个依赖来说,

可能会存在5个项目内,

还要维护到最新版本,

确实比较痛苦

【qiao-webpack】

封装了一个npm包,欢迎使用, https://qiao-webpack.vincentqiao.com/#/

【总结】

1.webpack-安装

2.webpack-配置文件

3.webpack-构建

4.webpack-entry

5.webpack-output

6.webpack-module

7.webpack-loader

8.webpack-asset

9.webpack-plugin

10.webpack-mode

11.webpack-watch

12.webpack-devServer

13.webpack-code splitting

14.webpack-react配置

15.webpack-sass配置

16.webpack-开箱即用工具:qiao-webpack, https://qiao-webpack.vincentqiao.com/#/

17.webpack-手册和随笔专栏: https://blog.csdn.net/uikoo9/category_11471307.html

© 2026 vincentqiao.com . 保留所有权利。