Webpack初识 | 青训营笔记
这是我参与「第四届青训营 」笔记创作活动的的第11天。
为什么要学习Webpack
- 理解前端‘工程化’概念、目标、工具
- 一个团队总要有那么几个人熟悉Webpack,某种程度上可以成为个人的核心竞争力
- 高阶前端必经之路
什么是Webpack
前端项目是由资源构建起来的,虽然我们可以手动管理这些资源,但是当我们钓的资源很多的时候,会导致页面复杂繁琐,对开发效率有很大的影响。Webpack等工程化工具出现才解决了上述问题,从而有了前端工程化这个概念。
本质上,webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具(module bundler) 。
当 webpack 处理应用程序时,它会在内部构建一个 依赖图(dependency graph),此依赖图对应映射到项目所需的每个模块,并生成一个或多个 bundle。
Webpack核心思想:一切皆模块
如上图所示,webpack将所有的依赖文件视为模块(依赖可以理解为你的项目中所需要的东西),webpack通过对这些模块的分析,完成转换、压缩、合成、混淆等操作,将所有的项目文件打包成最原始的静态资源。
Webpack用法
- 安装:
npm i -D webpack webpack-cli - 编辑配置文件:在webpack.config.js中配置
- 执行编译命令:
npx webpack
关于Webpack的用法,基本围绕 ‘配置’ 展开,而这些配置大致可划分为两类:
- 流程类:作用于流程中某个 or 若干个环节,直接影响打包效果的配置项
- 工具类:主流程之外,提供更多工程化能力的配置项。
Webpack打包核心流程
Webpack打包的最简化核心流程分为以下四步:
- 入口处理
- 依赖解析
- 资源解析
- 资源合并打包
- 入口处理:从‘entry’文件开始,启动编译流程
- 依赖解析:从‘entry’文件开始,根据‘require’ or ‘import’ 等语句找到依赖资源
- 递归调用2、3,直到所有资源处理完毕
- 资源解析:根据 ‘module’配置,调用资源转移器,将png、css等非标准js资源转译为js内容
- 资源合并打包:将转译后的资源内容合并打包为可直接在游览器运行的js文件
配置总览
webpack有五个模块 :
- 入口(entry) -----设置入口文件路径
- 输出(output) -----设置打包后的文件存放路径以及文件名
- loader加载器(module) -----一般用于css文件的打包
- 插件(plugin) -----可以设置一个html模板插件
- 模式(mode) -----设置打包模式(一般在开发阶段使用webpack,一般不在产品阶段打包)
按使用频率:
- entry/output
- module/plugins
- mode
- watch/devServer/devtool
入口(entry)
入口起点(entry point) 指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
这里的依赖可以理解为入口文件里面require() / import 的文件
webpack.config.js
module.exports = {
entry: './path/to/my/entry/file.js'
};
出口(output)
output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,主要输出文件的默认值是 ./dist/main.js,其他生成文件默认放置在 ./dist 文件夹中。
基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。可以通过在配置中指定一个 output 字段,来配置这些处理过程:
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 能够去处理那些非 JavaScript 文件。
loader可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后就可以利用 webpack 的打包能力,对它们进行处理。
本质上,webpack loader将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。
举个栗子:解析css文件
首先安装 style-loader 和 css-loader,并在 module 配置 中添加这些 loader:
npm install style-loader css-loader
webpack.config.js
const commonConfig = {
module: {
rules: [
{
test: /.css$/,
use: ['style-loader', 'css-loader']
}
]
}
}
这里的test属性是正则表达式,匹配出use数组里loader需要处理的文件。
use数组表示需要使用的loader,同时在执行loader的时候,会按照use数组的顺序,逆序链式执行(从后往前) 。第一个 loader 将其结果(被转换后的资源)传递给下一个 loader,依此类推。最后,webpack 期望链中的最后的 loader 返回 JavaScript。
插件(plugins)
loader被用于转换某些类型的模块,而plugins则可以用于执行范围更广的任务。
插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。
想要使用一个插件,只需要 require() 它,然后把它添加到 plugins 数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例。
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
const webpack = require('webpack'); // 用于访问内置插件
const config = {
module: {
rules: [
{ test: /.txt$/, use: 'raw-loader' }
]
},
plugins: [
new HtmlWebpackPlugin({template: './src/index.html'})
]
};
module.exports = config;
loader和plugin的区别
- loader是一个转换器,将a文件进行编译输出b文件,这里是操作文件。单纯的文件转换。
- plugin是一个扩展器,用于扩展webpack的功能,让webpack具有更多的灵活性。在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。
模式(mode)
通过选择 development 或 production 或 none 之中的一个,来设置 mode 参数,可以启用相应模式下的 webpack 内置的优化,其默认值为 production。
module.exports = {
mode: 'production'
};
如何学习Webpack
官网:Loaders | webpack 中文文档 (docschina.org)
知识体系导航图:Webpack 5 知识体系 - GitMind
参考博客:
- 链接:juejin.cn/post/713063…,作者:haloerkay
- 链接:juejin.cn/post/713007…,作者:SSRRFF