假设你有一个需求,要把代码里的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的optionsconst 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'}},]}]}
}
代码结构目录如下