学习笔记:吴浩麟–深入浅出 Webpack:第一章 入门
第一章 入门
1-1前端的发展
模块化 | 新框架 | 新语言 |
---|---|---|
CommonJS | React | ES6 |
AMD | Vue | TypeScript |
ES6 模块化 | Angular2 | FLow |
样式文件中的模块化 | SCSS |
1-2常见的构建工具及对比
构建其实是工程化、自动化思想在前端开发中的体现,把一系列流程用代码去实现,让代码自动化地执行这一系列复杂的流程
- 代码转换:
TypeScript
编译成JavaScript
、SCSS
编译成CSS
等。 - 文件优化:压缩
JavaScript
、CSS
、HTML
代码,压缩合并图片等。 - 代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载。
- 模块合并:在采用模块化的项目里会有很多个模块和文件,需要构建功能把模块分类合并成一个文件。
- 自动刷新:监听本地源代码的变化,自动重新构建、刷新浏览器。
- 代码校验:在代码被提交到仓库前需要校验代码是否符合规范,以及单元测试是否通过。
- 自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。
构建工具:
Npm Script
、Grunt
、Gulp
、Fis3
、Webpack
、Rollup
1-3代码示例
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="app"></div>
<script src="./dist/bundle.js></script>
</body>
</html>
main.css
#app {
text-align: center;
}
mian.js
const show = require('./show')
show('Webpack')
show.js
function show(content) {
window.document.getElementById('app').innerText = 'Hello, ' + content
}
module.exports = show
1-3安装与使用
代码示例
index.html
、show.js
见1-3
mian.js
// 通过CommonJS规范导入show函数
const show = require('./show')
// 执行show函数
show('Webpack')
package.json
{
"name": "webpack-1-3",
"version": "1.0.0",
"scripts": {
"build": "webpack"
},
"dependencies": {},
"devDependencies": {
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1"
}
}
webpack.config.js
const path = require('path')
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist')
}
}
1-4使用Loader
说明
Loader
可以看作具有文件转换功能的翻译员,配置里的 module.rules
数组配置了一组规则,告诉 Webpack
在遇到哪些文件时使用哪些 Loader
去加载和转换。 如上配置告诉 Webpack
在遇到以 .css
结尾的文件时先使用 css-loader
读取 CSS
文件,再交给 style-loader
把 CSS
内容注入到 JavaScript
里。 在配置 Loader
时需要注意的是:
use
属性的值需要是一个由Loader
名称组成的数组,Loader
的执行顺序是由后到前的;- 每一个
Loader
都可以通过URL
querystring
的方式传入参数,例如css-loader?minimize
中的minimize
告诉css-loader
要开启CSS
压缩。
它的工作原理大概是把 CSS
内容用 JavaScript
里的字符串存储起来, 在网页执行 JavaScript 时通过 DOM
操作动态地往 HTML head
标签里插入 HTML style
标签。
代码示例
index.html
、main.css
、mian.js
、show.js
见1-3
package.json
{
"name": "webpack-1-3",
"version": "1.0.0",
"scripts": {
"build": "webpack"
},
"dependencies": {},
"devDependencies": {
"css-loader": "^6.7.3",
"style-loader": "^3.3.1",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1"
}
}
webpack.config.js
const path = require('path')
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist')
},
module: {
rules: [{
// 用正则去匹配要用该loader转换的CSS文件
test: /\.css$/,
// 执行顺序由后到前
use: ['style-loader',
{
loader: 'css-loader',
// minimize属性已经弃用
options: {
// minimize: true
}
}]
}]
}
}
1-5使用PLugin
说明
运行命令:
npm i -D extract-text-webpack-plugin
代码示例
index.html
、main.css
、mian.js
、show.js
见1-3
package.json
{
"name": "webpack-1-3",
"version": "1.0.0",
"scripts": {
"build": "webpack"
},
"dependencies": {},
"devDependencies": {
"css-loader": "^6.7.3",
"mini-css-extract-plugin": "^2.7.2",
"style-loader": "^3.3.1",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1"
}
}
webpack.config.js
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
// JavaScript执行入口文件
entry: './main.js',
output: {
// 把所有依赖的模块合并输出到一个bundle.js
filename: 'bundle.js',
// 把输出文件都放到dist目录下
path: path.resolve(__dirname, './dist')
},
module: {
rules: [{
// 用正则去匹配要用该loader转换的CSS文件
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}]
},
plugins: [
new MiniCssExtractPlugin({
/*
fullhash:所有构建产物均使用相同的 hash。这意味着修改任何一个文件,所有文件的 hash 值都将会被改变
chunkhash:同一 chunk 下的文件使用相同的 hash。修改在同一个chunk中的文件,同属该 chunk 的所有文件 hash 值都会改变
contenthash:不同的文件使用不同的 hash。每个文件都会根据自己的文件内容生成 hash 值,互不干扰。
*/
filename: `[name]_[fullhash:8].css`
})
]
}
1-6使用DevServer
说明
安装 DevServer
,安装成功后执行 webpack-dev-server
命令
npm i -D webpack-dev-server
实时预览、模块热替换、支持Source Map
代码示例
index.html
、main.css
、mian.js
、show.js
见1-3
package.json
{
"name": "webpack-1-3",
"version": "1.0.0",
"scripts": {
"serve": "webpack-dev-server --mode=development --hot --devtool source-map",
"build": "webpack"
},
"dependencies": {},
"devDependencies": {
"css-loader": "^6.7.3",
"html-webpack-plugin": "^5.5.0",
"mini-css-extract-plugin": "^2.7.2",
"style-loader": "^3.3.1",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.11.1"
}
}
webpack.config.js
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
// JavaScript执行入口文件
entry: './main.js',
devServer: {
static: './',
},
output: {
// 把所有依赖的模块合并输出到一个bundle.js
filename: 'bundle.js',
// 把输出文件都放到dist目录下
path: path.resolve(__dirname, './dist')
},
module: {
rules: [{
// 用正则去匹配要用该loader转换的CSS文件
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}]
},
plugins: [
new MiniCssExtractPlugin({
/*
fullhash:所有构建产物均使用相同的 hash。这意味着修改任何一个文件,所有文件的 hash 值都将会被改变
chunkhash:同一 chunk 下的文件使用相同的 hash。修改在同一个chunk中的文件,同属该 chunk 的所有文件 hash 值都会改变
contenthash:不同的文件使用不同的 hash。每个文件都会根据自己的文件内容生成 hash 值,互不干扰。
*/
filename: `[name]_[fullhash:8].css`
})
]
}
1-7核心概念
Webpack
有以下几个核心概念。
Entry
:入口,Webpack
执行构建的第一步将从Entry
开始,可抽象成输入。Module
:模块,在Webpack
里一切皆模块,一个模块对应着一个文件。Webpack
会从配置的 Entry 开始递归找出所有依赖的模块。Chunk
:代码块,一个Chunk
由多个模块组合而成,用于代码合并与分割。Loader
:模块转换器,用于把模块原内容按照需求转换成新内容。Plugin
:扩展插件,在Webpack
构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要的事情。Output
:输出结果,在Webpack
经过一系列处理并得出最终想要的代码后输出结果。
Webpack
启动后会从 Entry
里配置的 Module
开始递归解析 Entry
依赖的所有 Module
。 每找到一个 Module
, 就会根据配置的 Loader
去找出对应的转换规则,对 Module
进行转换后,再解析出当前 Module
依赖的 Module
。 这些模块会以 Entry
为单位进行分组,一个 Entry
和其所有依赖的 Module 被分到一个组也就是一个 Chunk
。最后 Webpack
会把所有 Chunk
转换成文件输出。 在整个流程中 Webpack
会在恰当的时机执行 Plugin
里定义的逻辑。