五、处理图片
file-loader
- 通过src使用图片, 有三种方式
// ===========================1===========================
// image.js
// webpack 5以后require返回的是一个对象
img.src = require('../img/1-icon.png').default
// webpack.config.js
{
test:/\.(png|svg|gif|jpe?g)$/,
use: [ 'file-loader' ]
}
// ===========================2===========================
// image.js
img.src = require('../img/1-icon.png')
// webpack.config.js
{
test:/\.(png|svg|gif|jpe?g)$/,
use: [
{
loader: 'file-loader',
options: {
// 导出的内容是否转化为esMoudle
esModule: false
}
}
]
}
// ===========================3===========================
// image.js
import imgSrc from '../img/1-icon.png'
img.src = imgSrc
// webpack.config.js
{
test:/\.(png|svg|gif|jpe?g)$/,
use: [ 'file-loader' ]
}
- 通过url使用图片,
注意要关闭 css-loader转为esModule的功能
。
// bgImg.css
.bgImg {
background-image: url('../img/2-message.jpg');
}
// image.js
bgImg.className = 'bgImg'
// css-loader 看到url,或转成require处理
{
test: /\.less$/,
use: ['style-loader', {
loader: 'css-loader',
options: {
// 代表向前找一个loader处理
importLoaders: 1,
esModule: false
}
}, 'postcss-loader', 'less-loader']
}
- 设置文件名称输出
{
test:/\.(png|svg|gif|jpe?g)$/,
use: [
{
loader: 'file-loader',
options: {
name: 'img/[name].[hash:6].[ext]',
// outputPath: 'img'
}
}
]
}
常见属性配置:
[ext]:扩展名
[name]:文件名
[hash]:文件内容md4
[contentHash]:文件hash, 和hash一样
[hash:<length>]:限定长度的hash
[path]:路径
url-loader
yarn add url-loader --dev
url-loader 和 file-loader类似,只是url-loader默认使用base64加载图片。
优点可以减少一次请求的次数, 但是文件大的时候,一次性请求就会很慢。
不过url-loader可以通过limit来控制加载方式。
{
test:/\.(png|svg|gif|jpe?g)$/,
use: [
{
loader: 'url-loader',
options: {
name: 'img/[name].[hash:6].[ext]',
// 可以限制小于这个大小的才使用base64
limit: 20 * 1024
}
}
]
}
asset module
- 处理图片
a. asset/resource (类似file-loader)
{
test:/\.(png|svg|gif|jpe?g)$/,
type: 'asset/resource'
}
// 1.图片字体都放在一个地方,不建议
// assetModuleFilename: 'img/[name].[hash:4][ext]'
// 2.单独配置
{
test:/\.(png|svg|gif|jpe?g)$/,
type: 'asset/resource',
generator: {
filename: 'img/[name].[hash:4][ext]'
}
}
b. asset/inline (类似url-loader)
// 全部转成base64
// {
// test:/\.(png|svg|gif|jpe?g)$/,
// type: 'asset/inline'
// }
// 根据条件转成base64
{
test:/\.(png|svg|gif|jpe?g)$/,
type: 'asset',
generator: {
filename: 'img/[name].[hash:4][ext]'
},
parser: {
dataUrlCondition: {
maxSize: 20 * 1024
}
}
}
c. asset/source (raw-loader 不常用)
- 处理图标字体
// font.js
const oSpan = document.createElement('span')
oSpan.className = 'iconfont icon-linggan lg-icon'
oEle.appendChild(oSpan)
// webpack.config.js
{
test: /\.(ttf|woff2?)$/,
type: 'asset/resource',
generator: {
filename: 'font/[name].[hash:4][ext]'
}
}
六、插件使用
- loader: 负责转换 特定类型 。
- plugin: 可以做更多事情,每个插件都是一个类。
plugin是通过钩子机制实现, 钩子必须是一个函数或者一个包含apply方法的对象。
- clean-webpack-plugin 清除目标目录
yarn add clean-webpack-plugin --dev
// webpack.config.js
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
plugins: [
new CleanWebpackPlugin()
]
- html-webpack-plugin 生成默认html
yarn add html-webpack-plugin --dev
默认有个ejs模板,我们也可以自定义模板,新建public/index.html
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
const HtmlWebpackPlugin = require('html-webpack-plugin')
plugins: [
new CleanWebpackPlugin(),
// 可以定义多个HtmlWebpackPlugin插件用于生成多个html文件
new HtmlWebpackPlugin({
title: 'jerry-webpack-plugin',
template: './public/index.html'
})
]
- DefinePlugin定义常量( webpack自带)
const { DefinePlugin } = require('webpack')
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'jerry-webpack-plugin',
template: './public/index.html'
}),
new DefinePlugin({
// 定义常量
new DefinePlugin({
// 这里要添加双引号,DefinePlugin会把数据原封不动返回
BASE_URL: '"./"'
})
]
- copy-webpack-plugin拷贝资源
有些资源只需要拷贝,不需要打包。
yarn add copy-webpack-plugin --dev
const CopyWebpackPlugin = require('copy-webpack-plugin')
new CopyWebpackPlugin({
patterns: [
{
// 省略了to,to默认output.path的文件夹
from: 'public',
globOptions: {
// index.html上面已经操作过了,需要排除。
// 默认从项目根找, **代表从当前目录找
ignore: ['**/index.html']
}
}
]
})
七、babel
- babel负责处理JS兼容,比如JSX、TS、ES6+。
和postcss 很像, 不过postcss主要处理是css兼容。
-
命令行使用
yarn add @babel/core @babel/cli @babel/preset-env --dev
@babel/core:核心模块
@babel/cli:命令行使用babel
@babel/preset-env:预设
npm babel src --out-dir build --presets=@babel/preset-env
-
babel-loader, 同样依据.browserslistrc里面配置
yarn add babel-loader --dev
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
// presets: [
// [
// '@babel/preset-env',
// // 这里的配置为准
// {targets: 'chrome 91'}
// ]
// ],
}
}
]
}
- 使用配置文件
使用 babel.config.js(json cjs mjs), 一般就是.js后缀。
babel 7之前使用babelrc.json(js)类似配置文件
// webpack.config.js
{
test: /\.js$/,
use: [ 'babel-loader' ]
}
// babel.config.js
module.exports = {
presets: ['@babel/preset-env']
}
八、polyfill
- webpack 4自动包含polyfill,打包产出比较大, webpack 5 就移出去了。
preset-env对于新语法不能全部转换,所以需要polyfill来打补丁。
yarn add core-js regenerator-runtime
babel-polyfill进行了拆分,不建议直接使用了,
// babel.config.js
module.exports = {
presets: [
[
'@babel/preset-env',
{
// false: 不对当前的JS处理做 polyfill 的填充
// usage: 依据用户源代码当中所使用到的新语法进行填充
// entry: 依据我们当前筛选出来的浏览器决定填充什么
// 使用entry,需要在使用的地方导入头文件
// import "core-js/stable";
// import "regenerator-runtime/runtime"
useBuiltIns: 'usage',
// 默认版本2
corejs: 3
}
]
]
}
// webpack.config.js
{
test: /\.js$/,
// 防止node_modules中的库也使用了babel,导致干扰
exclude: /node_modules/,
use: [ 'babel-loader' ]
}
网友评论