来源掘金小册笔记
# 一、webpack概念和基础使用
# 1.1 安装和使用
npm install webpack webpack-cli -g
# 或者
yarn global add webpack webpack-cli
# 然后就可以全局执行命令了
webpack --help
# 1.2 webpack 的基本概念
webpack 本质上是一个打包工具,它会根据代码的内容解析模块依赖,帮助我们把多个模块的代码打包

webpack 会把我们项目中使用到的多个代码模块(可以是不同文件类型),打包构建成项目运行仅需要的几个静态文件
入口
入口可以使用
entry字段来进行配置,webpack支持配置多个入口来进行构建
module.exports = {
entry: './src/index.js'
}
// 上述配置等同于
module.exports = {
entry: {
main: './src/index.js'
}
}
// 或者配置多个入口
module.exports = {
entry: {
foo: './src/page-foo.js',
bar: './src/page-bar.js',
// ...
}
}
// 使用数组来对多个文件进行打包
module.exports = {
entry: {
main: [
'./src/foo.js',
'./src/bar.js'
]
}
}...
loader
可以把
loader理解为是一个转换器,负责把某种文件格式的内容转换成 webpack 可以支持打包的模块
- 当我们需要使用不同的
loader来解析处理不同类型的文件时,我们可以在module.rules字段下来配置相关的规则,例如使用Babel来处理.js文件
module: {
// ...
rules: [
{
test: /\.jsx?/, // 匹配文件路径的正则表达式,通常我们都是匹配文件类型后缀
include: [
path.resolve(__dirname, 'src') // 指定哪些路径下的文件需要经过 loader 处理
],
use: 'babel-loader', // 指定使用的 loader
},
],
}...
plugin
模块代码转换的工作由
loader来处理,除此之外的其他任何工作都可以交由plugin来完成。通过添加我们需要的plugin,可以满足更多构建中特殊的需求。例如,要使用压缩JS代码的uglifyjs-webpack-plugin插件,只需在配置中通过plugins字段添加新的plugin即可…
const UglifyPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
plugins: [
new UglifyPlugin()
],
}
plugin理论上可以干涉webpack整个构建流程,可以在流程的每一个步骤中定制自己的构建需求
输出
构建结果的文件名、路径等都是可以配置的,使用
output字段
module.exports = {
// ...
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
}
// 或者多个入口生成不同文件
module.exports = {
entry: {
foo: './src/foo.js',
bar: './src/bar.js',
},
output: {
filename: '[name].js',
path: __dirname + '/dist',
},
}
// 路径中使用 hash,每次构建时会有一个不同 hash 值,避免发布新版本时线上使用浏览器缓存
module.exports = {
// ...
output: {
filename: '[name].js',
path: __dirname + '/dist/[hash]',
},
}...
我们一开始直接使用
webpack构建时,默认创建的输出内容就是./dist/main.js
一个简单的 webpack 配置
我们把上述涉及的几部分配置内容合到一起,就可以创建一个简单的
webpack配置了,webpack运行时默认读取项目下的webpack.config.js文件作为配置。所以我们在项目中创建一个webpack.config.js文件
const path = require('path')
const UglifyPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.jsx?/,
include: [
path.resolve(__dirname, 'src')
],
use: 'babel-loader',
},
],
},
// 代码模块路径解析的配置
resolve: {
modules: [
"node_modules",
path.resolve(__dirname, 'src')
],
extensions: [".wasm", ".mjs", ".js", ".json", ".jsx"],
},
plugins: [
new UglifyPlugin(),
// 使用 uglifyjs-webpack-plugin 来压缩 JS 代码
// 如果你留意了我们一开始直接使用 webpack 构建的结果,你会发现默认已经使用了 JS 代码压缩的插件
// 这其实也是我们命令中的 --mode production 的效果,后续的小节会介绍 webpack 的 mode 参数
],
}...
# 二、搭建基础的前端开发环境
# 2.1 关联 HTML
webpack默认从作为入口的.js文件进行构建(更多是基于SPA去考虑),但通常一个前端项目都是从一个页面(即 HTML)出发的,最简单的方法是,创建一个 HTML 文件,使用script标签直接引用构建好的 JS 文件,如…
<script src="./dist/bundle.js"></script>
- 但是,如果我们的文件名或者路径会变化,例如使用
[hash]来进行命名,那么最好是将HTML引用路径和我们的构建结果关联起来,这个时候我们可以使用html-webpack-plugin html-webpack-plugin是一个独立的node package,所以在使用之前我们需要先安装它,把它安装到项目的开发依赖中
npm install html-webpack-plugin -D
然后在
webpack配置中,将html-webpack-plugin添加到plugins列表中
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// ...
plugins: [
new HtmlWebpackPlugin(),
],
}...
这样配置好之后,构建时
html-webpack-plugin会为我们创建一个HTML文件,其中会引用构建出来的 JS 文件。实际项目中,默认创建的HTML文件并没有什么用,我们需要自己来写HTML文件,可以通过html-webpack-plugin的配置,传递一个写好的 HTML 模板…
module.exports = {
// ...
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // 配置输出文件名和路径
template: 'assets/index.html', // 配置文件模板
}),
],
}...
这样,通过
html-webpack-plugin就可以将我们的页面和构建JS关联起来,回归日常,从页面开始开发。如果需要添加多个页面关联,那么实例化多个html-webpack-plugin, 并将它们都放到plugins字段数组中就可以了…
# 2.2 构建 CSS
我们编写
CSS,并且希望使用webpack来进行构建,为此,需要在配置中引入loader来解析和处理CSS文件
module.exports = {
module: {
rules: [
// ...
{
test: /\.css/,
include: [
path.resolve(__dirname, 'src'),
],
use: [
'style-loader',
'css-loader',
],
},
],
}
}...
css-loader负责解析CSS代码,主要是为了处理CSS中的依赖,例如@import和url()等引用外部文件的声明;style-loader会将css-loader解析的结果转变成JS代码,运行时动态插入style标签来让CSS代码生效…
经由上述两个
loader的处理后,CSS 代码会转变为 JS,和index.js一起打包了。如果需要单独把 CSS 文件分离出来,我们需要使用extract-text-webpack-plugin插件
const ExtractTextPlugin = require('extract-text-webpack-plugin')
module.exports = {
// ...
module: {
rules: [
{
test: /\.css$/,
// 因为这个插件需要干涉模块转换的内容,所以需要使用它对应的 loader
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader',
}),
},
],
},
plugins: [
// 引入插件,配置文件名,这里同样可以使用 [hash]
new ExtractTextPlugin('index.css'),
],
}...
# 2.3 CSS 预处理器
在上述使用 CSS 的基础上,通常我们会使用
Less/Sass等 CSS 预处理器,webpack 可以通过添加对应的loader来支持,以使用Less为例,我们可以在官方文档中找到对应的loader
module.exports = {
// ...
module: {
rules: [
{
test: /\.less$/,
// 因为这个插件需要干涉模块转换的内容,所以需要使用它对应的 loader
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader',
'less-loader',
],
}),
},
],
},
// ...
}...
