From 824cf7e658dc5feff86f9ff2f1b4ad2cf79aecb0 Mon Sep 17 00:00:00 2001 From: fxy060608 Date: Tue, 11 Jan 2022 21:10:04 +0800 Subject: [PATCH] wip(app): nvue --- packages/shims-node.d.ts | 1 + .../__tests__/service/index.spec.ts | 2 +- packages/uni-app-vite/src/index.ts | 73 +---------- packages/uni-app-vite/src/nvue/index.ts | 17 +-- .../uni-app-vite/src/nvue/plugin/index.ts | 15 +++ .../uni-app-vite/src/nvue/rollup/index.ts | 35 ----- packages/uni-app-vite/src/vue/index.ts | 57 ++++++++ .../src/{ => vue}/plugin/build.ts | 0 .../src/{ => vue}/plugin/configResolved.ts | 0 .../src/{ => vue}/plugin/index.ts | 0 .../src/{ => vue}/plugin/uni/index.ts | 0 .../uni/transforms/transformRenderjs.ts | 0 packages/uni-cli-shared/src/logs/format.ts | 34 ++++- packages/vite-plugin-uni/src/cli/build.ts | 124 ++++++++++++++++-- .../src/configResolved/index.ts | 5 +- 15 files changed, 230 insertions(+), 133 deletions(-) create mode 100644 packages/uni-app-vite/src/nvue/plugin/index.ts delete mode 100644 packages/uni-app-vite/src/nvue/rollup/index.ts create mode 100644 packages/uni-app-vite/src/vue/index.ts rename packages/uni-app-vite/src/{ => vue}/plugin/build.ts (100%) rename packages/uni-app-vite/src/{ => vue}/plugin/configResolved.ts (100%) rename packages/uni-app-vite/src/{ => vue}/plugin/index.ts (100%) rename packages/uni-app-vite/src/{ => vue}/plugin/uni/index.ts (100%) rename packages/uni-app-vite/src/{ => vue}/plugin/uni/transforms/transformRenderjs.ts (100%) diff --git a/packages/shims-node.d.ts b/packages/shims-node.d.ts index 602325500..3376084fd 100644 --- a/packages/shims-node.d.ts +++ b/packages/shims-node.d.ts @@ -26,5 +26,6 @@ declare namespace NodeJS { UNI_CUSTOM_DEFINE?: string UNI_CUSTOM_CONTEXT?: string UNI_MINIMIZE?: 'true' + UNI_COMPILER: 'vue' | 'nvue' } } diff --git a/packages/uni-app-plus/__tests__/service/index.spec.ts b/packages/uni-app-plus/__tests__/service/index.spec.ts index acb388863..4ea036ecf 100644 --- a/packages/uni-app-plus/__tests__/service/index.spec.ts +++ b/packages/uni-app-plus/__tests__/service/index.spec.ts @@ -1,6 +1,6 @@ import { compileTemplate } from '@vue/compiler-sfc' -import { uniAppPlugin } from '../../../uni-app-vite/src/plugin' +import { uniAppPlugin } from '../../../uni-app-vite/src/vue/plugin' import { ref, nextTick, diff --git a/packages/uni-app-vite/src/index.ts b/packages/uni-app-vite/src/index.ts index e6162ee86..241c9ee1a 100644 --- a/packages/uni-app-vite/src/index.ts +++ b/packages/uni-app-vite/src/index.ts @@ -1,68 +1,7 @@ -import { - initAppProvide, - uniViteInjectPlugin, - uniCssScopedPlugin, - getAppStyleIsolation, - parseManifestJsonOnce, - uniHBuilderXConsolePlugin, - UNI_EASYCOM_EXCLUDE, - isVueSfcFile, - isUniPageFile, -} from '@dcloudio/uni-cli-shared' -import { plugins as nvuePlugins } from '@dcloudio/uni-cli-nvue' -import { uniAppPlugin } from './plugin' -import { uniTemplatePlugin } from './plugins/template' -import { uniMainJsPlugin } from './plugins/mainJs' -import { uniManifestJsonPlugin } from './plugins/manifestJson' -import { uniPagesJsonPlugin } from './plugins/pagesJson' -// import { uniResolveIdPlugin } from './plugins/resolveId' -import { uniRenderjsPlugin } from './plugins/renderjs' -import { uniStatsPlugin } from './plugins/stats' -import { uniEasycomPlugin } from './plugins/easycom' -import { uniConfusionPlugin } from './plugins/confusion' -import { uniNVuePlugin } from './nvue' -import { uniNVueEntryPlugin } from './nvue/plugins/entry' - -function initUniCssScopedPluginFilter( - inputDir: string -): void | ((id: string) => boolean) { - const styleIsolation = getAppStyleIsolation(parseManifestJsonOnce(inputDir)) - if (styleIsolation === 'shared') { - return - } - if (styleIsolation === 'isolated') { - // isolated: 对所有非 App.vue 增加 scoped - return (id) => isVueSfcFile(id) && !id.endsWith('App.vue') - } - // apply-shared: 仅对非页面组件增加 scoped - return (id) => - isVueSfcFile(id) && !id.endsWith('App.vue') && !isUniPageFile(id, inputDir) +import { initVuePlugins } from './vue' +import { initNVuePlugins } from './nvue' +export default () => { + return process.env.UNI_COMPILER === 'nvue' + ? initNVuePlugins() + : initVuePlugins() } - -const plugins = [ - uniEasycomPlugin({ exclude: UNI_EASYCOM_EXCLUDE }), - // uniResolveIdPlugin(), - uniHBuilderXConsolePlugin(), - uniMainJsPlugin(), - uniManifestJsonPlugin(), - uniPagesJsonPlugin(), - uniViteInjectPlugin(initAppProvide()), - uniRenderjsPlugin(), - uniTemplatePlugin(), - uniStatsPlugin(), - uniAppPlugin(), - uniConfusionPlugin(), -] - -const filter = initUniCssScopedPluginFilter(process.env.UNI_INPUT_DIR) -if (filter) { - plugins.unshift(uniCssScopedPlugin({ filter })) -} -if (process.env.UNI_NVUE_COMPILER === 'vite') { - plugins.push(uniNVuePlugin('pages/demo/demo')) - plugins.push(uniNVueEntryPlugin()) -} else if (process.env.UNI_NVUE_COMPILER !== 'vue') { - plugins.push(...nvuePlugins) -} - -export default plugins diff --git a/packages/uni-app-vite/src/nvue/index.ts b/packages/uni-app-vite/src/nvue/index.ts index 577c80724..4e943722f 100644 --- a/packages/uni-app-vite/src/nvue/index.ts +++ b/packages/uni-app-vite/src/nvue/index.ts @@ -1,14 +1,5 @@ -import { Plugin } from 'vite' -import { createRollupOptions } from './rollup' -export function uniNVuePlugin(pagePath: string): Plugin { - return { - name: 'vite:uni-app-nvue', - config() { - return { - build: { - rollupOptions: createRollupOptions(pagePath), - }, - } - }, - } +import { uniNVuePlugin } from './plugin' + +export function initNVuePlugins() { + return [uniNVuePlugin()] } diff --git a/packages/uni-app-vite/src/nvue/plugin/index.ts b/packages/uni-app-vite/src/nvue/plugin/index.ts new file mode 100644 index 000000000..c9046fe5a --- /dev/null +++ b/packages/uni-app-vite/src/nvue/plugin/index.ts @@ -0,0 +1,15 @@ +import path from 'path' +import { Plugin } from 'vite' +export function uniNVuePlugin(): Plugin { + return { + name: 'vite:uni-app-nvue', + config() { + return { + build: { + outDir: path.join(process.env.UNI_OUTPUT_DIR, '../.nvue'), + rollupOptions: {}, + }, + } + }, + } +} diff --git a/packages/uni-app-vite/src/nvue/rollup/index.ts b/packages/uni-app-vite/src/nvue/rollup/index.ts deleted file mode 100644 index ff5be405c..000000000 --- a/packages/uni-app-vite/src/nvue/rollup/index.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { RollupOptions } from 'rollup' -import vue from '@vitejs/plugin-vue' -import { EXTNAME_VUE_RE, removeExt } from '@dcloudio/uni-cli-shared' -import { isBuiltInComponent } from '@dcloudio/uni-shared' -import { createUniNVuePagePath } from '../plugins/entry' - -export function createRollupOptions(pagePath: string): RollupOptions { - return { - input: createUniNVuePagePath(pagePath), - context: 'global', - external: ['vue'], - preserveEntrySignatures: false, - output: { - dir: process.env.UNI_OUTPUT_DIR, - file: removeExt(pagePath) + '.js', - format: 'iife', - exports: 'auto', - sourcemap: false, - globals: { vue: 'Vue' }, - }, - plugins: [ - vue({ - include: [EXTNAME_VUE_RE], - isProduction: process.env.NODE_ENV === 'production', - // reactivityTransform: true, - template: { - compilerOptions: { - // TODO - isNativeTag: isBuiltInComponent, - }, - }, - }), - ], - } -} diff --git a/packages/uni-app-vite/src/vue/index.ts b/packages/uni-app-vite/src/vue/index.ts new file mode 100644 index 000000000..e18d53a26 --- /dev/null +++ b/packages/uni-app-vite/src/vue/index.ts @@ -0,0 +1,57 @@ +import { + initAppProvide, + uniViteInjectPlugin, + uniCssScopedPlugin, + getAppStyleIsolation, + parseManifestJsonOnce, + uniHBuilderXConsolePlugin, + UNI_EASYCOM_EXCLUDE, + isVueSfcFile, + isUniPageFile, +} from '@dcloudio/uni-cli-shared' +import { uniAppPlugin } from '../vue/plugin' +import { uniTemplatePlugin } from '../plugins/template' +import { uniMainJsPlugin } from '../plugins/mainJs' +import { uniManifestJsonPlugin } from '../plugins/manifestJson' +import { uniPagesJsonPlugin } from '../plugins/pagesJson' +import { uniRenderjsPlugin } from '../plugins/renderjs' +import { uniStatsPlugin } from '../plugins/stats' +import { uniEasycomPlugin } from '../plugins/easycom' +import { uniConfusionPlugin } from '../plugins/confusion' + +function initUniCssScopedPluginFilter( + inputDir: string +): void | ((id: string) => boolean) { + const styleIsolation = getAppStyleIsolation(parseManifestJsonOnce(inputDir)) + if (styleIsolation === 'shared') { + return + } + if (styleIsolation === 'isolated') { + // isolated: 对所有非 App.vue 增加 scoped + return (id) => isVueSfcFile(id) && !id.endsWith('App.vue') + } + // apply-shared: 仅对非页面组件增加 scoped + return (id) => + isVueSfcFile(id) && !id.endsWith('App.vue') && !isUniPageFile(id, inputDir) +} + +export function initVuePlugins() { + const plugins = [ + uniEasycomPlugin({ exclude: UNI_EASYCOM_EXCLUDE }), + uniHBuilderXConsolePlugin(), + uniMainJsPlugin(), + uniManifestJsonPlugin(), + uniPagesJsonPlugin(), + uniViteInjectPlugin(initAppProvide()), + uniRenderjsPlugin(), + uniTemplatePlugin(), + uniStatsPlugin(), + uniAppPlugin(), + uniConfusionPlugin(), + ] + const filter = initUniCssScopedPluginFilter(process.env.UNI_INPUT_DIR) + if (filter) { + plugins.unshift(uniCssScopedPlugin({ filter })) + } + return plugins +} diff --git a/packages/uni-app-vite/src/plugin/build.ts b/packages/uni-app-vite/src/vue/plugin/build.ts similarity index 100% rename from packages/uni-app-vite/src/plugin/build.ts rename to packages/uni-app-vite/src/vue/plugin/build.ts diff --git a/packages/uni-app-vite/src/plugin/configResolved.ts b/packages/uni-app-vite/src/vue/plugin/configResolved.ts similarity index 100% rename from packages/uni-app-vite/src/plugin/configResolved.ts rename to packages/uni-app-vite/src/vue/plugin/configResolved.ts diff --git a/packages/uni-app-vite/src/plugin/index.ts b/packages/uni-app-vite/src/vue/plugin/index.ts similarity index 100% rename from packages/uni-app-vite/src/plugin/index.ts rename to packages/uni-app-vite/src/vue/plugin/index.ts diff --git a/packages/uni-app-vite/src/plugin/uni/index.ts b/packages/uni-app-vite/src/vue/plugin/uni/index.ts similarity index 100% rename from packages/uni-app-vite/src/plugin/uni/index.ts rename to packages/uni-app-vite/src/vue/plugin/uni/index.ts diff --git a/packages/uni-app-vite/src/plugin/uni/transforms/transformRenderjs.ts b/packages/uni-app-vite/src/vue/plugin/uni/transforms/transformRenderjs.ts similarity index 100% rename from packages/uni-app-vite/src/plugin/uni/transforms/transformRenderjs.ts rename to packages/uni-app-vite/src/vue/plugin/uni/transforms/transformRenderjs.ts diff --git a/packages/uni-cli-shared/src/logs/format.ts b/packages/uni-cli-shared/src/logs/format.ts index 3ab9a13db..69f03e46e 100644 --- a/packages/uni-cli-shared/src/logs/format.ts +++ b/packages/uni-cli-shared/src/logs/format.ts @@ -52,12 +52,44 @@ export function formatErrMsg(msg: string, options?: LogErrorOptions) { return msg } -export function formatInfoMsg(msg: string, options?: LogOptions) { +const REMOVED_NVUE_MSGS = [ + (msg: string) => { + // vite v2.7.10 building for development... (x2) + return msg.includes('vite v') && msg.includes('building ') + }, +] + +export const removeNVueInfoFormatter: Formatter = { + test(msg) { + return !!REMOVED_NVUE_MSGS.find((m) => + typeof m === 'string' ? msg.includes(m) : m(msg) + ) + }, + format() { + return '' + }, +} +const nvueInfoFormatters: Formatter[] = [] +const initNVueInfoFormattersOnce = once(() => { + nvueInfoFormatters.push(removeNVueInfoFormatter) +}) + +export function formatInfoMsg( + msg: string, + options?: LogOptions & { nvue?: boolean } +) { initInfoFormattersOnce() const formatter = infoFormatters.find(({ test }) => test(msg, options)) if (formatter) { return formatter.format(msg, options) } + if (options?.nvue) { + initNVueInfoFormattersOnce() + const formatter = nvueInfoFormatters.find(({ test }) => test(msg, options)) + if (formatter) { + return formatter.format(msg, options) + } + } return msg } diff --git a/packages/vite-plugin-uni/src/cli/build.ts b/packages/vite-plugin-uni/src/cli/build.ts index 518e09139..258787d69 100644 --- a/packages/vite-plugin-uni/src/cli/build.ts +++ b/packages/vite-plugin-uni/src/cli/build.ts @@ -1,6 +1,11 @@ import path from 'path' import fs from 'fs-extra' -import { build as buildByVite, BuildOptions, InlineConfig } from 'vite' +import { + build as buildByVite, + BuildOptions, + InlineConfig, + ServerOptions, +} from 'vite' import { extend } from '@vue/shared' import { initPreContext, @@ -10,22 +15,11 @@ import { } from '@dcloudio/uni-cli-shared' import { CliOptions } from '.' import { addConfigFile, cleanOptions } from './utils' +import { RollupWatcher, RollupWatcherEvent } from 'rollup' export async function build(options: CliOptions) { if (options.platform === 'app') { - if ((options as BuildOptions).manifest) { - return buildManifestJson() - } - if (process.env.UNI_RENDERER === 'native') { - return buildByVite( - addConfigFile( - extend( - { nvue: true }, - initBuildOptions(options, cleanOptions(options) as BuildOptions) - ) - ) - ) - } + return buildApp(options) } return buildByVite( addConfigFile( @@ -99,3 +93,105 @@ function buildManifestJson() { JSON.stringify(manifestJson, null, 2) ) } + +export async function buildApp(options: CliOptions) { + if ((options as BuildOptions).manifest) { + return buildManifestJson() + } + if (process.env.UNI_RENDERER === 'native') { + return buildByVite( + addConfigFile( + extend( + { nvue: true }, + initBuildOptions(options, cleanOptions(options) as BuildOptions) + ) + ) + ) + } + // 指定为 vue 方便 App 插件初始化 vue 所需插件列表 + process.env.UNI_COMPILER = 'vue' + const vueBuilder = await buildByVite( + addConfigFile( + initBuildOptions(options, cleanOptions(options) as BuildOptions) + ) + ) + // 临时指定为 nvue 方便 App 插件初始化 nvue 所需插件列表 + process.env.UNI_COMPILER = 'nvue' + const nvueBuilder = await buildByVite( + addConfigFile( + extend( + { nvue: true }, + initBuildOptions(options, cleanOptions(options) as BuildOptions) + ) + ) + ) + // 还原为 vue + process.env.UNI_COMPILER = 'vue' + + if ((options as ServerOptions).watch) { + return initAppWatcher( + vueBuilder as RollupWatcher, + nvueBuilder as RollupWatcher + ) + } +} + +class AppWatcher { + private _vueStart: boolean = false + private _vueEnd: boolean = false + private _nvueStart: boolean = false + private _nvueEnd: boolean = false + private _callback!: (event: RollupWatcherEvent) => void + on(callback: (event: RollupWatcherEvent) => void) { + this._callback = callback + } + _bundleVueStart(event: RollupWatcherEvent) { + this._vueStart = true + this._bundleStart(event) + } + _bundleVueEnd(event: RollupWatcherEvent) { + this._vueEnd = true + this._bundleEnd(event) + } + _bundleNVueStart(event: RollupWatcherEvent) { + this._nvueStart = true + this._bundleStart(event) + } + _bundleNVueEnd(event: RollupWatcherEvent) { + this._nvueEnd = true + this._bundleEnd(event) + } + _bundleStart(event: RollupWatcherEvent) { + if (this._vueStart && this._nvueStart) { + this._callback(event) + } + } + _bundleEnd(event: RollupWatcherEvent) { + if (this._vueEnd && this._nvueEnd) { + this._callback(event) + } + } +} + +function initAppWatcher(vueWatcher: RollupWatcher, nvueWatcher: RollupWatcher) { + const appWatcher = new AppWatcher() + vueWatcher.on('event', (event) => { + if (event.code === 'BUNDLE_START') { + appWatcher._bundleVueStart(event) + } else if (event.code === 'BUNDLE_END') { + appWatcher._bundleVueEnd(event) + } + }) + nvueWatcher.on('event', (event) => { + if (event.code === 'BUNDLE_START') { + appWatcher._bundleNVueStart(event) + } else if (event.code === 'BUNDLE_END') { + appWatcher._bundleNVueEnd(event) + } + }) + return { + on(_, fn) { + appWatcher.on(fn as (event: RollupWatcherEvent) => void) + }, + } as RollupWatcher +} diff --git a/packages/vite-plugin-uni/src/configResolved/index.ts b/packages/vite-plugin-uni/src/configResolved/index.ts index b8c69c79d..247bc6018 100644 --- a/packages/vite-plugin-uni/src/configResolved/index.ts +++ b/packages/vite-plugin-uni/src/configResolved/index.ts @@ -1,4 +1,5 @@ import { Plugin, ResolvedConfig } from 'vite' +import { extend } from '@vue/shared' import { checkUpdate, isWindows, @@ -40,10 +41,10 @@ function initCheckUpdate() { }) } -function initLogger({ logger }: ResolvedConfig) { +function initLogger({ logger, nvue }: ResolvedConfig & { nvue?: boolean }) { const { info, warn, error } = logger logger.info = (msg, opts) => { - msg = formatInfoMsg(msg, opts) + msg = formatInfoMsg(msg, extend({ nvue }, opts)) if (msg) { return info(msg, opts) } -- GitLab