@canvases/ifdef-loader
Version:
"A loader used to distinguish and manage the configurations of multiple projects. It utilizes the ifdef conditional compilation directive and clearly marks the configurations of different projects through comments, facilitating development and compilation
106 lines (82 loc) • 4.37 kB
JavaScript
module.exports = function (source) {
const platform = this.query.platform; // 获取 Webpack 配置传入的平台标识
if (!platform) return source; // 没有平台直接返回原代码
// 处理条件编译逻辑
return processConditionalCode(source, platform);
};
function processConditionalCode(source, platform) {
// 匹配所有条件编译块的正则
// 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*#(ifdef|ifndef)\s+(\w+(?:\s*\|\|\s*\w+)*)\s*(?:-->|\*\/)?\n?([\s\S]*?)\n?(?:<!--|\/\/|\/\*)?\s*#endif\s*(?:-->|\*\/)?/g;
return source.replace(regex, (match, directive, condition, codeBlock) => {
// console.log(" ++++++++++ match: ",match, "directive: ",directive, "condition: ",condition, "codeBlock: ",codeBlock);
// 解析条件类型(ifdef 或 ifndef)
const isIfDef = directive === 'ifdef';
const conditions = condition.split(/\s*\|\|\s*/); // 支持多条件,如 XAM || WX
// console.log("============",condition,directive,conditions);
// 判断条件是否满足
const isMatched = conditions.some(c => {
const isNegation = c.startsWith('!');
const target = isNegation ? c.slice(1) : c;
return isNegation ? (platform !== target) : (platform === target);
});
if(isMatched){
}
// 返回的代码数据
// 3. 处理 #elseif 和 #else 逻辑
let finalCode = handleIfElseLogic(codeBlock, (isIfDef && isMatched) || (!isIfDef && !isMatched), platform);
return finalCode ? finalCode.trim() : '';
// 根据条件保留或移除代码块
// if ((isIfDef && isMatched) || (!isIfDef && !isMatched)) {
// console.log("!!!!!",codeBlock);
// // 移除注释标记,保留代码内容
// return codeBlock.trim()
// // return codeBlock.replace(/^\n+|\n+$/g, '');
// } else {
// return '';
// }
});
}
// 处理 #elseif 和 #else 逻辑
function handleIfElseLogic(codeBlock, isFirstMatched, platform) {
// const regex = /(?:<!--|\/\/|\/\*)\s*#(ifdef|ifndef|elseif|else)\s*(\w+(?:\s*\|\|\s*\w+)*)?\s*(?:-->|\*\/)?\n?([\s\S]*?)\n?(?=(?:<!--|\/\/|\/\*)?\s*#(?:elseif|else|endif)\s*(?:-->|\*\/)?|$)/g;
const regex = /(?:<!--|\/\/|\/\*)\s*#(ifdef|ifndef|elseif|else)\s*(\w+(?:\s*\|\|\s*\w+)*)?\s*(?:-->|\*\/)?\n?([\s\S]*?)\n?(?=(?:<!--|\/\/|\/\*)?\s*#(?:elseif|else|endif)\s*(?:-->|\*\/)?|$)/g;
let match = regex.exec(codeBlock),
result = [];
// console.log("======",match,isFirstMatched,codeBlock);
// 满足单个if条件的话,则返回结果
if (match === null) {
return isFirstMatched ? codeBlock.trim() : '';
}
if(isFirstMatched){
// 匹配第一个 // #elseif、<!-- #elseif、/* #elseif 或 // #else、<!-- #else、/* #else 之前的内容
const regexMatch = /^([\s\S]*?)(?:\/\/|<!--|\/\*)\s*#(?:elseif|else)/;
const matchFirst = codeBlock.match(regexMatch);
if (matchFirst) {
return result = matchFirst[1].trim();
} else {
console.log('未找到符合条件的代码片段');
return ' '
}
}
codeBlock.replace(regex, (match, directive, condition, codeBlock)=>{
if (directive === 'else') {
// #else 默认执行
result.push(match.trim());
}
if (directive === 'elseif') {
const conditions = condition.split(/\s*\|\|\s*/);
const isMatchedElseIf = conditions.some(c => {
const isNegation = c.startsWith('!');
const target = isNegation ? c.slice(1) : c;
return isNegation ? (platform !== target) : (platform === target);
});
if (isMatchedElseIf) {
// result += codeBlock.trim();
result.push(codeBlock.trim());
}
}
})
return result[0] || '';
}