介入webpack 的打包流程,将某个包给mock 掉
介入webpack 的打包流程,将某个包给mock 掉
在某些情况下,我们对于包的体积比较敏感,某些第三方的包引用了其他第三方的包,而且第三方的包不支持摇树,我们希望在打包的时候将第三方包所依赖的第三方包给去除掉,因为那部分功能我们并不使用。思路是采用mock 的方式,将第三方的第三方包给去除。
被测试代码的例子
// index.js
// 这个里面直接import 的modA 不mock, modB 里面的 modA要mock
import {greeting} from './modA/modA';
import {greetingWrapper} from './modA/modB';
greetingWrapper();
greeting();
// modA.js
import {debounce} from 'lodash';
export const greeting=debounce(()=>`hello world`,10);
// modB.js 这个里面的modA 要mock
import { greeting } from "./modA";
export const greetingWrapper = ()=>{
greeting();
}
// mock_modA.js
export const greeting=()=>`hello world from mock moduleA`;
webpack plugin
我们可以借助webpack 的plugin, 在normalModuleFactory这个hook里面将某个issuer里面所使用的requet给替换掉,这个是webpack 的插件,可以直接使用
class ReplacePlugin{
apply(compiler){
compiler.hooks.normalModuleFactory.tap('ReplacePlugin', (normalModuleFactory) => {
normalModuleFactory.hooks.beforeResolve.tapAsync('ReplacePlugin', (result, callback) => {
// 条件判断,issuer 就是使用方,request 就是被导入的模块
if(result && /modA(\.js)?$/i.test(result.request) && result.context.issuer && /[\\/]modB(\.js)?$/i.test(result.context.issuer)){
// 把request 的路径给替换掉
result.request = result.request.replace(/modA(\.js)?$/i, 'mock_modA$1');
}
callback();
});
});
}
}
webpack resolve 的plugin
借助webpack 的resolve, 在它解析的时候将被使用的模块给替换掉
class ResolvePlugin{
apply(resolver){
resolver.hooks.resolve.tapAsync('ResolvePlugin', (request, resolveContext, callback) => {
const requestPath = request.request;
if(/\/modA(\.js)?$/i.test(requestPath) && request.context.issuer && /[\\/]modB(\.js)?$/i.test(request.context.issuer)){
console.log(request.context.issuer);
const newRequest ={
...request,
request: requestPath.replace(/modA(\.js)?$/i, 'mock_modA$1'),
};
return resolver.doResolve(resolver.hooks.resolve, newRequest, `Redirecting ${requestPath} -> ${newRequest.request}`, resolveContext, callback);
}
callback();
});
}
}
// webpack 的配置
const ResolvePluginInstance = new ResolvePlugin();
resolve:{
extensions:['.js'],
plugins:[
// 记得构建实例
ResolvePluginInstance
]
},
总结
这两种方式经过测试都可以实现我们预设的目标,但是推荐使用resolve 的这种方式,因为它只是发生在文件resolve 的时候,效率更高
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2024-03-01 介绍几个scss 与css 中的新的特性