提交 824cf7e6 编写于 作者: fxy060608's avatar fxy060608

wip(app): nvue

上级 3fc1d5a9
......@@ -26,5 +26,6 @@ declare namespace NodeJS {
UNI_CUSTOM_DEFINE?: string
UNI_CUSTOM_CONTEXT?: string
UNI_MINIMIZE?: 'true'
UNI_COMPILER: 'vue' | 'nvue'
}
}
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,
......
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
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()]
}
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: {},
},
}
},
}
}
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,
},
},
}),
],
}
}
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
}
......@@ -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
}
......
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
}
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)
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册