关于webpack的第一课

当我使用create-react-app接触到antd的时候,问题暴露出来了,关于配置文件和webpack等等,我一无所知,这是一个问题.于是,我开始寻找答案.

关于webpack

几篇他人精彩文章:

WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。

webpack

安装

1
2
3
4
//全局安装
npm install -g webpack
//安装到你的项目目录
npm install --save-dev webpack webpack-cli

开始正式使用webpack

初始化环境

1
2
3
4
5
6
// 在demo目录下:
npm init -y // 默认回复所有问题为yes

// 在项目目录下安装react和react-dom
npm i react react-dom
// 于是会产生一个node_Modules目录存放项目安装的库

尝试直接打包并且指定开发模式:
npx在项目内临时安装webpack和webpack-cli(而我习惯于全局安装这两个库)

1
2
npx webpack index.js -o build.min.js --mode development
// 提示安装cli,yes即可

而默认情况是:

1
webpack --mode development

webpack@4.x.x默认打包src下的index.js,生成dist目录存放打包后的main.js

为了避免修改源代码后需要手动打包的问题,可以添加监控options:

1
2
webpack --mode development --watch
// 保存文件后就会重新打包

为了让浏览器方面监控到页面代码的变化,并且自动刷新,就需要一个开发服务器:webpack-dev-server

1
2
3
npm i -D webpack-dev-server	// 临时安装在目录下的node-Modules内

npx webpack-dev-server --mode development --content-base ./dist

在index.js中添加jsx代码,于是就需要babel-loader(主页)出场救主.

引入加载器

JS加载器

项目目录内安装babel-loader:

1
2
3
4
npm install -D babel-loader @babel/core @babel/preset-env @babel/preset-react webpack

// 启动babel
npx webpack-dev-server --mode development --content-base ./dist --module-bind 'js=babel-loader?presets[]=@babel/preset-react'

于是发现这样以来终端options越来越多,就不够方便,于是开始通过配置文件来启动

在项目目录下创建了webpack.config.js文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// path库
const path = require('path')
module.exports = {
// 开发环境
mode: 'development',
// 服务器
devServer: {
// name和当前目录下的dist目录内的content为base(index.html)
contenBase: path.resolve(__dirname, 'dist')
},
module: {
// 各个模块的规则
rules: [
{
// 正则表达式,js文件的规则
test: /\.js$/,
// src目录内的js文件打包
include: [
path.resolve(__dirname, 'src')
],
// 打包工具 loader: babel-loader
loader: 'babel-loader',
// 转码规则
options: {
// react转码规则
presets: ['@babel/preset-react']
}
}
]
}
}
```
于是直接运行服务器即可:

```JavaScript
npx webpack-dev-server

提示:

1
2
3
✖ 「wds」: webpack Dev Server Invalid Options

options should NOT have additional properties

无效属性,问题出在DevServer配置上,我添加了无效的属性,结果一看,果然是contentBase写成了centenBase,改正!

file加载器

为了加载我需要的图片文件,于是安装file-loader

1
npm i -D file-loader

并且添加rules:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
rules: [
{
test: /\.js$/,
include: [
path.resolve(__dirname, 'src')
],
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react']
}
},
{
test: /\.jpg$/,
loader: 'file-loader'
}
]

Css加载器

安装:

1
npm i -D css-loader style-loader

配置:

1
2
3
4
5
6
7
8
9
{
test: /\.css$/,
// 使用两个加载器,则格式变化了,用到了use
use: [
// 两个顺序不能换,会报错
{loader: 'style-loader'},
{loader: 'css-loader'}
]
}

为了支持ES6的语法,需要安装babel-loader的插件@babel/plugin-proposal-class-properties

于是安装插件并且更新配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
npm i -D @babel/plugin-proposal-class-properties

// 配置文件更新
{
test: /\.js$/,
include: [
path.resolve(__dirname, 'src')
],
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react'],
plugins: ['@babel/plugin-proposal-class-properties']
}
},

部署

更改模式即可部署到dist目录下

1
npx webpack --mode production

每次部署之后,原dist下的一些img等等文件还在,于是一般需要先手动删除dist目录,也有插件可以完成此工作.

安装

1
npm i -D clean-webpack-plugin

部分配置代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
const path = require('path')
// 关键
const CleanWebpackPlugin = require('clean-webpack-plugin')
module.exports = {
mode: 'development',
devServer: {
contentBase: path.resolve(__dirname, 'dist')
},

// 部署插件
plugins: [
new CleanWebpackPlugin(['dist'])
],

自动部署会删除dist下的index.html,为了解决这个问题,可以引入html插件:

1
npm i -D html-webpack-plugin

配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const path = require('path')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
mode: 'development',
devServer: {
contentBase: path.resolve(__dirname, 'dist')
},

// 插件
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
title: 'webpack 教程'
})
],