From c87b1289a4fc4026edde0fc93f412097e2182a46 Mon Sep 17 00:00:00 2001 From: fxy060608 Date: Wed, 12 Jan 2022 18:21:16 +0800 Subject: [PATCH] wip(app): nvue --- packages/uni-app-vite/src/nvue/index.ts | 9 ++- .../uni-app-vite/src/nvue/plugin/index.ts | 53 ++++++++++++++++- .../uni-app-vite/src/nvue/plugins/entry.ts | 50 ---------------- .../uni-app-vite/src/nvue/plugins/mainJs.ts | 41 +++++++++++++ .../src/nvue/plugins/pagesJson.ts | 59 +++++++++++++++++++ packages/uni-app-vite/src/plugin/build.ts | 10 +++- packages/uni-app-vite/src/utils.ts | 3 + packages/uni-app-vite/src/vue/plugin/index.ts | 3 - .../uni-app-vite/src/vue/plugins/mainJs.ts | 4 +- .../uni-app-vite/src/vue/plugins/pagesJson.ts | 19 +++--- .../uni-app-vite/src/vue/plugins/renderjs.ts | 4 +- .../src/json/app/pages/definePage.ts | 16 +++++ .../src/json/app/pages/index.ts | 6 +- .../src/vite/plugins/dynamicImportPolyfill.ts | 12 ++++ .../uni-cli-shared/src/vite/plugins/index.ts | 1 + packages/uni-mp-vite/src/plugin/build.ts | 15 +---- 16 files changed, 218 insertions(+), 87 deletions(-) delete mode 100644 packages/uni-app-vite/src/nvue/plugins/entry.ts create mode 100644 packages/uni-app-vite/src/nvue/plugins/mainJs.ts create mode 100644 packages/uni-app-vite/src/nvue/plugins/pagesJson.ts create mode 100644 packages/uni-cli-shared/src/vite/plugins/dynamicImportPolyfill.ts diff --git a/packages/uni-app-vite/src/nvue/index.ts b/packages/uni-app-vite/src/nvue/index.ts index 32d135600..36e9eae4b 100644 --- a/packages/uni-app-vite/src/nvue/index.ts +++ b/packages/uni-app-vite/src/nvue/index.ts @@ -4,13 +4,20 @@ import { uniViteInjectPlugin, UNI_EASYCOM_EXCLUDE, } from '@dcloudio/uni-cli-shared' -import { uniAppNVuePlugin } from './plugin' + import { uniEasycomPlugin } from '../plugins/easycom' +import { uniManifestJsonPlugin } from '../plugins/manifestJson' +import { uniAppNVuePlugin } from './plugin' +import { uniMainJsPlugin } from './plugins/mainJs' +import { uniPagesJsonPlugin } from './plugins/pagesJson' export function initNVuePlugins() { return [ uniEasycomPlugin({ exclude: UNI_EASYCOM_EXCLUDE }), uniHBuilderXConsolePlugin(), + uniMainJsPlugin(), + ...(process.env.UNI_RENDERER === 'native' ? [uniManifestJsonPlugin()] : []), + uniPagesJsonPlugin(), uniViteInjectPlugin('uni:app-inject', initAppProvide()), uniAppNVuePlugin(), ] diff --git a/packages/uni-app-vite/src/nvue/plugin/index.ts b/packages/uni-app-vite/src/nvue/plugin/index.ts index f17e4e45e..94eba435a 100644 --- a/packages/uni-app-vite/src/nvue/plugin/index.ts +++ b/packages/uni-app-vite/src/nvue/plugin/index.ts @@ -1,15 +1,64 @@ import path from 'path' +import { + dynamicImportPolyfill, + normalizePath, + parseVueRequest, + removeExt, + resolveMainPathOnce, +} from '@dcloudio/uni-cli-shared' +import { PreRenderedChunk } from 'rollup' import { Plugin } from 'vite' +import { nvueOutDir } from '../../utils' export function uniAppNVuePlugin(): Plugin { return { name: 'uni:app-nvue', config() { + const inputDir = process.env.UNI_INPUT_DIR + const mainPath = resolveMainPathOnce(inputDir) return { + lib: { + // 必须使用 lib 模式,否则会生成 preload 等代码 + fileName: 'main.js', + entry: mainPath, + formats: ['esm'], + }, build: { - outDir: path.join(process.env.UNI_OUTPUT_DIR, '../.nvue'), - rollupOptions: {}, + outDir: nvueOutDir(), + rollupOptions: { + input: { + main: mainPath, + }, + output: { + entryFileNames(chunk) { + if (chunk.name === 'main') { + return 'app.js' + } + return chunk.name + '.js' + }, + format: 'esm', + assetFileNames: '[name][extname]', + chunkFileNames: createChunkFileNames(inputDir), + plugins: [dynamicImportPolyfill()], + }, + }, }, } }, } } + +function createChunkFileNames( + inputDir: string +): (chunkInfo: PreRenderedChunk) => string { + return function chunkFileNames(chunk) { + if (chunk.isDynamicEntry && chunk.facadeModuleId) { + const { filename } = parseVueRequest(chunk.facadeModuleId) + if (filename.endsWith('.nvue')) { + return ( + removeExt(normalizePath(path.relative(inputDir, filename))) + '.js' + ) + } + } + return '[name].js' + } +} diff --git a/packages/uni-app-vite/src/nvue/plugins/entry.ts b/packages/uni-app-vite/src/nvue/plugins/entry.ts deleted file mode 100644 index e8d49b69a..000000000 --- a/packages/uni-app-vite/src/nvue/plugins/entry.ts +++ /dev/null @@ -1,50 +0,0 @@ -import path from 'path' -import type { Plugin } from 'vite' -import { - decodeBase64Url, - encodeBase64Url, - normalizePath, - polyfillCode, -} from '@dcloudio/uni-cli-shared' - -const uniNVuePagePrefix = 'uniNVuePage://' - -function isUniNVuePageUrl(id: string) { - return id.startsWith(uniNVuePagePrefix) -} - -export function createUniNVuePagePath(pagePath: string) { - return uniNVuePagePrefix + encodeBase64Url(pagePath + '.nvue') -} - -function parseUniNvuePagePath(uniNVuePageUrl: string) { - return decodeBase64Url(uniNVuePageUrl.replace(uniNVuePagePrefix, '')) -} - -export function uniNVueEntryPlugin(): Plugin { - const inputDir = process.env.UNI_INPUT_DIR - return { - name: 'uni:app-nvue-entry', - enforce: 'pre', - resolveId(id) { - if (isUniNVuePageUrl(id)) { - return id - } - }, - load(id) { - if (isUniNVuePageUrl(id)) { - const filepath = normalizePath( - path.resolve(inputDir, parseUniNvuePagePath(id)) - ) - this.addWatchFile(filepath) - return { - code: `import { createApp } from 'vue' -import App from '${filepath}' -${polyfillCode} -createApp(App).mount('#app') -`, - } - } - }, - } -} diff --git a/packages/uni-app-vite/src/nvue/plugins/mainJs.ts b/packages/uni-app-vite/src/nvue/plugins/mainJs.ts new file mode 100644 index 000000000..ff75540fa --- /dev/null +++ b/packages/uni-app-vite/src/nvue/plugins/mainJs.ts @@ -0,0 +1,41 @@ +import { defineUniMainJsPlugin } from '@dcloudio/uni-cli-shared' + +export function uniMainJsPlugin() { + return defineUniMainJsPlugin((opts) => { + return { + name: 'uni:app-nvue-main-js', + enforce: 'pre', + transform(code, id) { + if (opts.filter(id)) { + if (process.env.UNI_RENDERER === 'native') { + code = code.includes('createSSRApp') + ? createApp(code) + : createLegacyApp(code) + return { + code: `import './pages.json.js';` + code, + map: { mappings: '' }, + } + } + return { + code: `import './pages.json.js'`, + map: { mappings: '' }, + } + } + }, + } + }) +} + +function createApp(code: string) { + return `${code.replace( + 'createSSRApp', + 'createVueApp as createSSRApp' + )};const __app__=createApp().app;__app__._component.mpType='app';__app__._component.render=()=>{};__app__.use(uni.__vuePlugin).mount("#app");` +} + +function createLegacyApp(code: string) { + return `function createApp(rootComponent,rootProps){rootComponent.mpTye='app';rootComponent.render=()=>{};const app=createVueApp(rootComponent,rootProps).use(uni.__vuePlugin);const oldMount=app.mount;app.mount=(container)=>{const appVm=oldMount.call(app,container);return appVm;};return app;};${code.replace( + 'createApp', + 'createVueApp' + )}` +} diff --git a/packages/uni-app-vite/src/nvue/plugins/pagesJson.ts b/packages/uni-app-vite/src/nvue/plugins/pagesJson.ts new file mode 100644 index 000000000..cd55ea564 --- /dev/null +++ b/packages/uni-app-vite/src/nvue/plugins/pagesJson.ts @@ -0,0 +1,59 @@ +import path from 'path' +import { Plugin } from 'vite' + +import { + defineUniPagesJsonPlugin, + normalizeAppConfigService, + normalizePagesJson, + parseManifestJsonOnce, + getLocaleFiles, + normalizeAppNVuePagesJson, +} from '@dcloudio/uni-cli-shared' + +export function uniPagesJsonPlugin(): Plugin { + return defineUniPagesJsonPlugin((opts) => { + return { + name: 'uni:app-nvue-pages-json', + enforce: 'pre', + transform(code, id) { + if (!opts.filter(id)) { + return + } + this.addWatchFile(path.resolve(process.env.UNI_INPUT_DIR, 'pages.json')) + getLocaleFiles( + path.resolve(process.env.UNI_INPUT_DIR, 'locale') + ).forEach((filepath) => { + this.addWatchFile(filepath) + }) + const pagesJson = normalizePagesJson(code, process.env.UNI_PLATFORM) + pagesJson.pages.forEach((page) => { + if (page.style.isNVue) { + this.addWatchFile( + path.resolve(process.env.UNI_INPUT_DIR, page.path + '.nvue') + ) + } + }) + if (process.env.UNI_RENDERER === 'native') { + this.emitFile({ + fileName: `app-config-service.js`, + type: 'asset', + source: normalizeAppConfigService( + pagesJson, + parseManifestJsonOnce(process.env.UNI_INPUT_DIR) + ), + }) + return { + code: + `import './manifest.json.js'\n` + + normalizeAppNVuePagesJson(pagesJson), + map: { mappings: '' }, + } + } + return { + code: normalizeAppNVuePagesJson(pagesJson), + map: { mappings: '' }, + } + }, + } + }) +} diff --git a/packages/uni-app-vite/src/plugin/build.ts b/packages/uni-app-vite/src/plugin/build.ts index a74e694ab..14842ed92 100644 --- a/packages/uni-app-vite/src/plugin/build.ts +++ b/packages/uni-app-vite/src/plugin/build.ts @@ -6,7 +6,9 @@ import { emptyDir, isInHybridNVue, normalizePath, + resolveMainPathOnce, } from '@dcloudio/uni-cli-shared' +import { nvueOutDir } from '../utils' export function buildOptions( userConfig: UserConfig, @@ -15,7 +17,12 @@ export function buildOptions( const inputDir = process.env.UNI_INPUT_DIR const outputDir = process.env.UNI_OUTPUT_DIR // 开始编译时,清空输出目录 - if (!isInHybridNVue(userConfig)) { + if (isInHybridNVue(userConfig)) { + const nvueOutputDir = nvueOutDir() + if (fs.existsSync(nvueOutputDir)) { + emptyDir(nvueOutputDir) + } + } else { if (fs.existsSync(outputDir)) { emptyDir(outputDir) } @@ -27,6 +34,7 @@ export function buildOptions( assetsInlineLimit: 0, rollupOptions: { external: ['vue'], + input: resolveMainPathOnce(inputDir), output: { sourcemapPathTransform(relativeSourcePath, sourcemapPath) { const sourcePath = normalizePath( diff --git a/packages/uni-app-vite/src/utils.ts b/packages/uni-app-vite/src/utils.ts index b655ac001..bb1580478 100644 --- a/packages/uni-app-vite/src/utils.ts +++ b/packages/uni-app-vite/src/utils.ts @@ -1,2 +1,5 @@ import path from 'path' export const templateDir = path.resolve(__dirname, '../lib/template/') +export function nvueOutDir() { + return path.join(process.env.UNI_OUTPUT_DIR, '../.nvue') +} diff --git a/packages/uni-app-vite/src/vue/plugin/index.ts b/packages/uni-app-vite/src/vue/plugin/index.ts index 005df574b..ecb2e1e53 100644 --- a/packages/uni-app-vite/src/vue/plugin/index.ts +++ b/packages/uni-app-vite/src/vue/plugin/index.ts @@ -2,7 +2,6 @@ import path from 'path' import fs from 'fs-extra' import { APP_SERVICE_FILENAME, - resolveMainPathOnce, parsePagesJsonOnce, UniVitePlugin, } from '@dcloudio/uni-cli-shared' @@ -13,14 +12,12 @@ import { configResolved } from './configResolved' import { templateDir } from '../../utils' export function uniAppVuePlugin(): UniVitePlugin { - const inputDir = process.env.UNI_INPUT_DIR return { name: 'uni:app-vue', config() { return { build: { rollupOptions: { - input: resolveMainPathOnce(inputDir), output: { name: 'AppService', format: process.env.UNI_APP_CODE_SPLITING ? 'amd' : 'iife', diff --git a/packages/uni-app-vite/src/vue/plugins/mainJs.ts b/packages/uni-app-vite/src/vue/plugins/mainJs.ts index dba9b1d82..16b8a2e30 100644 --- a/packages/uni-app-vite/src/vue/plugins/mainJs.ts +++ b/packages/uni-app-vite/src/vue/plugins/mainJs.ts @@ -3,7 +3,7 @@ import { defineUniMainJsPlugin } from '@dcloudio/uni-cli-shared' export function uniMainJsPlugin() { return defineUniMainJsPlugin((opts) => { return { - name: 'uni:app-main-js', + name: 'uni:app-vue-main-js', enforce: 'pre', transform(code, id) { if (opts.filter(id)) { @@ -12,7 +12,7 @@ export function uniMainJsPlugin() { : createLegacyApp(code) return { code: `import './pages.json.js';` + code, - map: this.getCombinedSourcemap(), + map: { mappings: '' }, } } }, diff --git a/packages/uni-app-vite/src/vue/plugins/pagesJson.ts b/packages/uni-app-vite/src/vue/plugins/pagesJson.ts index 29d92d5ff..cb9672e85 100644 --- a/packages/uni-app-vite/src/vue/plugins/pagesJson.ts +++ b/packages/uni-app-vite/src/vue/plugins/pagesJson.ts @@ -9,12 +9,11 @@ import { parseManifestJsonOnce, getLocaleFiles, } from '@dcloudio/uni-cli-shared' -import { initWebpackNVueEntry } from '@dcloudio/uni-cli-nvue' export function uniPagesJsonPlugin(): Plugin { return defineUniPagesJsonPlugin((opts) => { return { - name: 'uni:app-pages-json', + name: 'uni:app-vue-pages-json', enforce: 'pre', transform(code, id) { if (!opts.filter(id)) { @@ -27,16 +26,12 @@ export function uniPagesJsonPlugin(): Plugin { this.addWatchFile(filepath) }) const pagesJson = normalizePagesJson(code, process.env.UNI_PLATFORM) - - if (process.env.UNI_NVUE_COMPILER !== 'vue') { - initWebpackNVueEntry(pagesJson.pages) - } - - // TODO subpackages pagesJson.pages.forEach((page) => { - this.addWatchFile( - path.resolve(process.env.UNI_INPUT_DIR, page.path + '.vue') - ) + if (!page.style.isNVue) { + this.addWatchFile( + path.resolve(process.env.UNI_INPUT_DIR, page.path + '.vue') + ) + } }) this.emitFile({ fileName: `app-config-service.js`, @@ -49,7 +44,7 @@ export function uniPagesJsonPlugin(): Plugin { return { code: `import './manifest.json.js'\n` + normalizeAppPagesJson(pagesJson), - map: this.getCombinedSourcemap(), + map: { mappings: '' }, } }, } diff --git a/packages/uni-app-vite/src/vue/plugins/renderjs.ts b/packages/uni-app-vite/src/vue/plugins/renderjs.ts index 8257fd542..977ff9d26 100644 --- a/packages/uni-app-vite/src/vue/plugins/renderjs.ts +++ b/packages/uni-app-vite/src/vue/plugins/renderjs.ts @@ -24,7 +24,7 @@ export function uniRenderjsPlugin(): Plugin { let resolvedConfig: ResolvedConfig let changed: boolean = false return { - name: 'uni:app-renderjs', + name: 'uni:app-vue-renderjs', configResolved(config) { resolvedConfig = config wxsModulesCache.set(resolvedConfig, new Map()) @@ -78,7 +78,7 @@ export function uniRenderjsPlugin(): Plugin { ;(Comp.$${type} || (Comp.$${type} = [])).push('${name}') ;(Comp.$${globalName} || (Comp.$${globalName} = {}))['${name}'] = '${moduleHashId}' }`, - map: null, + map: { mappings: '' }, } }, generateBundle() { diff --git a/packages/uni-cli-shared/src/json/app/pages/definePage.ts b/packages/uni-cli-shared/src/json/app/pages/definePage.ts index 0684c12f6..e5ce5f115 100644 --- a/packages/uni-cli-shared/src/json/app/pages/definePage.ts +++ b/packages/uni-cli-shared/src/json/app/pages/definePage.ts @@ -26,3 +26,19 @@ export function definePageCode(pagesJson: Record) { }) return importPagesCode.join('\n') + '\n' + definePagesCode.join('\n') } + +export function defineNVuePageCode(pagesJson: Record) { + const importNVuePagesCode: string[] = [] + pagesJson.pages.forEach((page: UniApp.PagesJsonPageOptions) => { + if (!page.style.isNVue) { + return + } + const pagePathWithExtname = normalizePagePath(page.path, 'app') + if (pagePathWithExtname) { + importNVuePagesCode.push( + `import('./${pagePathWithExtname}').then(()=>{})` + ) + } + }) + return importNVuePagesCode.join('\n') +} diff --git a/packages/uni-cli-shared/src/json/app/pages/index.ts b/packages/uni-cli-shared/src/json/app/pages/index.ts index f5fb9e000..7c59eeb1a 100644 --- a/packages/uni-cli-shared/src/json/app/pages/index.ts +++ b/packages/uni-cli-shared/src/json/app/pages/index.ts @@ -1,5 +1,5 @@ import { globalCode, polyfillCode, restoreGlobalCode } from './code' -import { definePageCode } from './definePage' +import { definePageCode, defineNVuePageCode } from './definePage' import { normalizeAppUniConfig } from './uniConfig' import { normalizeAppUniRoutes } from './uniRoutes' @@ -7,6 +7,10 @@ export function normalizeAppPagesJson(pagesJson: Record) { return polyfillCode + restoreGlobalCode + definePageCode(pagesJson) } +export function normalizeAppNVuePagesJson(pagesJson: Record) { + return defineNVuePageCode(pagesJson) +} + export function normalizeAppConfigService( pagesJson: UniApp.PagesJson, manifestJson: Record diff --git a/packages/uni-cli-shared/src/vite/plugins/dynamicImportPolyfill.ts b/packages/uni-cli-shared/src/vite/plugins/dynamicImportPolyfill.ts new file mode 100644 index 000000000..d31242e89 --- /dev/null +++ b/packages/uni-cli-shared/src/vite/plugins/dynamicImportPolyfill.ts @@ -0,0 +1,12 @@ +import type { Plugin } from 'vite' +export function dynamicImportPolyfill(): Plugin { + return { + name: 'dynamic-import-polyfill', + renderDynamicImport() { + return { + left: '(', + right: ')', + } + }, + } +} diff --git a/packages/uni-cli-shared/src/vite/plugins/index.ts b/packages/uni-cli-shared/src/vite/plugins/index.ts index 86e409f84..4c866c065 100644 --- a/packages/uni-cli-shared/src/vite/plugins/index.ts +++ b/packages/uni-cli-shared/src/vite/plugins/index.ts @@ -4,6 +4,7 @@ export * from './inject' export * from './mainJs' export * from './jsonJs' export * from './console' +export * from './dynamicImportPolyfill' export { assetPlugin, getAssetHash } from './vitejs/plugins/asset' export { diff --git a/packages/uni-mp-vite/src/plugin/build.ts b/packages/uni-mp-vite/src/plugin/build.ts index 22f6edafc..b7e2ef862 100644 --- a/packages/uni-mp-vite/src/plugin/build.ts +++ b/packages/uni-mp-vite/src/plugin/build.ts @@ -14,8 +14,9 @@ import { isCSSRequest, parseManifestJsonOnce, M, + dynamicImportPolyfill, } from '@dcloudio/uni-cli-shared' -import { GetManualChunk, GetModuleInfo, Plugin, PreRenderedChunk } from 'rollup' +import { GetManualChunk, GetModuleInfo, PreRenderedChunk } from 'rollup' import { isUniComponentUrl, isUniPageUrl, @@ -191,18 +192,6 @@ function createChunkFileNames( } } -function dynamicImportPolyfill(): Plugin { - return { - name: 'dynamic-import-polyfill', - renderDynamicImport() { - return { - left: '(', - right: ')', - } - }, - } -} - export function notFound(filename: string): never { console.log() console.error(M['file.notfound'].replace('{file}', filename)) -- GitLab