共计 2379 个字符,预计需要花费 6 分钟才能阅读完成。
目录
上节:css 代码分割
目录:
先改一下 src/index.js:
import _ from 'lodash';
const root = document.getElementById('root');
root.innerText = _.join(['hello', 'webpack'], '-');
现在写一个简单的 loader,将所有的 webpack 替换成其它内容,内容可通过 options 配置。
在根目录新建 loaders/replace-loader.js。
loaders/replace-loader.js:
const {getOptions} = require('loader-utils');
module.exports = function(source) {
/*
this 指向 webpack
source:打包后的文件内容
this.query options 参数
*/
const options = getOptions(this) || {};
// 返回处理后的结果,相当于是打包拦截器
return source.replace('webpack', options.name || 'Madao');
}
source 是打包后生成的文件,options 可以拿到配置参数, 这个 loader 会将所有 webpack 替换成 options.name 的内容,如果没指定 options.name, 就替换成 Madao.
然后引用这个 loader, 修改 webpack/webpack.base.js:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {resolve} = require('path');
module.exports = {
entry: './src/index.js',
output: {path: resolve(__dirname, '../bundles')
},
// 注册 loader
resolveLoader: {
// loader 查找顺序,从左到右
modules: ['node_modules', './loaders/']
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
// 先不传 options
use: ['replace-loader', 'babel-loader']
}, {test: /\.(gif|jpg|jpeg|png|svg)$/,
use: ['url-loader']
}]
},
plugins: [
new HtmlWebpackPlugin({template: './index.html'})
]
};
安装 loader 工具库:npm i loader-utils -D
然后 npm run build, 打开 bundles 下的 main.[contenthash].js 文件,应该可以搜索到 Madao:
然后我们自己传一个配置参数,修改 webpack/webpack.base.js:
// 省略
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'replace-loader',
options: {name: '史珍香'}
}, 'babel-loader']
}, {test: /\.(gif|jpg|jpeg|png|svg)$/,
use: ['url-loader']
}]
},
// 省略
再次 npm run build,可以看到 webpack 就换成了 ’ 史珍香 ’:
一个简单的 loader 就实现了。现在这个 replace-loader 只返回了替换后的内容,如果还想返回点其它内容,就得再改写下。
loaders/replace-loader.js:
const {getOptions} = require('loader-utils');
module.exports = function(source) {
/*
this 指向 webpack
source:打包后的文件内容
this.query options 参数
*/
const options = getOptions(this) || {};
// 返回处理后的结果,相当于是打包拦截器
// return source.replace('webpack', options.name || 'Madao');
const result = source.replace('webpack', options.name || 'Madao');
/*
this.callback(
err: Error | null, // error 信息
content: string | Buffer, // 要返回的内容
sourceMap?: SourceMap, // source-map
meta?: any // 会被 webpack 忽略,可以是任何东西(例如一些元数据)。);
*/
// 如果只传这两个参数,效果同上
this.callback(null, result);
}
如果转换过程中有什么异步操作,还可以返回异步 loader,这里用定时器模拟下异步
loaders/replace-loader.js:
module.exports = function(source) {const callback = this.async();
setTimeout(() => { // 直接影响打包时间
const options = getOptions(this);
const result = source.replace('webpack', options.name || 'Madao');
callback(null, result); // 这里实际还是调用了 this.callback()}, 3000);
}
this 对象上还挂了很多属性,具体参考:https://webpack.js.org/api/lo…
下节:编写一个 plugin