Skip to content

Commit

Permalink
feat: 更新条件判断css loader
Browse files Browse the repository at this point in the history
  • Loading branch information
Blackgan3 committed Nov 30, 2024
1 parent 9b87c84 commit 977c5ad
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 11 deletions.
18 changes: 14 additions & 4 deletions packages/webpack-plugin/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const wxssLoaderPath = normalize.lib('wxss/index')
const wxmlLoaderPath = normalize.lib('wxml/loader')
const wxsLoaderPath = normalize.lib('wxs/loader')
const styleCompilerPath = normalize.lib('style-compiler/index')
const styleStripConditaionalPath = normalize.lib('style-compiler/strip-conditional-loader')
const templateCompilerPath = normalize.lib('template-compiler/index')
const jsonCompilerPath = normalize.lib('json-compiler/index')
const jsonThemeCompilerPath = normalize.lib('json-compiler/theme')
Expand Down Expand Up @@ -1775,7 +1776,7 @@ try {
})

const typeLoaderProcessInfo = {
styles: ['node_modules/css-loader', wxssLoaderPath, styleCompilerPath],
styles: ['node_modules/css-loader', wxssLoaderPath, styleCompilerPath, styleStripConditaionalPath],
template: ['node_modules/html-loader', wxmlLoaderPath, templateCompilerPath]
}

Expand All @@ -1801,9 +1802,18 @@ try {
}
})
if (insertBeforeIndex > -1) {
loaders.splice(insertBeforeIndex + 1, 0, {
loader: info[2]
})
if (type === 'styles') {
loaders.splice(insertBeforeIndex + 1, 0, {
loader: info[2]
}, {
loader: info[3]
})
} else {
loaders.splice(insertBeforeIndex + 1, 0, {
loader: info[2]
})
}

}
break
}
Expand Down
2 changes: 1 addition & 1 deletion packages/webpack-plugin/lib/resolver/AddEnvPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ module.exports = class AddEnvPlugin {
const queryObj = parseQuery(request.query || '?')
queryObj.infix = `${queryObj.infix || ''}.${env}`
// css | stylus | less | sass 中 import file 过滤query,避免在对应的 loader 中无法读取到文件
if (!isCSSFileName(extname)) obj.query = stringifyQuery(queryObj)
obj.query = stringifyQuery(queryObj)
obj.path = addInfix(resourcePath, env, extname)
obj.relativePath = request.relativePath && addInfix(request.relativePath, env, extname)
resolver.doResolve(target, Object.assign({}, request, obj), 'add env: ' + env, resolveContext, callback)
Expand Down
4 changes: 1 addition & 3 deletions packages/webpack-plugin/lib/resolver/AddModePlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ module.exports = class AddModePlugin {
if (defaultMode && !result) {
queryObj.infix = `${queryInfix || ''}.${defaultMode}`
// css | stylus | less | sass 中 import file 过滤query,避免在对应的 loader 中无法读取到文件
if (!isCSSFileName(extname)) {
obj.query = stringifyQuery(queryObj)
}
obj.query = stringifyQuery(queryObj)
obj.path = addInfix(resourcePath, defaultMode, extname)
resolver.doResolve(target, Object.assign({}, request, obj), 'add mode: ' + defaultMode, resolveContext, (err, result) => {
callback(err, result)
Expand Down
6 changes: 3 additions & 3 deletions packages/webpack-plugin/lib/style-compiler/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ module.exports = function (css, map) {
plugins.push(transSpecial({ id }))
}

plugins.push(pluginCondStrip({
defs
}))
// plugins.push(pluginCondStrip({
// defs
// }))

for (const item of transRpxRules) {
const {
Expand Down
116 changes: 116 additions & 0 deletions packages/webpack-plugin/lib/style-compiler/strip-conditional-loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
const MagicString = require('magic-string')

function cssConditionalStrip(cssContent, defs) {
const ms = new MagicString(cssContent)

// 正则匹配 @mpx-if, @mpx-elif, @mpx-else, @mpx-endif 的模式
const ifPattern = /\/\*\s*@mpx-if\s*\((.*?)\)\s*\*\//gs
const elifPattern = /\/\*\s*@mpx-elif\s*\((.*?)\)\s*\*\//gs
const elsePattern = /\/\*\s*@mpx-else\s*\*\//gs
const endifPattern = /\/\*\s*@mpx-endif\s*\*\//gs

function evaluateCondition(condition) {
// 替换变量
for (const key in defs) {
condition = condition.replace(new RegExp(`\\b${key}\\b`, 'g'), JSON.stringify(defs[key]))
}

// 解析条件表达式
try {
return Function('"use strict";return (' + condition + ')')()
} catch (e) {
throw new Error(`Failed to evaluate condition: ${condition}`)
}
}

let currentStart = 0
function processCondition(start, end, condition) {
const conditionResult = evaluateCondition(condition)
let hasElse = false
let elseStart = -1
let elseLen = 0
currentStart = end + 1

while (currentStart < ms.original.length) {
elsePattern.lastIndex = currentStart
const elseMatch = elsePattern.exec(ms.original)
if (elseMatch) {
elseLen = elseMatch[0].length
}

ifPattern.lastIndex = currentStart
const ifMatch = ifPattern.exec(ms.original)

elifPattern.lastIndex = currentStart
const elifMatch = elifPattern.exec(ms.original)

endifPattern.lastIndex = currentStart
const endifMatch = endifPattern.exec(ms.original)

const nextIf = ifMatch ? ifMatch.index : Infinity
const nextElseIf = elifMatch ? elifMatch.index : Infinity
const nextElse = elseMatch ? elseMatch.index : Infinity
const nextEndif = endifMatch ? endifMatch.index : Infinity

const nextMarker = Math.min(nextIf, nextElseIf, nextElse, nextEndif)

if (nextMarker === Infinity) break

if (nextMarker === nextElse) {
// 处理 @mpx-else
hasElse = true
elseStart = nextElse
currentStart = elseMatch.index + elseLen
} else if (nextMarker === nextElseIf) {
// 处理 @mpx-elif
if (!conditionResult) {
ms.remove(start, nextElseIf)
}
if (elifMatch) {
currentStart = nextElseIf + elifMatch[0].length
processCondition(nextElseIf, nextElseIf + elifMatch[0].length, elifMatch[1])
}
} else if (nextMarker === nextIf) {
// 处理嵌套的 @mpx-if
// 如果遇到了新的 @mpx-if,则递归处理
if (ifMatch) {
currentStart = nextIf + ifMatch[0].length
processCondition(nextIf, nextIf + ifMatch[0].length, ifMatch[1])
}
} else if (nextMarker === nextEndif) {
// 处理 @mpx-endif block块
if (conditionResult && hasElse) {
// 移除 @mpx-else 至 @mpx-endif 代码
ms.remove(elseStart, endifMatch.index + endifMatch[0].length)
} else if (!conditionResult && hasElse) {
ms.remove(start, elseStart + elseLen)
} else if (!conditionResult) {
ms.remove(start, endifMatch.index + endifMatch[0].length)
}
currentStart = endifMatch.index + endifMatch[0].length
break
}
// 兜底更新当前开始位置
if (currentStart < nextMarker) {
currentStart = nextMarker + 1
}
}
}

// 处理所有条件
let match
while ((match = ifPattern.exec(ms.original)) !== null) {
processCondition(match.index, ifPattern.lastIndex, match[1])
ifPattern.lastIndex = currentStart
}

return ms.toString()
}

module.exports = function (css) {
this.cacheable()
const mpx = this.getMpx()
const defs = mpx.defs

return cssConditionalStrip(css, defs)
}

0 comments on commit 977c5ad

Please sign in to comment.