@canvases/ifcomp-config-loader
Version:
本项目提供了一个 Webpack Loader,用于在 Vue2 项目中进行条件编译功能。它允许你在 Web 和不同平台(如 `APP-PLUS`、`H5`、`MP-WEIXIN` 等)之间运用不同的业务组件。
76 lines (55 loc) • 2.85 kB
JavaScript
const path = require('path');
const fs = require('fs');
module.exports = function (source) {
const {
platform,entryJson
} = this.query; // 获取 Webpack 配置传入的平台标识
if (!platform) return source; // 没有平台直接返回原代码
// 处理条件编译逻辑
return moduleConditionalCode(source, platform, entryJson);
};
// 获取manifest.json 里面的 module 名称
const getModuleName = function (platform,entryJson) {
// 获取 `manifest.json` 绝对路径
const manifestPath = entryJson || path.resolve(__dirname,'manifest.json');
// 如果配置文件不存在,则直接抛出错误,终止构建
if (!fs.existsSync(manifestPath)) {
throw new Error(`入口配置文件未找到:${manifestPath}。请检查配置是否正确。`);
}
// 读取 `manifest.json`
let manifest = {},modulesKeys=[];
if (fs.existsSync(manifestPath)) {
manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
}
if (manifest[platform] && manifest[platform].modules) {
modulesKeys = Object.keys(manifest[platform].modules)
}
return modulesKeys;
}
function moduleConditionalCode(source, platform, entryJson) {
// 匹配所有条件编译块的正则
// const regex = /(?:<!--|\/\/|\/\*)\s*#(ifdef|ifndef)\s+(\w+)\s*(?:-->|\*\/)?\n?([\s\S]*?)\n?(?:<!--|\/\/|\/\*)?\s*#endif\s*(?:-->|\*\/)?/g;
// const regex = /(?:<!--|\/\/|\/\*)\s*#(ifdef|ifndef)\s+([\w\s\|\!]+)\s*(?:-->|\*\/)?\n?([\s\S]*?)\n?(?:<!--|\/\/|\/\*)?\s*#endif\s*(?:-->|\*\/)?/g;
const regex = /(?:<!--|\/\/|\/\*)\s*#(ifcomp|ifncomp)\s+(\w+(?:\s*\|\|\s*\w+)*)\s*(?:-->|\*\/)?\n?([\s\S]*?)\n?(?:<!--|\/\/|\/\*)?\s*#endif\s*(?:-->|\*\/)?/g;
const moduleNames = getModuleName(platform,entryJson);
return source.replace(regex, (match, directive, condition, codeBlock) => {
// 解析条件类型(ifdef 或 ifndef)
const isIfDef = directive === 'ifcomp';
const conditions = condition.split(/\s*\|\|\s*/); // 支持多条件,如 XAM || WX
// 判断条件是否满足
const isMatched = conditions.some(item => moduleNames.includes(item))
// const isMatched = conditions.some(c => {
// const isNegation = c.startsWith('!');
// const target = isNegation ? c.slice(1) : c;
// return isNegation ? (platform !== target) : (platform === target);
// });
// 根据条件保留或移除代码块
if ((isIfDef && isMatched) || (!isIfDef && !isMatched)) {
// 移除注释标记,保留代码内容
// return codeBlock.trim()
return codeBlock.replace(/^\n+|\n+$/g, '');
} else {
return '';
}
});
}