学习Webpack4这一篇就够了

Posted 分享录

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习Webpack4这一篇就够了相关的知识,希望对你有一定的参考价值。

目录

  • 第一章 Webpack4简介


    • 1.1、Webpack4简介

    • 1.2、Wepback4目标

    • 1.3、Webpack4快速入门

  • 第二章 Webpack4资源管理


    • 2.1、处理样式资源

    • 2.2、处理脚本资源

    • 2.3、处理图像资源

    • 2.4、处理字体资源

    • 2.5、处理其它资源

    • 2.6、处理页面资源

    • 2.7、配置开发服务

  • 第三章 Webpack4环境配置


    • 3.1、开发环境配置

    • 3.2、生产环境配置



配套资料,免费下载
链接:https://pan.baidu.com/s/1NJtOQMA7nrIhuwmE-UDQaA
提取码:jfb9
复制这段内容后打开百度网盘手机App,操作更方便哦

第一章 Webpack4简介

1.1、Webpack4简介

webpack 是一种前端资源构建工具,一个静态模块打包器(module bundler)。在 webpack 看来, 前端的所有资源文件(js/json/css/less/sass/img/…)都会作为模块处理。它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源(bundle)。

模块要能够在客户端中去执行,则必须将它们从 server => browser

  • 一种极端的想法: 

    • 一个请求一个模块,只有需要的模块会被转换,但是耗费资源,时间长

    • 所有请求都在一个模块,不需要的模块也会被转换时间短,耗费资源少

  • 分块转换的想法: 

    • 将众多的模块切成许多片,在初始化时的请求不会包括完整的代码,并且在初始化时不需要的模块切片会在后续加载过程中按需加载,并且将模块化的切片方式是可以有开发人员自己定义的。

我们知道,对于浏览器来说,加载的资源越少,响应的速度也就越快,所以有时候我们为了优化浏览器的性能,会尽可能的将资源合并到一个主文件app.js里面。但是这导致的很大的缺点:

  • 当你的项目十分庞大的时候,不同的页面不能做到按需加载,而是将所有的资源一并加载,耗费时间长,性能降低。

  • 会导致依赖库之间关系的混乱,特别是大型项目时,会变得难以维护和跟踪。比如:哪些文件是需要A模块加载完后才能执行的?哪些页面会受到多个样式表同时影响的?等许多问题。

而 webpack 可以很好的解决以上缺点,因为它是一个十分聪明的模块打包系统,当你正确配置后,它会比你想象中的更强大,更优秀。

1.2、Wepback4目标

webpack 能将依赖的模块转化成可以代表这些包的静态文件,它的目标有:

  • 将依赖的模块分片化,并且按需加载

  • 解决大型项目初始化加载慢的问题

  • 每一个静态文件都可以看成一个模块

  • 可以整合第三方库

  • 能够在大型项目中运用

  • 可以自定义切割模块的方式

1.3、Webpack4快速入门

我们先要做一个 必需 的准备工作,那就是允许在你的系统上运行脚本。在底部左侧导航栏输入 Windows PowerShell ,然后 以管理员身份运行 ,在打开的PowerShell窗口中,输入指定的指令 Set-ExecutionPolicy RemoteSigned ,等弹出内容输入 Y 确定即可。

学习Webpack4这一篇就够了

学习Webpack4这一篇就够了

注意:本教程所采用的是 Node.js v14.15.0。

首先我们创建一个目录,初始化 npm,然后在本地安装 webpack,接着安装 webpack-cli(此工具用于在命令行中运行 webpack):

mkdir webpack-demo
cd webpack-demo
npm init -y
npm install --save-dev webpack@4.44.2 webpack-cli@3.3.12
  • 1

  • 2

  • 3

  • 4

注意:是否使用 --save-dev 取决于你的应用场景。假设你仅使用 webpack 进行构建操作,那么建议你在安装时使用 --save-dev 选项,因为可能你不需要在生产环境上使用 webpack。如果需要应用于生产环境,请忽略 --save-dev 选项。

接下来,我们需要运行 npm install --save-dev jquery@3.5.1 下载一个jQuery库,然后为接下来的使用提供依赖。

npm install --save-dev jquery@3.5.1
  • 1

现在,我们将创建以下目录结构、文件和内容:

创建一个src目录,目录中创建一个 index.js ,文件内容如下:

// 导入刚才下载的jQuery库
import $ from 'jquery';

// 为h1大标题美化样式
$('h1').css('color','red');
  • 1

  • 2

  • 3

  • 4

  • 5

创建一个dist目录,目录中创建一个 index.html ,文件内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
</head>
<body>
<h1>Hello,Webpack!</h1>
<script src="main.js"></script>
</body>
</html>
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

现在,我们将会打包所有脚本,执行 npx webpack,会将我们的脚本 src/index.js 作为入口起点(默认),也会将 dist/main.js作为输出路径(默认)。Node 8.2/npm 5.2.0 以上版本提供的 npx 命令,可以运行在初次安装的 webpack package 中的 webpack 二进制文件:

npx webpack
  • 1

在浏览器中打开 dist 目录下的 index.html,如果一切正常,你应该能看到以下红色文本:'Hello,Webpack!'

ES2015 中的 import 和 export 语句已经被标准化。虽然大多数浏览器还无法支持它们,但是 webpack 却能够提供开箱即用般的支持。

事实上,webpack 在幕后会将代码“转译”,以便旧版本浏览器可以执行。如果你检查 dist/main.js,你可以看到 webpack 具体如何实现,这是独创精巧的设计!除了 import 和 export,webpack 还能够很好地支持多种其它模块语法。

在 webpack v4 中,可以无须任何配置,然而大多数项目会需要很复杂的设置,这就是为什么 webpack 仍然要支持配置文件。这比在 terminal(终端) 中手动输入大量命令要高效的多,所以让我们创建一个配置文件:

webpack.config.js

const { resolve } = require('path');

module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: resolve(__dirname, 'dist'),
},
mode: 'development'
};
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

现在,让我们通过新的配置文件再次执行命令重新进行构建:

npx webpack --config webpack.config.js
  • 1

注意:如果 webpack.config.js 存在,则 webpack 命令将默认选择使用它。我们在这里使用 --config 选项只是向你表明,可以传递任何名称的配置文件。这对于需要拆分成多个文件的复杂配置是非常有用的,比起 CLI 这种简单直接的使用方式,配置文件具有更多的灵活性。

考虑到用 CLI 这种方式来运行本地的 webpack 副本并不是特别方便,我们可以设置一个快捷方式。调整 package.json 文件内容如下:

{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"jquery": "^3.5.1",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12"
}
}
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

  • 17

  • 18

现在,可以使用 npm run build 命令,来替代我们之前使用的 npx 命令。

现在运行 npm run build 命令,然后看看你的脚本别名是否正常运行:

npm run build
  • 1

在浏览器中打开 dist 目录下的 index.html,如果一切正常,你应该能看到以下红色文本:'Hello,Webpack!'

现在由 webpack 将我们自己写的 index.js 和 jQuery 打包到了 dist/main.js ,然后由我们手写的 dist/index.html 进行引用,如果你不想写 index.html 接下来介绍一个插件,可以大大解放你的双手。

npm install --save-dev html-webpack-plugin
  • 1

HtmlWebpackPlugin:该插件将为你生成一个 HTML5 文件, 其中包括使用 script 标签的 body 中的所有 webpack 包。只需添加插件到你的 webpack 配置如下:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: resolve(__dirname, 'dist'),
},
plugins: [new HtmlWebpackPlugin()],
mode: 'development'
};
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

这将会产生一个包含以下内容的文件 dist/index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>webpack App</title>
</head>
<body>
<script src="main.js"></script>
</body>
</html>
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

现在运行 npm run build 命令:

npm run build
  • 1

在浏览器中打开 dist 目录下的 index.html,如果一切正常,你应该 看不到 红色文本:'Hello,Webpack!'

因为,这是由插件自动生成的 index.html 自然是没有 <h1>Hello,Webpack!</h1>,那能不能指定咱们自己写的一个 index.html作为这个生成的模板,当然也是可以的,只需要如下修改:

webpack.config.js

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: resolve(__dirname, 'dist'),
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

当然了,我们也需要在 src 下创建一个我们自己的模板,它默认创建的,可能有时候并不适合我们,这时候,我们可以指定:

src/index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
</head>
<body>
<h1>Hello,Webpack!</h1>
</body>
</html>
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

现在运行 npm run build 命令:

npm run build
  • 1

在浏览器中打开 dist 目录下的 index.html,如果一切正常,你应该能看到红色文本:'Hello,Webpack!'

第二章 Webpack4资源管理

2.1、处理样式资源

  • 处理css样式文件

  • 处理less样式文件

  • 处理sass样式文件

第一步:安装处理器loader

npm install --save-dev style-loader css-loader less-loader less sass-loader node-sass
  • 1

第二步:引入处理器loader

webpack.config.js

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: resolve(__dirname, 'dist'),
},
module: {
rules: [
// 处理css样式
{
test: /.css$/i,
use: ['style-loader', 'css-loader']
},
// 处理less样式
{
test: /.less$/i,
use: ['style-loader', 'css-loader', 'less-loader']
},
// 处理sass样式
{
test: /.scss$/i,
use: ['style-loader', 'css-loader', 'sass-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
  • 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

第三步:验证处理器是否工作

在 src 目录下,创建 style.css ,文件内容如下:

h2{color: blueviolet;}
  • 1

在 src 目录下,创建 style.less ,文件内容如下:

h3{color: pink;}
  • 1

在 src 目录下,创建 style.scss ,文件内容如下:

h4{color: orange;}
  • 1

在 src 目录下,修改 index.js ,文件内容如下:

// 导入刚才下载的jQuery库
import $ from 'jquery';
// 导入css样式
import './style.css';
// 导入less样式
import './style.less';
// 导入sass样式
import './style.scss';

// 为h1大标题美化样式
$('h1').css('color', 'red');
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

在 src 目录下,修改 index.html ,文件内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
</head>
<body>
<h1>Hello,Webpack jquery!</h1>
<h2>Hello,Webpack css!</h2>
<h3>Hello,Webpack less!</h3>
<h4>Hello,Webpack sass!</h4>
</body>
</html>
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

第四步:测试输出效果

运行命令 npm run build 重新进行打包,然后打开 dist/index.html ,如果一切正常,那么您的页面效果看起来应该如下:

学习Webpack4这一篇就够了

现在我们发现 webpack 可以处理css、less、sass资源了,但是,经过处理后的样式是使用 style 标签内联到 html 中,如果每一个样式非常的大,那么页面的加载速度就会大大降低,为了解决这个问题,我们需要把每一种样式文件单独抽取出来,首先处理浏览器的兼容性,然后将处理后的样式文件经过压缩处理并导出为不同的文件,这样的处理才是有效的,接下来我们就这个问题进行探讨。

  • 处理浏览器的兼容性问题

  • 压缩css、less、sass样式

  • 抽取css、less、sass样式

第一步:安装兼容处理器loader和压缩、抽取插件

npm install --save-dev postcss-loader postcss-preset-env optimize-css-assets-webpack-plugin mini-css-extract-plugin
  • 1

第二步:引入处理器loader

webpack.config.js

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

// 设置nodejs环境变量,开发模式下需要设置为 development
process.env.NODE_ENV = 'development';

module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: resolve(__dirname, 'dist'),
},
module: {
rules: [
// 处理css样式
{
test: /.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'] /* 用于处理css兼容性问题 */
},
// 处理less样式
{
test: /.less$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader']
},
// 处理sass样式
{
test: /.scss$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
// 用于压缩css样式文件
new OptimizeCssAssetsWebpackPlugin(),
// 用于提取css样式文件
new MiniCssExtractPlugin({
filename: 'css/built.[contenthash].css'
})
],
mode: 'development'
};
  • 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

  • 37

  • 38

  • 39

  • 40

  • 41

  • 42

  • 43

  • 44

  • 45

  • 46

第三步:在 package.json 中需要设置兼容浏览器的版本

package.json

{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"css-loader": "^5.0.1",
"html-webpack-plugin": "^4.5.0",
"jquery": "^3.5.1",
"less": "^3.12.2",
"less-loader": "^7.1.0",
"mini-css-extract-plugin": "^1.3.1",
"node-sass": "^5.0.0",
"optimize-css-assets-webpack-plugin": "^5.0.4",
"postcss-loader": "^4.1.0",
"postcss-preset-env": "^6.7.0",
"sass-loader": "^10.1.0",
"style-loader": "^2.0.0",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12"
},
"browserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
}
}
  • 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

  • 37

  • 38

  • 39

  • 40

  • 41

第四步:测试输出效果

运行命令 npm run build 重新进行打包,然后打开 dist/index.html ,如果一切正常,那么您的页面效果看起来应该如下:

学习Webpack4这一篇就够了

而您的样式文件看起来应该是这样的:

学习Webpack4这一篇就够了

做到这里,你可以说已经掌握了处理css、less、sass的核心知识了,我们注意一下 dist 目录,随着代码的修改,以及文件的增多,有些文件是旧文件,我们可以在每一次打包之前手动删除一次,但是太麻烦了,所以这里推荐一款清理插件,它会在每次打包发布之前,都会将目标生成目录进行清理,因此,我们需要安装一款插件:

npm install --save-dev clean-webpack-plugin
  • 1

webpack.config.js

const { resolve } = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

// 设置nodejs环境变量,开发模式下需要设置为 development
process.env.NODE_ENV = 'development';

module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: resolve(__dirname, 'dist'),
},
module: {
rules: [
// 处理css样式
{
test: /.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'] /* 用于处理css兼容性问题 */
},
// 处理less样式
{
test: /.less$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader']
},
// 处理sass样式
{
test: /.scss$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader']
}
]
},
plugins: [
// 清理旧打包资源插件
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: './src/index.html'
}),
// 用于压缩css样式文件
new OptimizeCssAssetsWebpackPlugin(),
// 用于提取css样式文件
new MiniCssExtractPlugin({
filename: 'css/built.[contenthash].css'
})
],
mode: 'development'
};
  • 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

  • 37

  • 38

  • 39

  • 40

  • 41

  • 42

  • 43

  • 44

  • 45

  • 46

  • 47

  • 48

  • 49

2.2、处理脚本资源

我们对脚本主要是进行以下几个方面的处理:

  • 对不同模块的 js 代码进行合并打包(Webpack会自动对js和json文件进行打包,此步忽略)

  • 对不同模块的 js 代码进行语法检查

  • 对不同模块的 js 代码进行兼容性处理

  • 对不同模块的 js 代码进行压缩抽取

第一步:安装处理器loader

npm install --save-dev eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import
npm install --save-dev babel-loader @babel/core @babel/preset-env core-js
npm install --save-dev uglifyjs-webpack-plugin
  • 1

  • 2

  • 3

第二步:引入处理器loader

webpack.config.js

const { resolve } = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin');

// 定义 nodejs 环境变量:决定使用 browserslist 的哪个环境
process.env.NODE_ENV = 'development';

module.exports = {
entry: './src/index.js',
output: {
filename: 'js/built.[contenthash].js',/* 重新指定js输出文件路径 */
path: resolve(__dirname, 'dist'),
},
module: {
rules: [
// 处理css样式
{
test: /.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'] /* 用于处理css兼容性问题 */
},
// 处理less样式
{
test: /.less$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader']
},
// 处理sass样式
{
test: /.scss$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader']
},
// 进行js语法检查
{
test: /.js$/i,
loader: 'eslint-loader',
options: {
// 自动修复eslint的错误
fix: true
}
},
// 进行js兼容性
{
test: /.js$/i,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定core-js版本
corejs: { version: 3 },
// 指定兼容性做到哪个版本浏览器
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
]
}
}
]
},
plugins: [
// 清理旧打包资源插件
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: './src/index.html'
}),
// 用于压缩css样式文件
new OptimizeCssAssetsWebpackPlugin(),
// 用于提取css样式文件
new MiniCssExtractPlugin({
filename: 'css/built.[contenthash].css'
}),
// 用于压缩js脚本代码
new UglifyjsWebpackPlugin()
],
mode: 'development'
};
  • 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

  • 37

  • 38

  • 39

  • 40

  • 41

  • 42

  • 43

  • 44

  • 45

  • 46

  • 47

  • 48

  • 49

  • 50

  • 51

  • 52

  • 53

  • 54

  • 55

  • 56

  • 57

  • 58

  • 59

  • 60

  • 61

  • 62

  • 63

  • 64

  • 65

  • 66

  • 67

  • 68

  • 69

  • 70

  • 71

  • 72

  • 73

  • 74

  • 75

  • 76

  • 77

  • 78

  • 79

  • 80

  • 81

  • 82

  • 83

  • 84

  • 85

  • 86

  • 87

  • 88

第三步:在 package.json 中需要设置语法检查的规则 airbnb-base

package.json

{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.12.3",
"@babel/preset-env": "^7.12.1",
"babel-loader": "^8.2.1",
"clean-webpack-plugin": "^3.0.0",
"core-js": "^3.7.0",
"css-loader": "^5.0.1",
"eslint": "^7.13.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-loader": "^4.0.2",
"eslint-plugin-import": "^2.22.1",
"html-webpack-plugin": "^4.5.0",
"jquery": "^3.5.1",
"less": "^3.12.2",
"less-loader": "^7.1.0",
"mini-css-extract-plugin": "^1.3.1",
"node-sass": "^5.0.0",
"optimize-css-assets-webpack-plugin": "^5.0.4",
"postcss-loader": "^4.1.0",
"postcss-preset-env": "^6.7.0",
"sass-loader": "^10.1.0",
"style-loader": "^2.0.0",
"uglifyjs-webpack-plugin": "^2.2.0",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12"
},
"browserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
},
"eslintConfig": {
"extends": "airbnb-base",
"env": {
"browser": true
}
}
}
  • 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

  • 37

  • 38

  • 39

  • 40

  • 41

  • 42

  • 43

  • 44

  • 45

  • 46

  • 47

  • 48

  • 49

  • 50

  • 51

  • 52

  • 53

  • 54

  • 55

  • 56

  • 57

第四步:测试输出效果

运行命令 npm run build 重新进行打包,你应该是运行失败的,因为语法检查提示:jquery不应该被安装到开发依赖中,这里我们用最简单的方法解决,注释掉,index.js 中所有用到jquery的部分,然后就行了。

学习Webpack4这一篇就够了

重新运行命令 npm run build 重新进行打包,然后打开 dist/index.html ,如果一切正常,那么您的页面效果看起来应该如下:

学习Webpack4这一篇就够了

学习Webpack4这一篇就够了

2.3、处理图像资源

除了样式和脚本资源需要处理,我们还得处理图像资源,常见的图像包括以下几种出现方式:

  • 包括样式中background属性中的url图片

  • 使用脚本动态添加的img图片

  • 直接写在页面中的img图片

您应该找一张你所喜欢的图片放到src中,以方便后边的演示,在这里名称默认为“myimg.png”

第一步:安装处理器loader

npm install --save-dev url-loader file-loader html-loader
  • 1

第二步:引用处理器loader

webpack.config.js

const { resolve } = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin');

// 定义 nodejs 环境变量:决定使用 browserslist 的哪个环境
process.env.NODE_ENV = 'development';

const MiniCssExtractPlugin_loader = {
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../' /* 修正把样式单独抽取到一个目录中出现的属性图片路径报错 */
}
};

module.exports = {
entry: './src/index.js',
output: {
filename: 'js/built.[contenthash].js',/* 重新指定js输出文件路径 */
path: resolve(__dirname, 'dist')
},
module: {
rules: [
// 处理css样式
{
test: /.css$/i,
use: [MiniCssExtractPlugin_loader, 'css-loader', 'postcss-loader'] /* 用于处理css兼容性问题 */
},
// 处理less样式
{
test: /.less$/i,
use: [MiniCssExtractPlugin_loader, 'css-loader', 'postcss-loader', 'less-loader']
},
// 处理sass样式
{
test: /.scss$/i,
use: [MiniCssExtractPlugin_loader, 'css-loader', 'postcss-loader', 'sass-loader']
},
// 进行js语法检查
{
test: /.js$/i,
loader: 'eslint-loader',
options: {
// 自动修复eslint的错误
fix: true
}
},
// 进行js兼容性
{
test: /.js$/i,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定core-js版本
corejs: { version: 3 },
// 指定兼容性做到哪个版本浏览器
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
]
}
},
// 进行样式属性、脚本添加图像的处理
{
test: /.(png|jpg|jpeg|gif)$/i,
loader: 'url-loader',
options: {
limit: 10 * 1024,// 图片大小小于10kb,就会被base64处理
esModule: false,// 解决:关闭url-loader的es6模块化,使用commonjs解析
outputPath: 'images', // 将文件打包到哪里
name: '[hash].[ext]'// 给图片进行重命名
}
},
// 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
{
test: /.html$/i,
loader: 'html-loader'
}
]
},
plugins: [
// 清理旧打包资源插件
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: './src/index.html'
}),
// 用于压缩css样式文件
new OptimizeCssAssetsWebpackPlugin(),
// 用于提取css样式文件
new MiniCssExtractPlugin({
filename: 'css/built.[contenthash].css'
}),
// 用于压缩js脚本代码
new UglifyjsWebpackPlugin()
],
mode: 'development'
};
  • 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

  • 37

  • 38

  • 39

  • 40

  • 41

  • 42

  • 43

  • 44

  • 45

  • 46

  • 47

  • 48

  • 49

  • 50

  • 51

  • 52

  • 53

  • 54

  • 55

  • 56

  • 57

  • 58

  • 59

  • 60

  • 61

  • 62

  • 63

  • 64

  • 65

  • 66

  • 67

  • 68

  • 69

  • 70

  • 71

  • 72

  • 73

  • 74

  • 75

  • 76

  • 77

  • 78

  • 79

  • 80

  • 81

  • 82

  • 83

  • 84

  • 85

  • 86

  • 87

  • 88

  • 89

  • 90

  • 91

  • 92

  • 93

  • 94

  • 95

  • 96

  • 97

  • 98

  • 99

  • 100

  • 101

  • 102

  • 103

  • 104

  • 105

  • 106

  • 107

  • 108

  • 109

  • 110

  • 111

第三步:验证处理器是否工作

在 src 目录下,修改 style.css ,文件内容如下:

h2 {
width: 151px;
height: 151px;
background: url('./myimg.png') no-repeat;
}
  • 1

  • 2

  • 3

  • 4

  • 5

在 src 目录下,修改 style.less ,文件内容如下:

h3 {
width: 151px;
height: 151px;
background: url('./myimg.png') no-repeat;
}
  • 1

  • 2

  • 3

  • 4

  • 5

在 src 目录下,修改 style.scss ,文件内容如下:

h4 {
width: 151px;
height: 151px;
background: url('./myimg.png') no-repeat;
}
  • 1

  • 2

  • 3

  • 4

  • 5

在 src 目录下,修改 index.js ,文件内容如下:

import './style.css'; // 导入css样式

import './style.less'; // 导入less样式

import './style.scss'; // 导入sass样式

import MyImg from './myimg.png'; // 导入一张图片

const myimg = new Image(); // 创建一张图片

myimg.src = MyImg;
document.body.append(myimg);
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

在 src 目录下,修改 index.html ,文件内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
</head>
<body>
<p>下边三张图片是css、less、sass中引入的:</p>
<h2>hello css!</h2>
<h3>hello less!</h3>
<h4>hello sass!</h4>
<p>下边这张图片是html中引入的:</p>
<img src="./myimg.png">
<p>下边这张图片是js中引入的:</p>
</body>
</html>
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

  • 17

第四步:测试输出效果

运行命令 npm run build 重新进行打包,然后打开 dist/index.html ,如果一切正常,那么您的页面效果看起来应该如下:

学习Webpack4这一篇就够了

2.4、处理字体资源

现在,我们准备了一个fonts文件夹(配套资料中有),里边有样式也有各种字体文件,我们现在需要对这些资源进行管理,具体怎么做,请往下看。

学习Webpack4这一篇就够了

第一步:安装处理器loader

file-loader在上一步的时候已经安装过了,这里就不用安装了
  • 1

第二步:引用处理器loader

webpack.config.js

const { resolve } = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin');

// 定义 nodejs 环境变量:决定使用 browserslist 的哪个环境
process.env.NODE_ENV = 'development';

const MiniCssExtractPlugin_loader = {
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../' /* 修正把样式单独抽取到一个目录中出现的属性图片路径报错 */
}
};

module.exports = {
entry: './src/index.js',
output: {
filename: 'js/built.[contenthash].js',/* 重新指定js输出文件路径 */
path: resolve(__dirname, 'dist')
},
module: {
rules: [
// 处理css样式
{
test: /.css$/i,
use: [MiniCssExtractPlugin_loader, 'css-loader', 'postcss-loader'] /* 用于处理css兼容性问题 */
},
// 处理less样式
{
test: /.less$/i,
use: [MiniCssExtractPlugin_loader, 'css-loader', 'postcss-loader', 'less-loader']
},
// 处理sass样式
{
test: /.scss$/i,
use: [MiniCssExtractPlugin_loader, 'css-loader', 'postcss-loader', 'sass-loader']
},
// 进行js语法检查
{
test: /.js$/i,
loader: 'eslint-loader',
options: {
// 自动修复eslint的错误
fix: true
}
},
// 进行js兼容性
{
test: /.js$/i,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定core-js版本
corejs: { version: 3 },
// 指定兼容性做到哪个版本浏览器
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
]
}
},
// 进行样式属性、脚本添加图像的处理
{
test: /.(png|jpg|jpeg|gif)$/i,
loader: 'url-loader',
options: {
limit: 10 * 1024,// 图片大小小于10kb,就会被base64处理
esModule: false,// 解决:关闭url-loader的es6模块化,使用commonjs解析
outputPath: 'images', // 将文件打包到哪里
name: '[hash].[ext]'// 给图片进行重命名
}
},
// 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
{
test: /.html$/i,
loader: 'html-loader'
},
// 打包字体资源
{
test: /.(eot|ttf|svg|woff|woff2)$/i,
loader: 'file-loader',
options: {
outputPath: 'fonts', // 将文件打包到哪里
name: '[hash].[ext]'// 给文件进行重命名
}
}
]
},
plugins: [
// 清理旧打包资源插件
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: './src/index.html'
}),
// 用于压缩css样式文件
new OptimizeCssAssetsWebpackPlugin(),
// 用于提取css样式文件
new MiniCssExtractPlugin({
filename: 'css/built.[contenthash].css'
}),
// 用于压缩js脚本代码
new UglifyjsWebpackPlugin()
],
mode: 'development'
};
  • 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

  • 37

  • 38

  • 39

  • 40

  • 41

  • 42

  • 43

  • 44

  • 45

  • 46

  • 47

  • 48

  • 49

  • 50

  • 51

  • 52

  • 53

  • 54

  • 55

  • 56

  • 57

  • 58

  • 59

  • 60

  • 61

  • 62

  • 63

  • 64

  • 65

  • 66

  • 67

  • 68

  • 69

  • 70

  • 71

  • 72

  • 73

  • 74

  • 75

  • 76

  • 77

  • 78

  • 79

  • 80

  • 81

  • 82

  • 83

  • 84

  • 85

  • 86

  • 87

  • 88

  • 89

  • 90

  • 91

  • 92

  • 93

  • 94

  • 95

  • 96

  • 97

  • 98

  • 99

  • 100

  • 101

  • 102

  • 103

  • 104

  • 105

  • 106

  • 107

  • 108

  • 109

  • 110

  • 111

  • 112

  • 113

  • 114

  • 115

  • 116

  • 117

  • 118

  • 119

  • 120

第三步:验证处理器是否工作

在 src 目录下,修改 index.js ,文件内容如下:

import './style.css'; // 导入css样式

import './style.less'; // 导入less样式

import './style.scss'; // 导入sass样式

import './fonts/iconfont.css'; // 导入字体资源
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

在 src 目录下,修改 index.html ,文件内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
</head>
<body>
<span class="iconfont icon-dianzan"></span>
<span class="iconfont icon-pinglun"></span>
<span class="iconfont icon-fenxiang"></span>
<span class="iconfont icon-gengduo"></span>
<span class="iconfont icon-guanbi"></span>
<span class="iconfont icon-shanchu"></span>
</body>
</html>
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

第四步:测试输出效果

运行命令 npm run build 重新进行打包,然后打开 dist/index.html ,如果一切正常,那么您的页面效果看起来应该如下:

学习Webpack4这一篇就够了

2.5、处理其它资源

其它资源是指除了html、js、json、css、less、sass、(png|jpg|jpeg|gif)、(eot|ttf|svg|woff|woff2)之外的资源,其实我们只需要使用一个 file-loader 就可以解决了,这里就不演示了,直接贴出处理器代码,请自行复制到指定位置:

// 打包其它资源
{
exclude: /.(html|js|json|css|less|scss|png|jpg|jpeg|gif|eot|ttf|svg|woff|woff2)$/i,
loader: 'file-loader',
options: {
outputPath: 'others', // 将文件打包到哪里
name: '[hash].[ext]'// 给文件进行重命名
}
}
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

2.6、处理页面资源

我们需要对页面资源进行去掉多余空格、注释,进行压缩处理,只需要修改一处配置即可。

new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,// 清理多余空格
removeComments: true// 移除注释
}
}),
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

运行 npm run build ,如果顺利,你将会看到以下效果:

学习Webpack4这一篇就够了

2.7、配置开发服务

我们每次写完代码,都得需要手动打包,然后再打开 dist/index.html ,即使有一点错误,重新修改也需要打包,很不方便有没有,还有就是有一些技术是需要服务器才能运行,并不支持本地直接打开 html 代码运行,遇到这种问题,我们也会束手无策,所以,我们需要一款运行在服务器端的插件或者软件,幸好,webpack 早已想到,如何使用,请看下边:

npm install --save-dev webpack-dev-server@3.11.0
  • 1

webpack.config.js 只需要配置 devServer 即可

const { resolve } = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin');

// 定义 nodejs 环境变量:决定使用 browserslist 的哪个环境
process.env.NODE_ENV = 'development';

const MiniCssExtractPlugin_loader = {
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../' /* 修正把样式单独抽取到一个目录中出现的属性图片路径报错 */
}
};

module.exports = {
entry: './src/index.js',
output: {
filename: 'js/built.[contenthash].js',/* 重新指定js输出文件路径 */
path: resolve(__dirname, 'dist')
},
module: {
rules: [
// 处理css样式
{
test: /.css$/i,
use: [MiniCssExtractPlugin_loader, 'css-loader', 'postcss-loader'] /* 用于处理css兼容性问题 */
},
// 处理less样式
{
test: /.less$/i,
use: [MiniCssExtractPlugin_loader, 'css-loader', 'postcss-loader', 'less-loader']
},
// 处理sass样式
{
test: /.scss$/i,
use: [MiniCssExtractPlugin_loader, 'css-loader', 'postcss-loader', 'sass-loader']
},
// 进行js语法检查
{
test: /.js$/i,
loader: 'eslint-loader',
options: {
// 自动修复eslint的错误
fix: true
}
},
// 进行js兼容性
{
test: /.js$/i,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定core-js版本
corejs: { version: 3 },
// 指定兼容性做到哪个版本浏览器
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
]
}
},
// 进行样式属性、脚本添加图像的处理
{
test: /.(png|jpg|jpeg|gif)$/i,
loader: 'url-loader',
options: {
limit: 10 * 1024,// 图片大小小于10kb,就会被base64处理
esModule: false,// 解决:关闭url-loader的es6模块化,使用commonjs解析
outputPath: 'images', // 将文件打包到哪里
name: '[hash].[ext]'// 给图片进行重命名
}
},
// 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
{
test: /.html$/i,
loader: 'html-loader'
},
// 打包字体资源
{
test: /.(eot|ttf|svg|woff|woff2)$/i,
loader: 'file-loader',
options: {
outputPath: 'fonts', // 将文件打包到哪里
name: '[hash].[ext]'// 给文件进行重命名
}
},
// 打包其它资源
{
exclude: /.(html|js|json|css|less|scss|png|jpg|jpeg|gif|eot|ttf|svg|woff|woff2)$/i,
loader: 'file-loader',
options: {
outputPath: 'others', // 将文件打包到哪里
name: '[hash].[ext]'// 给文件进行重命名
}
}
]
},
plugins: [
// 清理旧打包资源插件
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,// 清理多余空格
removeComments: true// 移除注释
}
}),
// 用于压缩css样式文件
new OptimizeCssAssetsWebpackPlugin(),
// 用于提取css样式文件
new MiniCssExtractPlugin({
filename: 'css/built.[contenthash].css'
}),
// 用于压缩js脚本代码
new UglifyjsWebpackPlugin()
],
mode: 'development',
// 开发服务器 devServer:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)
// 特点:只会在内存中编译打包,不会有任何输出
// 启动devServer指令为:npx webpack-dev-server
devServer: {
// 项目构建后路径
contentBase: resolve(__dirname, 'dist'),
// 启动gzip压缩
compress: true,
// 端口号
port: 3000,
// 自动打开浏览器
open: true
}
};
  • 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

  • 37

  • 38

  • 39

  • 40

  • 41

  • 42

  • 43

  • 44

  • 45

  • 46

  • 47

  • 48

  • 49

  • 50

  • 51

  • 52

  • 53

  • 54

  • 55

  • 56

  • 57

  • 58

  • 59

  • 60

  • 61

  • 62

  • 63

  • 64

  • 65

  • 66

  • 67

  • 68

  • 69

  • 70

  • 71

  • 72

  • 73

  • 74

  • 75

  • 76

  • 77

  • 78

  • 79

  • 80

  • 81

  • 82

  • 83

  • 84

  • 85

  • 86

  • 87

  • 88

  • 89

  • 90

  • 91

  • 92

  • 93

  • 94

  • 95

  • 96

  • 97

  • 98

  • 99

  • 100

  • 101

  • 102

  • 103

  • 104

  • 105

  • 106

  • 107

  • 108

  • 109

  • 110

  • 111

  • 112

  • 113

  • 114

  • 115

  • 116

  • 117

  • 118

  • 119

  • 120

  • 121

  • 122

  • 123

  • 124

  • 125

  • 126

  • 127

  • 128

  • 129

  • 130

  • 131

  • 132

  • 133

  • 134

  • 135

  • 136

  • 137

  • 138

  • 139

  • 140

  • 141

  • 142

  • 143

  • 144

  • 145

  • 146

运行 npx webpack-dev-server ,如果顺利,你将会看到以下效果:

第三章 Webpack4环境配置

3.1、开发环境配置

安装依赖

npm install --save-dev style-loader css-loader less-loader less sass-loader node-sass
npm install --save-dev eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import
npm install --save-dev babel-loader @babel/core @babel/preset-env core-js
npm install --save-dev uglifyjs-webpack-plugin
npm install --save-dev url-loader file-loader html-loader
npm install --save-dev webpack-dev-server@3.11.0
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

webpack.config.js

const { resolve } = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

// 定义 nodejs 环境变量:决定使用 browserslist 的哪个环境
process.env.NODE_ENV = 'development';

const MiniCssExtractPlugin_loader = {
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../' /* 修正把样式单独抽取到一个目录中出现的属性图片路径报错 */
}
};

module.exports = {
entry: './src/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'dist')
},
module: {
rules: [
// 进行js语法检查
{
test: /.js$/i,
loader: 'eslint-loader',
options: {
fix: true
}
},
{
// 以下 loader 只会匹配一个,减少了打包时间
oneOf: [
// 处理css样式
{
test: /.css$/i,
use: [MiniCssExtractPlugin_loader, 'css-loader', 'postcss-loader']
},
// 处理less样式
{
test: /.less$/i,
use: [MiniCssExtractPlugin_loader, 'css-loader', 'postcss-loader', 'less-loader']
},
// 处理sass样式
{
test: /.scss$/i,
use: [MiniCssExtractPlugin_loader, 'css-loader', 'postcss-loader', 'sass-loader']
},
// 进行js兼容性
{
test: /.js$/i,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: { version: 3 },
targets: {
chrome: '60',
firefox: '50'
}
}
]
]
}
},
// 进行样式属性、脚本添加图像的处理
{
test: /.(png|jpg|jpeg|gif)$/i,
loader: 'url-loader',
options: {
limit: 10 * 1024,
esModule: false,
outputPath: 'images',
name: '[hash].[ext]'
}
},
// 处理html文件的img图片
{
test: /.html$/i,
loader: 'html-loader'
},
// 打包字体资源
{
test: /.(eot|ttf|svg|woff|woff2)$/i,
loader: 'file-loader',
options: {
outputPath: 'fonts', // 将文件打包到哪里
name: '[hash].[ext]'// 给文件进行重命名
}
},
// 打包其它资源
{
exclude: /.(html|js|json|css|less|scss|png|jpg|jpeg|gif|eot|ttf|svg|woff|woff2)$/i,
loader: 'file-loader',
options: {
outputPath: 'others', // 将文件打包到哪里
name: '[hash].[ext]'// 给文件进行重命名
}
}
]
}
]
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
filename: 'css/built.css'
}),
],
mode: 'development',
devServer: {
contentBase: resolve(__dirname, 'dist'),
compress: true,
port: 3000,
open: true,
hot: true
},
devtool: 'eval-source-map'
};
  • 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

  • 37

  • 38

  • 39

  • 40

  • 41

  • 42

  • 43

  • 44

  • 45

  • 46

  • 47

  • 48

  • 49

  • 50

  • 51

  • 52

  • 53

  • 54

  • 55

  • 56

  • 57

  • 58

  • 59

  • 60

  • 61

  • 62

  • 63

  • 64

  • 65

  • 66

  • 67

  • 68

  • 69

  • 70

  • 71

  • 72

  • 73

  • 74

  • 75

  • 76

  • 77

  • 78

  • 79

  • 80

  • 81

  • 82

  • 83

  • 84

  • 85

  • 86

  • 87

  • 88

  • 89

  • 90

  • 91

  • 92

  • 93

  • 94

  • 95

  • 96

  • 97

  • 98

  • 99

  • 100

  • 101

  • 102

  • 103

  • 104

  • 105

  • 106

  • 107

  • 108

  • 109

  • 110

  • 111

  • 112

  • 113

  • 114

  • 115

  • 116

  • 117

  • 118

  • 119

  • 120

  • 121

  • 122

  • 123

  • 124

  • 125

  • 126

  • 127

package.json 最后添加以下信息

"browserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
},
"eslintConfig": {
"extends": "airbnb-base",
"env": {
"browser": true
}
}
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

  • 17

  • 18

3.2、生产环境配置

安装依赖

npm install --save-dev style-loader css-loader less-loader less sass-loader node-sass
npm install --save-dev eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import
npm install --save-dev babel-loader @babel/core @babel/preset-env core-js
npm install --save-dev uglifyjs-webpack-plugin
npm install --save-dev url-loader file-loader html-loader
npm install --save-dev webpack-dev-server@3.11.0
npm install --save-dev thread-loader
npm install --save-dev workbox-webpack-plugin
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

具备功能

  • 压缩样式(css、less、sass),对样式进行了兼容性处理

  • 压缩脚本(js),对脚本进行了兼容性处理以及语法检查

  • 压缩页面(html),对页面进行了空白字符以及注释去除处理

  • 根据内容哈希缓存样式文件、脚本文件、其它资源文件

  • 添加了离线pwa访问技术

  • 添加了多线程打包,提高打包速度

  • 添加了source-map查错机制

webpack.config.js

const { resolve } = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin');
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');

// 定义 nodejs 环境变量:决定使用 browserslist 的哪个环境
process.env.NODE_ENV = 'production';

const MiniCssExtractPlugin_loader = {
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../' /* 修正把样式单独抽取到一个目录中出现的属性图片路径报错 */
}
};

module.exports = {
entry: './src/index.js',
output: {
filename: 'js/[name].[contenthash:10].js',/* 重新指定js输出文件路径 */
path: resolve(__dirname, 'dist')
},
module: {
rules: [
// 进行js语法检查
{
test: /.js$/i,
loader: 'eslint-loader',
options: {
// 自动修复eslint的错误
fix: true
}
},
{
oneOf: [
// 处理css样式
{
test: /.css$/i,
use: [MiniCssExtractPlugin_loader, 'css-loader', 'postcss-loader']
},
// 处理less样式
{
test: /.less$/i,
use: [MiniCssExtractPlugin_loader, 'css-loader', 'postcss-loader', 'less-loader']
},
// 处理sass样式
{
test: /.scss$/i,
use: [MiniCssExtractPlugin_loader, 'css-loader', 'postcss-loader', 'sass-loader']
},
// 进行js兼容性
{
test: /.js$/i,
exclude: /node_modules/,
use: [
/**
* 开启多进程打包
* 进程启动大概为600ms,进程通信也有开销
* 只有工作消耗时间比较长,才需要多进程打包
*/

{
loader: 'thread-loader',
options: {
workers: 2 // 开启2个进程进行打包,加快打包速度
}
},
{
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定core-js版本
corejs: { version: 3 },
// 指定兼容性做到哪个版本浏览器
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
],
// 开启babel缓存,第二次构建时,会读取之前的缓存
cacheDirectory: true
}
}
]
},
// 进行样式属性、脚本添加图像的处理
{
test: /.(png|jpg|jpeg|gif)$/i,
loader: 'url-loader',
options: {
limit: 10 * 1024,// 图片大小小于10kb,就会被base64处理
esModule: false,// 解决:关闭url-loader的es6模块化,使用commonjs解析
outputPath: 'images', // 将文件打包到哪里
name: '[hash].[ext]'// 给图片进行重命名
}
},
// 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
{
test: /.html$/i,
loader: 'html-loader'
},
// 打包字体资源
{
test: /.(eot|ttf|svg|woff|woff2)$/i,
loader: 'file-loader',
options: {
outputPath: 'fonts', // 将文件打包到哪里
name: '[hash].[ext]'// 给文件进行重命名
}
},
// 打包其它资源
{
exclude: /.(html|js|json|css|less|scss|png|jpg|jpeg|gif|eot|ttf|svg|woff|woff2)$/i,
loader: 'file-loader',
options: {
outputPath: 'others', // 将文件打包到哪里
name: '[hash].[ext]'// 给文件进行重命名
}
}
]
}
]
},
plugins: [
// 清理旧打包资源插件
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,// 清理多余空格
removeComments: true// 移除注释
}
}),
// 用于压缩css样式文件
new OptimizeCssAssetsWebpackPlugin(),
// 用于提取css样式文件
new MiniCssExtractPlugin({
filename: 'css/[name].[contenthash:10].css'
}),
// 用于压缩js脚本代码
new UglifyjsWebpackPlugin(),
// 渐进式网络开发应用程序,离线可访问
new WorkboxWebpackPlugin.GenerateSW({
/**
* 1. 帮助 serviceworker 快速启动
* 2. 删除旧的 serviceworker,生成一个 serviceworker 配置文件
*/

clientsClaim: true,
skipWaiting: true
})
],
/**
* 1. 可以将node_modules中代码单独打包一个chunk最终输出
* 2. 自动分析多入口chunk中,有没有公共的文件,如果有会打包成单独一个chunk
*/

optimization: {
splitChunks: {
chunks: 'all'
}
},
mode: 'production',
devtool: 'source-map'
};
  • 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

  • 37

  • 38

  • 39

  • 40

  • 41

  • 42

  • 43

  • 44

  • 45

  • 46

  • 47

  • 48

  • 49

  • 50

  • 51

  • 52

  • 53

  • 54

  • 55

  • 56

  • 57

  • 58

  • 59

  • 60

  • 61

  • 62

  • 63

  • 64

  • 65

  • 66

  • 67

  • 68

  • 69

  • 70

  • 71

  • 72

  • 73

  • 74

  • 75

  • 76

  • 77

  • 78

  • 79

  • 80

  • 81

  • 82

  • 83

  • 84

  • 85

  • 86

  • 87

  • 88

  • 89

  • 90

  • 91

  • 92

  • 93

  • 94

  • 95

  • 96

  • 97

  • 98

  • 99

  • 100

  • 101

  • 102

  • 103

  • 104

  • 105

  • 106

  • 107

  • 108

  • 109

  • 110

  • 111

  • 112

  • 113

  • 114

  • 115

  • 116

  • 117

  • 118

  • 119

  • 120

  • 121

  • 122

  • 123

  • 124

  • 125

  • 126

  • 127

  • 128

  • 129

  • 130

  • 131

  • 132

  • 133

  • 134

  • 135

  • 136

  • 137

  • 138

  • 139

  • 140

  • 141

  • 142

  • 143

  • 144

  • 145

  • 146

  • 147

  • 148

  • 149

  • 150

  • 151

  • 152

  • 153

  • 154

  • 155

  • 156

  • 157

  • 158

  • 159

  • 160

  • 161

  • 162

  • 163

  • 164

  • 165

  • 166

  • 167

  • 168

  • 169

  • 170

  • 171

  • 172

  • 173

  • 174

package.json 最后添加以下信息

"browserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
},
"eslintConfig": {
"extends": "airbnb-base",
"env": {
"browser": true
}
},
"sideEffects": [
"*.css",
"*.less",
"*.scss"
]
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

  • 17

  • 18

  • 19

  • 20

  • 21

  • 22

  • 23

index.js 最后添加以下信息

// 注册serviceWorker
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js').then(() => {
console.log('sw注册成功了~');
}).catch(() => {
console.log('sw注册失败了~');
});
});
}

------------END-----------

更多原创文章请扫描上面(微信内长按可识别二维码访问我的个人网站(https://www.xubingtao.cn),或者打开我的微信小程序: 可以评论以及在线客服反馈问题,其他平台小程序APP请访问:https://www.xubingtao.cn/?p=1675祝大家生活愉快!

以上是关于学习Webpack4这一篇就够了的主要内容,如果未能解决你的问题,请参考以下文章

[转]关于深度学习,看这一篇就够了

iOS动画详解(学习动画看这一篇就够了)

给力!Python配置文件,这一篇就够了!

go全总结学习go这一篇就够了

学习正则表达式入门,这一篇就够了,教学实例代码加解析

学习HTML5这一篇就够了