diff --git a/packages/uni-cli-shared/src/mp/index.ts b/packages/uni-cli-shared/src/mp/index.ts index a01978da6ce0cb72d961d03e35f55629151be8d5..54f2ca47ac4e25ee4f9488e84156e694e507b840 100644 --- a/packages/uni-cli-shared/src/mp/index.ts +++ b/packages/uni-cli-shared/src/mp/index.ts @@ -1,4 +1,5 @@ export * from './nvue' export * from './event' export * from './style' +export * from './template' export { transformVueComponentImports } from './transformImports' diff --git a/packages/uni-cli-shared/src/mp/template.ts b/packages/uni-cli-shared/src/mp/template.ts new file mode 100644 index 0000000000000000000000000000000000000000..6ece4cb0a7fcac62edc89a3356a1eaed5c2de7e2 --- /dev/null +++ b/packages/uni-cli-shared/src/mp/template.ts @@ -0,0 +1,65 @@ +import { LINEFEED } from '@dcloudio/uni-shared' + +export interface MiniProgramFilterOptions { + id: string + type: 'wxs' + name: string + src?: string + code: string +} + +type GenFilterFn = (filter: MiniProgramFilterOptions) => string | void + +const templateFilesCache = new Map() +const templateFiltersCache = new Map>() + +export function findMiniProgramTemplateFiles(genFilter?: GenFilterFn) { + const files: Record = Object.create(null) + templateFilesCache.forEach((code, filename) => { + if (!genFilter) { + files[filename] = code + } else { + const filters = getMiniProgramTemplateFilters(filename) + if (filters.length) { + files[filename] = + filters.map((filter) => genFilter(filter)).join(LINEFEED) + + LINEFEED + + code + } else { + files[filename] = code + } + } + }) + return files +} + +export function clearMiniProgramTemplateFiles() { + templateFilesCache.clear() +} + +export function addMiniProgramTemplateFile(filename: string, code: string) { + templateFilesCache.set(filename, code) +} + +function getMiniProgramTemplateFilters(filename: string) { + return [...(templateFiltersCache.get(filename) || [])] +} + +export function clearMiniProgramTemplateFilter(filename: string) { + templateFiltersCache.delete(filename) +} + +export function addMiniProgramTemplateFilter( + filename: string, + filter: MiniProgramFilterOptions +) { + const filters = templateFiltersCache.get(filename) + if (filters) { + filters.add(filter) + } else { + templateFiltersCache.set( + filename, + new Set([filter]) + ) + } +} diff --git a/packages/uni-mp-vite/src/plugin/index.ts b/packages/uni-mp-vite/src/plugin/index.ts index 9263392f64035fb4e8bce8b73905098c856270f6..82ae1f6999a325787da84385674032656abbdf35 100644 --- a/packages/uni-mp-vite/src/plugin/index.ts +++ b/packages/uni-mp-vite/src/plugin/index.ts @@ -1,23 +1,18 @@ -import path from 'path' -import debug from 'debug' -import fs from 'fs-extra' -import { AliasOptions } from 'vite' +import { AliasOptions, ResolvedConfig } from 'vite' import { CopyOptions, - EXTNAME_VUE_RE, - normalizeNodeModules, resolveBuiltIn, UniVitePlugin, genNVueCssCode, parseManifestJsonOnce, + findMiniProgramTemplateFiles, } from '@dcloudio/uni-cli-shared' import { uniOptions } from './uni' import { buildOptions } from './build' import { createConfigResolved } from './configResolved' -import { EmittedFile } from 'rollup' +import { emitFile, getFilterFiles, getTemplateFiles } from './template' -const debugMp = debug('vite:uni:mp') export interface UniMiniProgramPluginOptions { vite: { alias: AliasOptions @@ -42,6 +37,11 @@ export interface UniMiniProgramPluginOptions { // 是否支持fallback content fallback: boolean } + filter?: { + extname: string + tag: string + generate: Parameters[0] + } } style: { extname: string @@ -53,10 +53,6 @@ export interface UniMiniProgramPluginOptions { '--window-right': string } } - filter?: { - extname: string - tag: string - } } export function uniMiniProgramPlugin( @@ -67,22 +63,9 @@ export function uniMiniProgramPlugin( template, style, } = options - const emitFile: (emittedFile: EmittedFile) => string = (emittedFile) => { - if (emittedFile.type === 'asset') { - const filename = emittedFile.fileName! - const outputFilename = normalizeNodeModules( - path.resolve( - process.env.UNI_OUTPUT_DIR, - path.relative(process.env.UNI_INPUT_DIR, filename) - ) - ).replace(EXTNAME_VUE_RE, template.extname) - debugMp(outputFilename) - fs.outputFile(outputFilename, emittedFile.source!) - return outputFilename - } - return '' - } + let isFirst = true + let resolvedConfig: ResolvedConfig return { name: 'vite:uni-mp', uni: uniOptions({ @@ -104,8 +87,30 @@ export function uniMiniProgramPlugin( build: buildOptions(), } }, - configResolved: createConfigResolved(options), + configResolved(config) { + resolvedConfig = config + return createConfigResolved(options)!(config) + }, generateBundle() { + if (template.filter) { + const extname = template.filter.extname + const filterFiles = getFilterFiles(resolvedConfig, this.getModuleInfo) + Object.keys(filterFiles).forEach((filename) => { + this.emitFile({ + type: 'asset', + fileName: filename + extname, + source: filterFiles[filename], + }) + }) + } + const templateFiles = getTemplateFiles(template) + Object.keys(templateFiles).forEach((filename) => { + this.emitFile({ + type: 'asset', + fileName: filename + template.extname, + source: templateFiles[filename], + }) + }) if (isFirst) { // 仅生成一次 isFirst = false diff --git a/packages/uni-mp-vite/src/plugin/template.ts b/packages/uni-mp-vite/src/plugin/template.ts new file mode 100644 index 0000000000000000000000000000000000000000..28d12d4dd3988e18951fcd1291107ca8d4703299 --- /dev/null +++ b/packages/uni-mp-vite/src/plugin/template.ts @@ -0,0 +1,80 @@ +import path from 'path' +import debug from 'debug' +import { EmittedFile, GetModuleInfo } from 'rollup' +import { ResolvedConfig } from 'vite' +import { + addMiniProgramTemplateFile, + removeExt, + normalizeMiniProgramFilename, + MiniProgramFilterOptions, + findMiniProgramTemplateFiles, + addMiniProgramTemplateFilter, + clearMiniProgramTemplateFiles, +} from '@dcloudio/uni-cli-shared' +import { getFiltersCache } from '../plugins/renderjs' +import { UniMiniProgramPluginOptions } from '.' + +const debugTemplate = debug('vite:uni:mp-template') + +export function getFilterFiles( + resolvedConfig: ResolvedConfig, + getModuleInfo: GetModuleInfo +) { + const filters: Record = Object.create(null) + const filtersCache = getFiltersCache(resolvedConfig) + if (!filtersCache.length) { + return filters + } + const inputDir = process.env.UNI_INPUT_DIR + function addFilter(id: string, filter: MiniProgramFilterOptions) { + const templateFilename = removeExt( + normalizeMiniProgramFilename(id, inputDir) + ) + addMiniProgramTemplateFilter(templateFilename, filter) + const filterFilename = removeExt( + normalizeMiniProgramFilename(filter.id, inputDir) + ) + if (templateFilename !== filterFilename) { + // 外链 + filter.src = filterFilename + filters[filterFilename] = filter.code + } + } + filtersCache.forEach((filter) => { + const moduleInfo = getModuleInfo(filter.id) + if (!moduleInfo) { + return + } + const { importers } = moduleInfo + if (!importers.length) { + return + } + importers.forEach((importer) => addFilter(importer, filter)) + }) + return filters +} + +export function getTemplateFiles( + template: UniMiniProgramPluginOptions['template'] +) { + const files = findMiniProgramTemplateFiles(template.filter!.generate) + clearMiniProgramTemplateFiles() + return files +} + +export const emitFile: (emittedFile: EmittedFile) => string = (emittedFile) => { + if (emittedFile.type === 'asset') { + const filename = emittedFile.fileName! + addMiniProgramTemplateFile( + removeExt( + normalizeMiniProgramFilename( + path.relative(process.env.UNI_INPUT_DIR, filename) + ) + ), + emittedFile.source!.toString() + ) + debugTemplate(filename) + return filename + } + return '' +} diff --git a/packages/uni-mp-vite/src/plugins/renderjs.ts b/packages/uni-mp-vite/src/plugins/renderjs.ts index 4198355bfafbca3de3f451feb8bee7a750ad4e74..6193c0cf9abb3df8b8872e1dfb9860b84b422c03 100644 --- a/packages/uni-mp-vite/src/plugins/renderjs.ts +++ b/packages/uni-mp-vite/src/plugins/renderjs.ts @@ -1,13 +1,30 @@ import debug from 'debug' -import { Plugin } from 'vite' +import { Plugin, ResolvedConfig } from 'vite' -import { missingModuleName, parseRenderjs } from '@dcloudio/uni-cli-shared' +import { + MiniProgramFilterOptions, + missingModuleName, + parseRenderjs, +} from '@dcloudio/uni-cli-shared' const debugRenderjs = debug('vite:uni:renderjs') +const filtersCache = new Map() + +export function getFiltersCache(resolvedConfig: ResolvedConfig) { + return filtersCache.get(resolvedConfig) || [] +} + export function uniRenderjsPlugin(): Plugin { + let resolvedConfig: ResolvedConfig return { name: 'vite:uni-mp-renderjs', + configResolved(config) { + resolvedConfig = config + }, + buildStart() { + filtersCache.set(resolvedConfig, []) + }, transform(code, id) { const { type, name } = parseRenderjs(id) if (!type) { @@ -18,12 +35,12 @@ export function uniRenderjsPlugin(): Plugin { this.error(missingModuleName(type, code)) } if (type === 'wxs') { - console.log('wxs', id, code) - // this.emitFile({ - // type: 'asset', - // fileName: '', - // source: code, - // }) + filtersCache.get(resolvedConfig)!.push({ + id, + type, + name, + code, + }) } return { code: 'export default {}', diff --git a/packages/uni-mp-weixin/dist/uni.compiler.js b/packages/uni-mp-weixin/dist/uni.compiler.js index 8fadb7191ed805cdbdc7acefa51288d464c5a6d0..49626fcfa57f3e5afade997e9ac89cdcbeb61c9f 100644 --- a/packages/uni-mp-weixin/dist/uni.compiler.js +++ b/packages/uni-mp-weixin/dist/uni.compiler.js @@ -107,6 +107,18 @@ const options = { source, }, template: { + filter: { + extname: '.wxs', + tag: 'wxs', + generate(filter) { + if (filter.src) { + return ``; + } + return ` +${filter.code} +`; + }, + }, slot: { fallback: false, }, @@ -123,10 +135,6 @@ const options = { '--window-right': '0px', }, }, - filter: { - extname: '.wxs', - tag: 'wxs', - }, }; var index = [uniMiniProgramWeixinPlugin, ...initMiniProgramPlugin__default["default"](options)]; diff --git a/packages/uni-mp-weixin/src/plugin/index.ts b/packages/uni-mp-weixin/src/plugin/index.ts index 0b58a21f1185b46695e8ebc97d3db92c5f1bd8b0..26ebfea8d66b6a123294aec8f3c7c519824bd7f4 100644 --- a/packages/uni-mp-weixin/src/plugin/index.ts +++ b/packages/uni-mp-weixin/src/plugin/index.ts @@ -61,6 +61,18 @@ const options: UniMiniProgramPluginOptions = { source, }, template: { + filter: { + extname: '.wxs', + tag: 'wxs', + generate(filter) { + if (filter.src) { + return `` + } + return ` +${filter.code} +` + }, + }, slot: { fallback: false, }, @@ -77,10 +89,6 @@ const options: UniMiniProgramPluginOptions = { '--window-right': '0px', }, }, - filter: { - extname: '.wxs', - tag: 'wxs', - }, } export default [uniMiniProgramWeixinPlugin, ...initMiniProgramPlugin(options)]