Webpack Plugins Loader
在上一章中使用了webpack的entry
和output
配置,这两个选项是Webpack构建过程中的基础配置。entry
指定了Webpack打包的入口文件,output
则指定了打包后的输出目录和文件名。
在这一章,将使用plugins和loader,来扩展Webpack的功能和优化前端项目的构建过程。
Plugins
Plugins是webpack的重要特性之一,可以在项目构建中执行额外的任务和操作,比如在上一章中我们只是体验了webpack打包js文件,而使用plugins能在打包之后自动生成html并且把打包好的js自动引入到html中。plugins还可以提取css样式、压缩代码、设置环境变量等等,让我们能否轻松的定制Webpack的构建行为,满足不同项目的需求。
使用webpack每次打包之后,Webpack都会生成一个新的JS文件,并且旧的文件会保留在输出目录中。为了解决这个问题,我们可以借助Webpack的clean-webpack-plugin
插件,它能够在每次打包之前自动清理输出目录,删除旧的文件,我们先安装所需要的插件:
npm install -D clean-webpack-plugin
安装完成后需要在webpack.config.js中引入并使用:
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
entry: './src/index.js',
output: {
filename: 'main_[contenthash].js',
path: path.join(__dirname, 'dist')
},
plugins: [
new CleanWebpackPlugin()
],
注意,plugins中存放的是插件实例数组,所以我们在使用时需要使用nwe
关键字来调用插件的构造函数。
这是现在的dist文件:
现在我们再执行打包命令试试有什么效果
可以看到,在我们安装clean-webpack-plugin之后,再次打包会自动清空已经过时的文件,节省了手动操作的步骤。但是现在我们的项目只能生成一个js,要如何引入到html中呢?手动创建显然是不可能的,特别是现在配置中打包的js是带有哈希字符的,文件内容变动之后文件名也会改变,所以这时候就轮到html-webpack-plugin
登场了。
和clean插件一样,我们要先下载:
npm install -D html-webpack-plugin
安装完成之后也需要在webpack.config.js中引入,但是和clean插件不同的是,不需要结构:
在这里传入了一个配置,不压缩tml,方便我们查看案例
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/index.js',
output: {
filename: 'main_[contenthash].js',
path: path.join(__dirname, 'dist')
},
plugins: [
new HtmlWebpackPlugin({
minify: {
collapseWhitespace: false, // 压缩空白字符
removeComments: false, // 去除注释
removeRedundantAttributes: false, // 去除多余的属性
removeScriptTypeAttributes: false, // 去除type="text/javascript"
removeStyleLinkTypeAttributes: false, // 去除type="text/css"
useShortDoctype: false // 使用短的文档类型声明
}
}),
new CleanWebpackPlugin()
],
保存后再次打包测试;
可以看到这次在dist目录中除了js外还多了一个index.html文件,并且文件中已经自动引入了main_f4524ad7c8af43b5abda.js
自定义模板
现在我们可以添加一些代码,然后重新打包后到浏览器中看看效果
在src/index.js中添加代码:
function createHelloWorldDiv() {
// 创建一个div元素
const divElement = document.createElement("div");
// 设置div的内容为"Hello World"
divElement.textContent = "Hello World";
// 设置样式
divElement.style.fontWeight = "bold";
divElement.style.textAlign = "center";
divElement.style.paddingTop = "40px";
divElement.style.fontSize = "24px";
// 将div添加到#app元素中
const appElement = document.getElementById("app");
appElement.appendChild(divElement);
}
// 调用函数
createHelloWorldDiv();
在这段代码中我们在页面查找了id为app的元素,但是在刚刚生成的html中是不存在#app元素,这个时候我们就需要使用html-webpack-plugin的配置项,自定义html模版了。我们先在src目录下创建一个index.html,并写上基础的html模板,添加上#app的元素,最后在webpck.config.js中添加配置:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>LESSON</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
</head>
<body>
<div id="app"></div>
</body>
</html>
template: './src/index.html',
配置完成后就可以打包了,最后把打包完成的html运行到浏览器中查看效果
Loader
Loader则是用于处理特定类型文件的转换器,webpack默认只能处理js文件和json文件,但是通过安装loader我们可以处理其他类型的文件比如CSS、SCSS、图片、字体等等,例如使用css-loader
和style-loader
,我们可以把css文件转换为JavaScript模块,并且将样式添加到页面中。
安装css-loader和style-loader
npm install -D css-loader style-loader
把下载好的插件写进到webpack.config.js的配置module中和plugins同级:
这里需要注意的是module中使用的配置是需要写到rules数组中,每一个对象就是一个配置,use是设置要使用的Loader。第二项加载图片的功能是webpack自带的,只需要设置需要打包的资源类型,不用使用其他Loader
plugins:...
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"]
},
{ //
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource'
},
],
}
在下面的案例中添加一个css文件和一张图片到src文件夹中并修改index.js:
import './index.css'
import htmlImage from './html5.png'
function createHelloWorldDiv() {
const divElement = document.createElement("div");
const imgElement = document.createElement("img");
divElement.textContent = "Hello World3";
divElement.classList.add("hello-world");
imgElement.src = htmlImage
imgElement.classList.add("image");
const appElement = document.getElementById("app");
appElement.appendChild(divElement);
appElement.appendChild(imgElement);
}
createHelloWorldDiv();
测试的打包效果:
最后附带一些常用的插件:
plugins:
MiniCssExtractPlugin: 将CSS从JS文件中提取出来,生成独立的CSS文件。
OptimizeCSSAssetsPlugin: 压缩和优化提取出来的CSS文件。
CleanWebpackPlugin: 在每次构建前清理输出目录,确保输出目录是最新的。
CopyWebpackPlugin: 将静态资源文件从源目录复制到输出目录,例如图片、字体等文件。
DefinePlugin: 在代码中创建全局常量,用于区分开发和发布版本的配置。
UglifyJsPlugin: 压缩和混淆JavaScript代码,在生产环境中使用。
HtmlWebpackPlugin: 将JavaScript和CSS自动注入到HTML模板中,并可以配置生成的HTML文件的选项。
ProvidePlugin: 自动加载模块,允许在代码中直接使用某些模块而无需显式导入。
EnvironmentPlugin: 将环境变量注入到代码中,方便在代码中使用环境变量。
ImageminWebpackPlugin: 优化图片,减小图片文件大小,提高加载速度。
BundleAnalyzerPlugin: 生成可视化的分析报告,展示打包文件中各个模块的大小。
ESLintPlugin: 集成ESLint,用于在构建过程中检查和修复JavaScript代码的语法和风格问题。
StylelintWebpackPlugin: 集成Stylelint,用于在构建过程中检查和修复CSS代码的语法和风格问题。
CompressionWebpackPlugin: 在生产环境中使用gzip或Brotli压缩生成的输出文件,减小文件大小。
FriendlyErrorsWebpackPlugin: 使构建错误和警告更友好和易读。
HardSourceWebpackPlugin: 缓存Webpack构建的中间产物,加快二次构建速度。
PreactRefreshWebpackPlugin: 支持在Preact项目中使用HMR。
FaviconsWebpackPlugin: 自动生成各种平台的favicon图标。
WebpackBar: 可以在终端展示Webpack构建的进度条。
WorkboxWebpackPlugin: 集成Google的Workbox库,用于生成Service Worker。
loader:
babel-loader:用于将ES6+代码转换为ES5代码,以便在旧版浏览器中运行。
css-loader:用于处理CSS文件,允许你在JavaScript中导入CSS文件,并处理其中的import和url()等。
style-loader:用于将CSS样式注入到HTML页面中,通常与css-loader一起使用。
sass-loader:用于将Sass/SCSS文件转换为CSS文件。
less-loader:用于将Less文件转换为CSS文件。
postcss-loader:用于后处理CSS,例如添加浏览器前缀、压缩等。
file-loader:用于处理文件资源,将文件复制到输出目录,并返回文件路径。
url-loader:类似于file-loader,但在文件大小小于指定限制时,返回Data URL,而不是复制文件。
image-webpack-loader:用于优化和压缩图片文件。
svg-url-loader:用于将SVG文件转换为DataURL。
html-loader:用于处理HTML文件,可以处理其中的img标签,将图片转换为DataURL。
json-loader:用于加载JSON文件。
raw-loader:用于将文件内容作为字符串导入,而不进行解析和转换。
eslint-loader:用于在构建过程中对JavaScript代码进行静态检查。
stylelint-webpack-plugin:用于在构建过程中对CSS代码进行静态检查。