Webpack 笔记

一、前端工程化

  • 模块化(js 的模块化、Css 的模块化、资源的模块化)
  • 组件化(复用现有的 UI 结构、样式、行为)
  • 规范化(目录结构的划分、编码规范化、接口规范化、文档规范化、Git 分支管理)
  • 自动化(自动化构建、自动部署、自动化测试)

二、webpack 基本使用

​ webpack 是前端项目工程化的具体解决方案。

​ 主要功能:它提供了友好的前端模块化开发支持,以及代码压缩混淆、处理浏览器端 JavaScript 的兼容性、性能优化等强大的功能。

安装:(记得先初始化 node.js 项目)

npm install webpack@5.42.1 webpack-cli@4.9.0 -D

配置

​ 在项目根目录中,创建名为 webpack.config.js 的 webpack 配置文件,并初始化如下的基本配置:

module.exports = {
    mode: 'development'		// 也可以选择 production,此时体积小,有压缩混淆,且有性能优化
}

​ 在 package.json 的 scripts 节点下,增加脚本:

"script": {
    "dev": "webpack"	// 通过 npm run dev 即可执行命令
}

使用

# 运行以下命令进行打包构建:
npm run dev

三、自定义打包入口和出口

​ 注:在 webpack 4.x 和 5.x 的版本中,有如下的默认约定:

  • 默认的打包入口文件为 src -> index.js
  • 默认的输出文件路径为 dist -> main.js

​ 也可以通过配置来修改。

​ 在 webpack.config.js 配置文件中,通过 entry 节点指定打包的入口。通过 output 节点指定打包的出口。如:

const path = require('path')
module.exports = {
    entry: path.join(__dirname, './src/index.js'),	// 打包入口
    output: {
        path: path.join(__dirname, './dist'),	    // 出口
        filename: 'bundle.js'		// 输出文件名称
    }
    devtool: 'inline-source-map'
}

四、webpack 插件

1、webpack-dev-server 插件

​ 安装 webpack-dev-server,可自动打包代码。

npm install webpack-dev-server@3.11.2 -D

​ 然后更改在 package.json 的 scripts 节点:

"script": {
    "dev": "webpack serve"	// 通过 npm run dev 即可执行命令
}

​ 但是注意:编译后的 js 文件是不会在本地的,而是在内存中,但可以通过 dev-server 提供的路径访问到。(默认路径是项目的根目录)

2、html-webpack-plugin 插件

​ html-webpack-plugin 是 webpack 中的 HTML 插件,可以通过此插件自定制 index.html 页面的内容。(实现 html 文件复制到根目录下,方便访问)

npm install html-webpack-plugin@5.1.0 -D

​ 配置 webpack.config.js :

// 导入 html 插件,得到一个构造函数
const HtmlPlugin = require('html-webpack-plugin')

const htmlPlugin = new HtmlPlugin({
    template: './src/index.html',	// 指定原文件存放路径
    filename: './index.html'		// 指定生成文件存放路径
})

module.exports = {
    ...
    plugins: [htmlPlugin]	// 通过该节点,挂载 htmlPlugin 插件
}

​ 注:

  • 通过该插件复制到项目根目录中的 index.html,也被放到了内存中
  • 该插件在生成的 index.html 页面的底部,自动注入了打包的 js 文件

3、devServer 节点

​ 在 webpack.config.js 配置文件中,可以通过 devServer 节点对 webpack-dev-server 插件进行更多的配置,如:

devServer: {
    open: true,		// 初次打包完成后自动打开浏览器
    host: '127.0.0.1',
   	port: 80,
}

五、webpack 中的 loader

​ 在实际开发过程中,webpack 默认只能打包处理以 .js 后缀名结尾的模块。其他非 .js 后缀名结尾的模块,webpack 默认处理不了,需要调用 loader 加载器才可以正常打包,否则会报错!

​ loader加载器的作用:协助 webpack 打包处理特定的文件模块。比如:

  • css-loader 可以打包处理 .css 相关的文件
  • less-loader可以打包处理 .less 相关的文件
  • babel-loader 可以打包处理 webpack 无法处理的高级 JS 语法

image-20220513190139737

1、打包处理 css 文件

安装

npm i style-loader@2.0.0 css-loader@5.0.1 -D

配置:(在 webpack.config.js 的 module->rules 数组中,添加 loader 规则如下)

module: {	// 所有第三方模块的配置规则
    rules: [	// 匹配规则
        { test: /\.css$/, use:['style-loader', 'css-loader']}
    ]
}

​ 注:其中,test 表示匹配的文件类型,use 表示对应要调用的 loader。

使用:(在 js 中 import 对应的 css 即可)

import './css/index.css'

2、打包处理 less 文件

安装

npm i less-loader@7.1.0 less@3.12.2 -D

配置:(在 webpack.config.js 的 module->rules 数组中,添加 loader 规则如下)

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

​ 注:其中,test 表示匹配的文件类型,use 表示对应要调用的 loader。

3、打包处理样式表中与 url 路径相关的文件

安装

npm i url-loader@4.1.1 file-loader@6.2.0 -D

​ 配置:(在 webpack.config.js 的 module->rules 数组中,添加 loader 规则如下)

module: {
    rules: [
        { test: /\.jpg|jpeg|png|gif$/, use: 'url-loader?limit=22229'}
    ]
}

参数 limit 含义: 图片大小 <= 22229 bytes,则转化为 base64 直接内嵌。

​ 参数配置也可以采用以下的写法:

module: {
    rules: [
        {
		test: /\.jpg|jpeg|png|gif$/,
		use: { loader: 'url-loader', options: { limit: 22229 } }
        },
    ]
}

4、打包处理 js 文件中的高级语法

​ webpack 只能打包处理一部分高级的 JavaScript 语法。对于那些 webpack 无法处理的高级 js 语法,需要借助于 babel-loader 进行打包处理。例如 webpack 无法处理下面的 JavaScript 代码:

class Person {
    static info = 'person info'
}
console.log(Person.info)

​ 因此需要安装下面这些包:

npm i babel-loader@8.2.1 @babel/core@7.12.3 @babel/plugin-proposal-class-properties@7.12.1 -D

​ 添加规则:

{
    test: /\.js$/,
    // exclude 为排除项,表示只需要处理开发者编写的 js 文件,不需要处理 node_modules 中的
    exclude: /node_modules/,
    use: {
        loader: 'babel-loader',
        options: {
            // 声明一个 babel 插件,用来转化
            plugins: ['@babel/plugin-proposal-class-properties'],
        }
    }
}

六、打包发布

配置:(在package.json文件的scripts节点下,新增build命令如下:)

"script": {
    ...
    "build": "webpack --mode production"
}

​ 运行命令 npm run build 即可,完成在 dist 文件夹。

1、指定 js 文件和图片文件生成到目录

output: {
    path: path.join(__dirname, 'dist'),
    // 明确存放到 dist/js 中
    filename: 'js/bundle.js',
}
{
    test: /\.jpg|jpeg|png|gif$/,
    use: {
        loader: 'url-loader',
        options: {
            limit: 22228,
            outputPath: 'image',
        }
    }
}

2、自动清理 dist 目录

​ 安装:

npm install clean-webpack-plugin@3.0.0 -D

​ 配置:

// 2.按需导入插件、得到插件的构造函数之后,创建插件的实例对象
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const cleanPlugin = new CleanWebpackPlugin()

//3.把创建的cleanPlughn 插件实例对象,挂载到plugins节点中
plugins: [htmlPlugin,cleanPlugin],//挂载插件

七、Source Map

​ Source Map 就是一个信息文件,里面储存着位置信息。也就是说,Source Map 文件中存储着代码压缩混淆前后的对应关系。在开发环境下,webpack 默认启用了 Source Map 功能。当程序运行出错时,可以直接在控制台提示错误行的位置,并定位到具体的源代码。

​ 但是:开发环境下默认生成的 Source Map ,记录的是生成后的代码的位置。会导致运行时报错的行数与源代码的行数不一致的问题。示意图如下:

image-20220513223701339

解决方案:添加以下配置即可。

module.exports = {
    mode: 'development',
    // eval-source-map 仅限在“开发模式”下使用,不建议在“生产模式”下使用。
    // 此选项生成的 Source Map 能够保证“运行时报错的行数”与“源代码的行数”保持一致
    devtool: 'eval-source-map'
    ...
}

​ 在生产环境下,如果只想定位报错的具体行数,且不想暴露源码。此时可以将 devtool 的值设置为 nosources-source-map。实际效果如图所示:

image-20220513225029547


八、注意

​ 实际应用中我们不会直接自己从零书写 webpack 配置,可以使用一些现成的 CLI 工具。但我们需要了解这些配置的作用。

Q.E.D.


f"{言语过于单薄,于此引用心声}"