配套资料,免费下载
链接: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
确定即可。
注意:本教程所采用的是 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
注意:是否使用
--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
现在,我们将创建以下目录结构、文件和内容:
创建一个src目录,目录中创建一个 index.js ,文件内容如下:
// 导入刚才下载的jQuery库
import $ from 'jquery';
// 为h1大标题美化样式
$('h1').css('color','red');
创建一个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>
现在,我们将会打包所有脚本,执行 npx webpack
,会将我们的脚本 src/index.js
作为入口起点(默认),也会将 dist/main.js
作为输出路径(默认)。Node 8.2/npm 5.2.0 以上版本提供的 npx 命令,可以运行在初次安装的 webpack package 中的 webpack 二进制文件:
npx webpack
在浏览器中打开 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'
};
现在,让我们通过新的配置文件再次执行命令重新进行构建:
npx webpack --config webpack.config.js
注意:如果
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"
}
}
现在,可以使用 npm run build
命令,来替代我们之前使用的 npx
命令。
现在运行 npm run build
命令,然后看看你的脚本别名是否正常运行:
npm run build
在浏览器中打开 dist
目录下的 index.html
,如果一切正常,你应该能看到以下红色文本:'Hello,Webpack!'
。
现在由 webpack 将我们自己写的 index.js
和 jQuery
打包到了 dist/main.js
,然后由我们手写的 dist/index.html
进行引用,如果你不想写 index.html
接下来介绍一个插件,可以大大解放你的双手。
npm install --save-dev html-webpack-plugin
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'
};
这将会产生一个包含以下内容的文件 dist/index.html
:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>webpack App</title>
</head>
<body>
<script src="main.js"></script>
</body>
</html>
现在运行 npm run build
命令:
npm run build
在浏览器中打开 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'
};
当然了,我们也需要在 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>
现在运行 npm run build
命令:
npm run build
在浏览器中打开 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
第二步:引入处理器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'
};
第三步:验证处理器是否工作
在 src
目录下,创建 style.css
,文件内容如下:
h2{
color: blueviolet;}
在 src
目录下,创建 style.less
,文件内容如下:
h3{color: pink;}
在 src
目录下,创建 style.scss
,文件内容如下:
h4{color: orange;}
在 src
目录下,修改 index.js
,文件内容如下:
// 导入刚才下载的jQuery库
import $ from 'jquery';
// 导入css样式
import './style.css';
// 导入less样式
import './style.less';
// 导入sass样式
import './style.scss';
// 为h1大标题美化样式
$('h1').css('color', 'red');
在 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>
第四步:测试输出效果
运行命令 npm run build
重新进行打包,然后打开 dist/index.html
,如果一切正常,那么您的页面效果看起来应该如下:
现在我们发现 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
第二步:引入处理器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'
};
第三步:在 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"
]
}
}
第四步:测试输出效果
运行命令 npm run build
重新进行打包,然后打开 dist/index.html
,如果一切正常,那么您的页面效果看起来应该如下:
而您的样式文件看起来应该是这样的:
做到这里,你可以说已经掌握了处理css、less、sass的核心知识了,我们注意一下 dist
目录,随着代码的修改,以及文件的增多,有些文件是旧文件,我们可以在每一次打包之前手动删除一次,但是太麻烦了,所以这里推荐一款清理插件,它会在每次打包发布之前,都会将目标生成目录进行清理,因此,我们需要安装一款插件:
npm install --save-dev clean-webpack-plugin
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'
};
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
第二步:引入处理器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'
};
第三步:在 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
}
}
}
第四步:测试输出效果
运行命令 npm run build
重新进行打包,你应该是运行失败的,因为语法检查提示:jquery不应该被安装到开发依赖中,这里我们用最简单的方法解决,注释掉,index.js
中所有用到jquery的部分,然后就行了。
重新运行命令 npm run build
重新进行打包,然后打开 dist/index.html
,如果一切正常,那么您的页面效果看起来应该如下:
2.3、处理图像资源
除了样式和脚本资源需要处理,我们还得处理图像资源,常见的图像包括以下几种出现方式:
- 包括样式中background属性中的url图片
- 使用脚本动态添加的img图片
- 直接写在页面中的img图片
您应该找一张你所喜欢的图片放到src中,以方便后边的演示,在这里名称默认为“myimg.png”
第一步:安装处理器loader
npm install --save-dev url-loader file-loader html-loader
第二步:引用处理器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'
};
第三步:验证处理器是否工作
在 src
目录下,修改 style.css
,文件内容如下:
h2 {
width: 151px;
height: 151px;
background: url('./myimg.png') no-repeat;
}
在 src
目录下,修改 style.less
,文件内容如下:
h3 {
width: 151px;
height: 151px;
background: url('./myimg.png') no-repeat;
}
在 src
目录下,修改 style.scss
,文件内容如下:
h4 {
width: 151px;
height: 151px;
background: url('./myimg.png') no-repeat;
}
在 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);
在 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>
第四步:测试输出效果
运行命令 npm run build
重新进行打包,然后打开 dist/index.html
,如果一切正常,那么您的页面效果看起来应该如下:
2.4、处理字体资源
现在,我们准备了一个fonts
文件夹(配套资料中有),里边有样式也有各种字体文件,我们现在需要对这些资源进行管理,具体怎么做,请往下看。

第一步:安装处理器loader
file-loader在上一步的时候已经安装过了,这里就不用安装了
第二步:引用处理器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'
};
第三步:验证处理器是否工作
在 src
目录下,修改 index.js
,文件内容如下:
import './style.css'; // 导入css样式
import './style.less'; // 导入less样式
import './style.scss'; // 导入sass样式
import './fonts/iconfont.css'; // 导入字体资源
在 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>
第四步:测试输出效果
运行命令 npm run build
重新进行打包,然后打开 dist/index.html
,如果一切正常,那么您的页面效果看起来应该如下:
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]'// 给文件进行重命名
}
}
2.6、处理页面资源
我们需要对页面资源进行去掉多余空格、注释,进行压缩处理,只需要修改一处配置即可。
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,// 清理多余空格
removeComments: true// 移除注释
}
}),
运行 npm run build
,如果顺利,你将会看到以下效果:
2.7、配置开发服务
我们每次写完代码,都得需要手动打包,然后再打开 dist/index.html
,即使有一点错误,重新修改也需要打包,很不方便有没有,还有就是有一些技术是需要服务器才能运行,并不支持本地直接打开 html
代码运行,遇到这种问题,我们也会束手无策,所以,我们需要一款运行在服务器端的插件或者软件,幸好,webpack 早已想到,如何使用,请看下边:
npm install --save-dev webpack-dev-server@3.11.0
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
}
};
运行 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
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'
};
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
}
}
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
具备功能
- 压缩样式(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'
};
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"
]
index.js 最后添加以下信息
// 注册serviceWorker
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js').then(() => {
console.log('sw注册成功了~');
}).catch(() => {
console.log('sw注册失败了~');
});
});
}
转载:https://blog.csdn.net/qq_38490457/article/details/109876123