You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
4.2 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* @fileoverview 条件编译
*/
const through2 = require('through2')
/**
* @description 条件编译
* @param {string} platform 平台
*/
module.exports = function (platform) {
return through2.obj(function (file, _, callback) {
if (file.isBuffer()) {
// 文件夹级别的处理
if (file.relative.includes('miniprogram')) {
if (platform !== 'uni-app') {
// 去掉这一层
file.path = file.path.replace(/(.*)[/\\]miniprogram/, '$1')
} else {
// 不用于本平台的文件
callback()
return
}
} else if (file.relative.includes('uni-app')) {
if (platform === 'uni-app') {
file.path = file.path.replace(/(.*)[/\\]uni-app/, '$1')
} else {
callback()
return
}
}
if (platform === 'uni-app') {
// uni-app 平台 vue3 要求使用 es6 模块
let content = file.contents.toString()
if (file.basename === 'prism.min.js') {
content = content.replace('"undefined"!=typeof module&&module.exports&&(module.exports=Prism),', 'export default Prism;')
} else if (file.extname === '.js' && !file.relative.includes('static')) {
content = content.replace(/module.exports\s*=\s*/, 'export default ')
.replace(/const\s+([^\s=]+)\s*=\s*require\(([^)]+)\)/g, 'import $1 from $2')
}
file.contents = Buffer.from(content)
} else {
// 小程序平台进行进一步处理
let content = file.contents.toString()
/**
* 方式1
* 在注释 #if(n)def xxx 和 #endif 之间的内容会根据是否定义 xxx 决定是否保留
*/
const commentReg = /\/\*[\s\S]*?\*\/|\/\/[^\n]*|<!--[\s\S]*?-->/g // 提取所有注释
const copy = content // 拷贝一个副本用于搜索
let match = commentReg.exec(copy)
const stack = []
while (match) {
if (match[0].includes('#if')) {
stack.push([match[0], match.index])
} else if (match[0].includes('#endif')) {
const item = stack.pop()
if (!item) {
throw Error('条件编译错误:存在多余的 #endifpath:' + file.path + 'content: ' + content.substr(match.index, 100))
}
const def = item[0].match(/MP-[A-Z]+/gi) || [] // 取出定义条件
let hit = false
for (let i = 0; i < def.length; i++) {
if (def[i] && platform === def[i].toLowerCase()) {
hit = true // 命中
break
}
}
// 不匹配
if ((item[0].includes('#ifdef') && !hit) || (item[0].includes('#ifndef') && hit)) {
let fill = ''
// 用空格填充
for (let j = item[1] + item[0].length; j < match.index; j++) {
if (content[j] === '\n') {
fill += '\n'
} else {
fill += ' '
}
}
content = content.substr(0, item[1] + item[0].length) + fill + content.substr(match.index)
}
}
match = commentReg.exec(copy)
}
if (stack.length) {
throw Error('条件编译错误:存在未闭合的 #ifdefpath:' + file.path + 'content: ' + content.substr(stack[0][1], 100))
}
/**
* 方式2
* wxml 中属性前加平台名将仅编译到该平台,如 mp-weixin:attr
*/
if (file.extname === '.wxml') {
content = content.replace(/([^:\s]+:[^=\s]+)\s*=\s*"(.*?)"/g, ($, $1, $2) => {
const platforms = $1.split(':')
let name = platforms.pop()
const last = platforms[platforms.length - 1]
if (last && !last.includes('mp')) {
name = platforms.pop() + ':' + name
}
if (!platforms.length) return $
let i
for (i = platforms.length; i--;) {
if (platform === platforms[i].toLowerCase()) break
}
if (i >= 0) return `${name}="${$2}"`
return ''
})
}
file.contents = Buffer.from(content)
}
}
this.push(file)
callback()
})
}