Files
fitness_walk_nwnu/node_modules/@dcloudio/webpack-uni-mp-loader/lib/plugin/generate-components-wxml.bak
T
2026-09-08 20:28:54 +08:00

222 lines
5.1 KiB
Plaintext

const {
md5
} = require('@dcloudio/uni-cli-shared')
const {
getSlotsPath
} = require('./util')
const {
getRoot,
getPlatformExts,
getGlobalComponents,
normalizeNodeModules,
getCompiledComponentTemplate,
cacheCompiledComponentTemplates
} = require('../shared')
const compileToTemplate = require('./compile-to-template')
const templateExt = getPlatformExts().template
function normalizeImports (imports = {}, componentPath, subPackages) {
const res = {}
Object.keys(imports).forEach(key => {
const {
name,
src
} = imports[key]
res[key] = {
name,
src: '/' + normalizeNodeModules(src) + '.vue' + templateExt
}
})
return res
}
function generateSlotsWxml ({
imports,
contents
}) {
let slotsOutput = ''
imports.forEach(im => {
slotsOutput = slotsOutput + `<import src="${normalizeNodeModules(im)}" />\n`
})
slotsOutput = slotsOutput + `\n`
contents.forEach(b => {
slotsOutput = slotsOutput + b + `\n\n`
})
return slotsOutput
}
module.exports = function generateComponentsWxml (templates, allCompilerOptions, subPackages) {
const mainSlots = {
imports: new Set(),
contents: new Set()
}
const subPackageSlots = {}
const files = []
const allDeps = new Set() // only for mpvue
const globalComponents = getGlobalComponents()
let isMPVue = false
Object.keys(templates).forEach(filePath => {
const source = templates[filePath]
const compilerOptions = allCompilerOptions[filePath]
if (!compilerOptions) {
throw new Error(filePath + ' error ')
}
const root = getRoot(filePath, subPackages)
const imports = normalizeImports(compilerOptions.imports, filePath, subPackages)
// add slots
imports['_slots_'] = {
name: '',
src: getSlotsPath(root)
}
const emitFilePath = filePath + '.vue' + templateExt
// 全局组件
Object.keys(globalComponents).forEach(name => {
imports[name] = globalComponents[name]
})
const componentMD5 = md5(source + compilerOptions.scopeId + JSON.stringify(imports))
const compiledComponentTemplate = getCompiledComponentTemplate(filePath)
let currentSlots = []
if (!subPackageSlots[root] && root) {
subPackageSlots[root] = {
imports: new Set(),
contents: new Set()
}
}
if (compiledComponentTemplate.md5 !== componentMD5) {
const result = compileToTemplate(source, Object.assign({}, compilerOptions, {
imports
}))
let body = result.body
const {
slots,
deps = [],
mpvue,
needHtmlParse
} = result
if (mpvue) {
isMPVue = true
deps.forEach(dep => {
allDeps.add(dep)
})
}
if (needHtmlParse) {
body = `<import src="/htmlparse/index${templateExt}" />
${body}`
}
cacheCompiledComponentTemplates(filePath, {
md5: componentMD5,
body,
slots
})
currentSlots = slots || []
files.push({
file: emitFilePath,
source: body
})
} else {
currentSlots = compiledComponentTemplate.slots || []
}
let collector
if (root) {
collector = subPackageSlots[root]
} else {
collector = mainSlots
}
currentSlots.forEach(slot => {
const dependencies = slot.dependencies || []
const body = slot.body
dependencies.forEach(d => collector.imports.add(d))
collector.contents.add(body)
if (collector !== mainSlots) { // TODO 待优化,把分包内容全部写入主包 slots 中
dependencies.forEach(d => mainSlots.imports.add(d))
mainSlots.contents.add(body)
}
})
})
if (!isMPVue) {
// subPackage slots
Object.keys(subPackageSlots)
.forEach(root => {
const {
imports,
contents
} = subPackageSlots[root] || {}
// subpackage slots
files.push({
file: getSlotsPath(root),
source: generateSlotsWxml({
imports,
contents
})
})
})
} else { // merge
Object.keys(subPackageSlots)
.forEach(root => {
const {
imports,
contents
} = subPackageSlots[root] || {}
if (imports && imports.size) {
mainSlots.imports = new Set([...mainSlots.imports, ...imports])
}
if (contents && contents.size) {
mainSlots.contents = new Set([...mainSlots.contents, ...contents])
}
})
// mpvue slots add all imports
allDeps.forEach(dep => {
mainSlots.imports.add(dep)
})
}
// main slots
files.push({
file: getSlotsPath(''),
source: generateSlotsWxml({
imports: mainSlots.imports,
contents: mainSlots.contents
})
})
// TODO 遗留问题:当subPackage 引用 main 中的组件时,slots 被放在 subPackage 的 slots 中,导致 main 中的组件访问不到该 slots
// 格式化node_modules,在微信小程序中,node_modules目录会被过滤掉,cli时 node_modules 在外层,也要转移到根目录
files.forEach(file => {
file.file = normalizeNodeModules(file.file)
})
return files
}