webpack入门

webpack是一个用于现代JavaScript应用程序的静态模块打包工具。本文通过一系列的代码实践(非常详细!)来学习webpack的概念、基本配置、如何使用loaderplugin

webpack能做什么

这里有一张来自官方文档首页的图,来描述Webpack的核心功能:

What Webpack do

实际上,webpack能做的事有很多:

  • 构建build:将一个或多个JS/CSS文件打包成对应的文件。

  • 转译代码:将高版本的JS转译成低版本的JS以兼容。

  • 代码压缩

  • 代码分析

webpack的一些概念

  • 入口(entry)
    入口起点(entry point)指示webpack应该使用哪个模块,来作为构建其内部依赖图的开始。
    // webpack.config.js
    module.exports = {
    entry: './path/to/my/entry/file.js',
    };
  • 输出(output)
    output属性表示在哪输出webpack创建的bundle(即打包好后的静态资源)。主要输出文件的默认值是./dist/main.js,其他生成文件默认放在./dist中。
    // webpack.config.js
    const path = require('path');

    module.exports = {
    entry: './path/to/my/entry/file.js',
    output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js',
    },
    };
  • loader
    webpack只能理解JavaScript和JSON文件,loader让webpack能够去处理其他类型的文件,并且将他们转为有效模块供程序使用,以及添加到依赖图中。
    webpack的一个强大特性是支持通过import导入任何类型的模块。
    loader有两个属性:
    • test:哪些文件会被转换,这里传一个正则表达式
    • use:在转换时,应该用哪个loader
  • plugin
    loader用于转换某些类型的模块,而插件可以做的事更多,包括:打包优化,资源管理,注入环境变量。
    想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。
  • 模式(mode)
    通过配置mode属性可以启用webpack在不同环境下的优化(内置的)。可以配置为development, productionnone,默认是production

动手实践webpack

安装

  1. 创建一个项目:
    cd webpack-demo/
    yarn init
  2. 本地安装webpack:
    npm install webpack --save-dev
    npm install webpack-cli --save-dev
    或者
    yarn add webpack --dev
    yarn add webpack-cli --dev
    注:不推荐全局安装webpack ,这样会使你项目中的webpack锁定到指定版本,在使用不同的webpack版本的项目中可能会导致构建失败。

安装完成之后控制台会输出webpack的版本。本文写作时安装的版本是webpack@5.58.1webpack-cli@4.9.0

使用webpack

第一行代码

创建src/index.js文件:

// src/index.js
console.log('hi')

使用命令:npx webpack运行webpack,可以看到在根目录下出现了一个dist文件夹,里面有一个main.js

// dist/main.js
console.log("hi");

使用复杂一些的语法

尝试在index.js中添加复杂一些的代码:
创建src/greeting.js

// src/greeing.js
export default 'hello webpack'
// src/index.js
import greeting from './greeting'
console.log(greeting)

运行npx webpack,发现main.js的内容变成了:

(()=>{"use strict";console.log("hello webpack")})();

我们可以得出,webpack帮我们把两个有依赖关系的JavaScript文件里的代码打包到一起了,并且添加了"use strict",添加了立即执行函数。

webpack会分析我们的代码,把模块化的代码打包到一起,并且把它们变成兼容低版本浏览器的代码。webpack还支持其他模块语法。

注意webpack不会去修改importexport以外的部分,如果其他ES2015新特性想要兼容低版本浏览器,需要使用Babel等转译器。

配置webpack

webpack提供了许多配置项。
根目录下创建webpack.config.js

// webpack.config.js
const path = require('path');

module.exports = {
// 模式
mode: 'development',
// 入口
entry: './src/index.js',
// 输出
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
}
};

使用配置文件构建:

npx webpack --config webpack.config.js

缓存文件

HTTP缓存的意义

访问一个网站时,我们可能会去请求许多文件,每次请求都需要获取到这些文件。如果其中有一些文件没有改动,那么我们没有必要每次都重新请求这些文件。如果我们能将这些文件缓存下来,那么下次请求的时候可以直接从本地读取,这样可以加快访问速度,节省流量。
如果要更新缓存,修改返回的文件名就可以了。

webpack更新缓存

通过配置webpack,我们可以做到文件内容更新后,自动改变文件名,从而实现更新缓存的效果。

// webpack.config.js
// 此处省略其他配置项
// 配置文件hash
output: {
// filename: 'main.js',
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist')
},

这样配置之后,每次构建时,如果src/index.js有变动,会生成一个新的js文件放在dist目录下,且不会覆盖之前的文件。

使用webpack插件

这里我们使用HtmlWebpackPlugin来自动生成HTML,同时可以看看webpack插件是怎么用的。

  1. 安装
    yarn add html-webpack-plugin --dev
  2. 配置
    // webpack.config.js
    // 此处省略其他配置
    plugins: [new HtmlWebpackPlugin({
    title: 'My App',
    template: './assets/test.html'
    })]
    这样配置之后,webpack会使用assets/test.html作为模板生成html文件,并且会自动将生成的bundle注入到此文件中。还会用title的值替换模板中的<%=htmlWebpackPlugin.options.title %>

使用webpack loader

还记得我们说过webpack的一个强大特性是支持导入任何类型的模块吗?这里我们试着让webpack能像导入js模块一样导入CSS文件。
我们需要使用到css-loader

  1. 安装
    yarn add css-loader --dev
    yarn add style-loader --dev
  2. 配置
    // webpack.config.js
    module.exports = {
    module: {
    rules: [
    {
    test: /\.css$/i,
    use: ["style-loader","css-loader"],
    },
    ],
    },
    };
    这里配置的意思是:

“嘿,webpack 编译器,当你碰到「在 require()/import 语句中被解析为 ‘.css’ 的路径」时,在你对它打包之前,先 use(使用) css-loader 转换一下。”

这里css-loader的作用是读取CSS字符串到内存中;style-loader的作用是创建一个style标签,把CSS字符串放到标签里然后插入DOM。
配置完成之后,我们在assests/下创建test.css,然后在src/index.js中引入它:import '../assets/test.css'
build之后,我们在bundle中可以搜索到我们写的CSS规则。打开浏览器开发者工具,我们可以在<head>中找到被style-loader添加的style标签。

注:官方文档推荐production模式下,将CSS文件抽离出来,而不是存储在JS模块中。这种方式需要使用到 mini-css-extract-plugin

其他工具

跟webpack类似的工具有这些:

  • Rollup:比webpack的打包体积更小,但生态不够丰富,适合库的开发。
  • Parcel:比webpack配置简单,功能也要少一些,适合demo学习。
  • Vite:新一代构建工具。它使用原生 ESM 文件,无需打包。

参考

Webpack 4 中文文档
Github - html-webpack-plugin

Author: kpt

Permalink: http://kpt.ink/2021/10/12/webpack-basic/

文章默认使用 CC BY-NC-SA 4.0 协议进行许可,使用时请注意遵守协议。