意在梳理
loader 是一个函数,处理非 JS 语法的资源
使用
对不同类型的文件使用不同 loader
module.exports = {
module: {
rules: [
{
test: /\.(a|b|c)$/, // 正则匹配文件
use: 'some-loader', // 使用 loader
options: {
// 一些 loader 相关配置
}
}
]
}
}
编写 mini-loader
实践,练手✋
raw-loader
- 识别 txt 文件并输出为 JS 理解的语法
- 转化要求
a.txt
=>module.exports / export default = 'a content'
schema.json 校验 options 的参数格式
{
"type": "object",
"properties": {
"esModule": {
"type": "boolean"
}
},
"additionalProperties": true
}
raw-loader.js
module.exports = function (content, mp, meta) {
const options = this.getOptions(schema)
const callback = this.async()
// 将字符串转为标准格式的json字符串,内部的换行符和引号会被转移
const transformContent = JSON.stringify(content)
.replace(/\u2028/g, '\\u2028')
.replace(/\u2029/g, '\\u2029')
const isEsModule =
typeof options.esModule !== 'undefined' ? options.esModule : true
callback(
null,
`
${isEsModule ? 'export default' : 'module.exports ='}
${transformContent};
`,
)
}
webpack.config.js
{
test: /\.txt$/,
use: [
{
loader: 'raw-loader',
options: {
esModule: true,
},
},
],
},
file-loader
- 识别 图片、视频、字体资源等文件
- 根据 options.name 给文件重命名
- 将重命名的文件输出至打包后的 outputPath 目录下
schema.json 校验 options 的参数格式
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"outputPath": {
"type": "string"
}
},
"additionalProperties": true
}
file-loader.js
const path = require('path')
const { interpolateName } = require('loader-utils')
module.exports = function (content, map, meta) {
const options = this.getOptions(schema)
// test.jpg -> [name]-[hash].[ext] -> test-xxxx.jpg
const url = interpolateName(this, options.name, {
content,
})
// 打包的目的地址
const outputPath = path.posix.join(options.outputPath, url)
this.emitFile(outputPath, content)
// 填入 src 的 publicPath
// 在浏览器中能够访问到的构建文件的路径 __webpack_public_path__,等于 output.publicPath
const publicPath = `__webpack_public_path__ + ${JSON.stringify(outputPath)}`
const isEsModule = typeof esModule !== 'undefined' ? esModule : true
return `${isEsModule ? 'export default' : 'module.exports ='} ${publicPath};`
}
// !!!
module.exports.raw = true
webpack.config.js
{
test: /\.(jpg|png)$/,
use: [
{
loader: 'file-loader',
options: {
outputPath: 'images/',
name: '[name]-[contentHash].[ext]',
},
},
],
},