waibu-mpa
Version:
MPA support for Waibu Framework
105 lines (96 loc) • 4 kB
JavaScript
import themeFactory from './class/theme.js'
import componentFactory from './class/component.js'
import loadResource from './load-resource.js'
import path from 'path'
async function addItem ({ file, container, prefix = '' } = {}) {
const { importModule } = this.app.bajo
const { camelCase } = this.app.lib._
const baseName = path.basename(file, path.extname(file))
const key = camelCase(`${prefix} ${baseName}`)
const mod = await importModule(file)
container[key] = mod
}
async function loadItems (type, theme) {
const { eachPlugins } = this.app.bajo
const { fastGlob } = this.app.lib
const me = this
const container = {}
// main
const files = await fastGlob(`${this.dir.pkg}/extend/waibuMpa/theme/component/${type}/*.js`)
for (const file of files) {
await addItem.call(this, { file, container })
}
// extender
await eachPlugins(async function ({ file }) {
await addItem.call(me, { file, container, prefix: this.alias })
}, { glob: `theme/component/${type}/*.js`, prefix: this.ns })
theme[type] = container
}
async function build (mod, fw) {
const { runHook } = this.app.bajo
const { omit, merge, find } = this.app.lib._
const me = this
await runHook(`${this.ns}.${mod.name}:beforeCollectTheme`, mod, fw)
const Theme = await themeFactory.call(this)
const theme = new Theme(this, mod.name)
Object.assign(theme, omit(mod, ['ns']))
await loadItems.call(mod.plugin, 'widget', theme)
await loadItems.call(mod.plugin, 'method', theme)
theme.createComponent = async function ({ $, iconset, req, reply, locals, scriptBlock, styleBlock }) {
const Cls = await componentFactory.call(me)
const cmp = new Cls({ plugin: fw ? fw.plugin : mod.plugin, $, theme, iconset, req, reply, locals, scriptBlock, styleBlock })
await cmp.loadBaseWidgets()
const framework = theme.framework ? find(me.themes, { name: theme.framework }) : undefined
merge(cmp.widget, framework ? framework.widget : {}, theme.widget)
Object.assign(cmp, merge({}, framework ? framework.method : {}, theme.method))
return cmp
}
this.themes.push(theme)
this.log.trace('- %s@%s', theme.name, mod.name)
await runHook(`${this.ns}.${mod.name}:afterCollectTheme`, theme)
}
async function collectThemes () {
const { eachPlugins, importModule } = this.app.bajo
const { isFunction, isArray, find, without } = this.app.lib._
this.themes = []
if (this.config.theme === false) {
this.log.warn('supportDisabled%s', this.t('Theme'))
return
}
this.log.debug('collect%s', this.t('themes'))
const modso = []
const modsf = []
const me = this
await eachPlugins(async function ({ file }) {
const plugin = this
let mod = await importModule(file)
if (isFunction(mod)) mod = await mod.call(this, me.webAppCtx)
if (!isArray(mod)) mod = [mod]
mod = mod.map(m => Object.assign(m, { plugin }))
for (const m of mod) {
m.meta = m.meta ?? []
if (!isArray(m.meta)) m.meta = [m.meta]
m.metaExcludes = m.metaExcludes ?? []
if (!isArray(m.metaExcludes)) m.metaExcludes = [m.metaExcludes]
for (const key of ['css', 'links', 'scripts', 'cssExcludes', 'linksExcludes', 'scriptsExcludes']) {
m[key] = await loadResource.call(this, m, key)
}
m.component = {}
if (m.framework) modsf.push(m) // module needs framework
else modso.push(m) // independent module
}
}, { glob: 'theme.js', prefix: this.ns })
for (const mod of modso) {
await build.call(this, mod)
}
for (const mod of modsf) {
const fw = find(modso, { name: mod.framework })
if (!fw) throw this.error('cantFindThemeFramework%s', mod.framework)
for (const key of ['meta', 'css', 'links', 'scripts']) {
mod[key].push(...without(fw[key], ...mod[`${key}Excludes`]))
}
mod.moveToEnd = fw.moveToEnd
await build.call(this, mod, fw)
}
}
export default collectThemes