假设你有一个需求,要把代码里的ad-button替换为div,因为是mi看ad-button不爽。
这还不简单么,webpack有那么多成熟的plugins和loaders,本身我对webpack也只是略知一二,随便一搜网上的解决方案,
string-replace-loader
string-replace-webpack-plugin
自定义loader:replace-str-loader
自定义plugin
把能搜到的方案都试了一遍,发现竟无一种方法可行。由于没有系统的学过webpack,也没有从头到尾把枯燥的webpack文档从头到尾翻一遍的觉悟。这种状态持续了一周,我发现不行,这样下去我根本不可能找到解决方案,因为好像没有别人有过在快应用webpack统一替换字符串的需求,所以不可能搜到对应的解决办法,我必须得再深入些,我坚定了一个想法:突破口一定是loader
通过自定义plugin,我发现快应用打包里有2个步骤
const myPlugin = 'myPlugin'
module.exports = class MyPlugin {
apply(compiler) {
compiler.hooks.compilation.tap(myPlugin, (compilation) => {
console.log(compilation.options.module.rules);
})
}
}
执行npm run build后得出以下打印
[
{
test: /\.js$/,
use: [
'D:\\code\\quick\\qbb\\node_modules\\@hap-toolkit\\packager\\lib\\loader\\module-loader.js',
[Object]
]
},
{
test: /\.(ux|mix)$/,
use: {
loader: 'D:\\code\\quick\\qbb\\node_modules\\@hap-toolkit\\dsl-xvm\\lib\\loader\\ux-loader.js'
}
}
]
一个是对代码中js的解析,一个是对快应用页面的解析,mix大概是mixins的简写,项目没用到先不管。而ad-button想要替换为div,那肯定是对ux的解析下手,要么在ux-loader前解析,要么在ux-loader处理完之后替换,经测试,必须要在ux-loader之前替换。随后查阅了webpack loader顺序相关的文章,最终实现如下
loader/index.js(自定义loader)
module.exports = function (source) {
// 获取webpack配置项loader的options
const options = this.query;
// source是每个页面ux文件的源码
const result = source.replace(/ad-button/g, options.name);
return result;
}
quickapp.config.js(快应用这可被webpack识别的配置文件),插件代码只是定位问题用的,删掉也不影响代码执行
const myPlugin = require('./plugin/myPlugin')
module.exports = {
plugins: [
new myPlugin()
],
module: {
rules: [
{
test: /\.ux$/,
// 设置模式为前置(pre),通过反复测试得出必须要是pre,
// 否则loader/index.js中拿到的source是被ux-loader编译过的,找不到需要替换的字符串了
enforce: 'pre',
use: [
{
loader: './loaders/index.js',
options: {
name: 'div'
}
},
]
}
]
}
}
代码结构目录如下