1.清除输出目录
clean-webpack-plugin
修改文件内容后自动删除输出目录
https://www.npmjs.com/package/clean-webpack-plugin
// webpack.config.js
const { CleanWebpackPlugin } = require('clean-webpack-plugin'); // 引入clean-webpack-plugin
module.exports = {
mode : "development",
devtool : "source-map",
output :{
filename : "[name]-[chunkhash:5].js"
},
plugins: [
new CleanWebpackPlugin(),
]
}
2.自动生成页面
html-webpack-plugin
通过模板生成html页面
https://www.npmjs.com/package/html-webpack-plugin
// webpack.config.js
const { CleanWebpackPlugin } = require("clean-webpack-plugin"); // 引入clean-webpack-plugin
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 引入html-webpack-plugin
module.exports = {
mode: "development",
devtool: "source-map",
entry: { // 两个入口文件
home: "./src/index.js",
a: "./src/a.js"
},
output: { // 出口
filename: "scripts/[name].[chunkhash:5].js"
},
plugins: [
new CleanWebpackPlugin(), // 清除输出目录 省去手动去删除
new HtmlWebpackPlugin({
// template 默认生成的HTML不能满足需求,可以提供自己的html模板
template: "./public/index.html", // 导出的html文件会按照此路径下的html模板进行处理
filename: "home.html", // 修改导出的html文件名称,默认是index.js
chunks: ["home"] // 只针对home模块进行处理
}),
//
new HtmlWebpackPlugin({
template: "./public/index.html", // 导出的html文件会按照此路径下的html模板进行处理
filename: "a.html", // 修改导出的html文件名称,默认是index.js
chunks: ["a"] // 只针对home模块进行处理
})
]
}
3.复制静态资源
copy-webpack-plugin
通常用于复制静态图片
https://www.npmjs.com/package/copy-webpack-plugin
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
mode: "development",
devtool: "source-map",
output: {
filename: "scripts/[name].[chunkhash:5].js"
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: "./public/index.html"
}),
new CopyPlugin([
{ from: "./public", to: "./" }, //从public目录下复制静态资源默认粘贴到dist目录下
{}
])
]
}
4.开发服务器
为了方便开发webpack官方制作的一个库:webpack-dev-server
它既不是plugin
也不是loader
https://www.npmjs.com/package/webpack-dev-server
用法:
- 安装:
npm install webpack-dev-server --save-dev
- 执行
npx webpack-dev-server
命令 - 通常也会在脚本里进行配置
"scripts": { "dev": "webpack-dev-server" }
在运行时使用命令npm run dev
webpack-dev-server
命令几乎支持所有的webpack命令参数,如--config
、-env
等等,你可以把它当作webpack命令使用
这个命令是专门为开发阶段服务的,真正部署的时候还是得使用webpack命令
当我们执行webpack-dev-server
命令后,它做了以下操作:
- 内部执行webpack命令,传递命令参数
- 开启watch
- 注册hooks:类似于plugin,webpack-dev-server会向webpack中注册一些钩子函数,主要功能如下:
- 将资源列表(aseets)保存起来
- 禁止webpack输出文件
- 用express开启一个服务器,监听某个端口,当请求到达后,根据请求的路径,给予相应的资源内容
常用配置
port
:配置监听端口open
: (true) 会自动打开页面proxy
:配置代理,常用于跨域访问stats
:配置控制台输出内容
针对webpack-dev-server
的配置,参考:https://www.webpackjs.com/configuration/dev-server/
举个栗子瞅一瞅:
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
mode : "development",
devtool : "source-map",
output :{
filename : "[name]-[chunkhash:5].js"
},
plugins: [
new CleanWebpackPlugin(), // 配置清除输出目录
new HtmlWebpackPlugin({ // 根据模板(template)自动生成页面
template: './public/index.html',
}),
new CopyPlugin([ //复制静态资源 (图片等)
{ from: './public', to: '' }
]),
],
// 开发服务器配置
devServer: {
port :8000, // 设置端口号
open :true, //会自动打开页面
proxy :{ // 设置代理 ,解决跨域问题
"/api":{ // 正则匹配/api"字段
target :"http://open.duyiedu.com", // 请求的地址
changeOrigin: true //更改请求头中的host和origin 这样才能够访问
}
}
},
stats: { // 配置控制台输出内容
modules: false, // 输出内容会变得简洁
colors: true // 会有花里胡哨的颜色
}
}
5.普通文件处理
file-loader
: 生成依赖的文件到输出目录,然后将模块文件设置为:导出一个路径\
https://www.npmjs.com/package/file-loader
//file-loader
function loader(source){
// source:文件内容(图片内容 buffer)
// 1. 生成一个具有相同文件内容的文件到输出目录
// 2. 返回一段代码 export default "文件名"
}
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
mode: "development",
devtool: "source-map",
output: {
filename: "scripts/[name].[chunkhash:5].js"
},
module: { // 配置loader
rules: [
{
test: /\.(png)|(gif)|(jpg)$/, // 正则匹配 以后缀名png,gif,jpg结尾的文件 要先经过loader处理
use: [{
loader: "file-loader",
options: { // 配置参数
name: "imgs/[name].[hash:5].[ext]" // 配置动态的名字
}
}]
}
]
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: "./public/index.html"
})
],
devServer: {
open: true
},
stats: {
modules: false,
colors: true
}
}
url-loader
将依赖的文件转换为:导出一个base64格式的字符串
https://www.npmjs.com/package/url-loader
//url-loader
function loader(source){
// source:文件内容(图片内容 buffer)
// 1. 根据buffer生成一个base64编码
// 2. 返回一段代码 export default "base64编码"
}
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
mode: "development",
devtool: "source-map",
output: {
filename: "scripts/[name].[chunkhash:5].js"
},
module: { // 配置loader
rules: [
{
test: /\.(png)|(gif)|(jpg)$/,
use: [{
loader: "url-loader",
options: {
// limit: false //不限制任何大小,所有经过loader的文件进行base64编码返回
limit: 10 * 1024, //只要文件不超过 100*1024 字节,则使用base64编码,否则,交给file-loader进行处理
name: "imgs/[name].[hash:5].[ext]"
}
}]
}
]
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: "./public/index.html"
})
],
devServer: {
open: true
},
stats: {
modules: false,
colors: true
}
}
6.解决路径问题
在使用file-loader
或url-loader
时,可能会遇到一个非常有趣的问题
比如,通过webpack打包的目录结构如下:
dist
|—— img
|—— a.png #file-loader生成的文件
|—— scripts
|—— main.js #export default "img/a.png"
|—— html
|—— index.html #<script src="../scripts/main.js" ></script>
这种问题发生的根本原因:模块中的路径来自于某个loader或plugin,当产生路径时,loader或plugin只有相对于dist目录的路径,并不知道该路径将在哪个资源中使用,从而无法确定最终正确的路径
面对这种情况,需要依靠webpack的配置publicPath
解决
7.webpack内置插件
所有的webpack内置插件都作为webpack的静态属性存在的,使用下面的方式即可创建一个插件对象
const webpack = require("webpack")
new webpack.插件名(options)
DefinePlugin
全局常量定义插件,使用该插件通常定义一些常量值,例如:
new webpack.DefinePlugin({
PI: `Math.PI`, // PI = Math.PI
VERSION: `"1.0.0"`, // VERSION = "1.0.0"
DOMAIN: JSON.stringify("duyi.com")
})
这样一来,在源码中,我们可以直接使用插件中提供的常量,当webpack编译完成后,会自动替换为常量的值
BannerPlugin
它可以为每个chunk生成的文件头部添加一行注释,一般用于添加作者、公司、版权等信息
new webpack.BannerPlugin({
banner: `
hash:[hash]
chunkhash:[chunkhash]
name:[name]
author:Ryx
corporation:duyi
`
})
ProvidePlugin
自动加载模块,而不必到处 import 或 require
new webpack.ProvidePlugin({
$: 'jquery',
_: 'lodash'
})
然后在我们任意源码中:
$('#item'); // <= 起作用
_.drop([1, 2, 3], 2); // <= 起作用