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

wip(app): nvue

上级 cf107fa8
...@@ -4,13 +4,20 @@ import { ...@@ -4,13 +4,20 @@ import {
uniViteInjectPlugin, uniViteInjectPlugin,
UNI_EASYCOM_EXCLUDE, UNI_EASYCOM_EXCLUDE,
} from '@dcloudio/uni-cli-shared' } from '@dcloudio/uni-cli-shared'
import { uniAppNVuePlugin } from './plugin'
import { uniEasycomPlugin } from '../plugins/easycom' 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() { export function initNVuePlugins() {
return [ return [
uniEasycomPlugin({ exclude: UNI_EASYCOM_EXCLUDE }), uniEasycomPlugin({ exclude: UNI_EASYCOM_EXCLUDE }),
uniHBuilderXConsolePlugin(), uniHBuilderXConsolePlugin(),
uniMainJsPlugin(),
...(process.env.UNI_RENDERER === 'native' ? [uniManifestJsonPlugin()] : []),
uniPagesJsonPlugin(),
uniViteInjectPlugin('uni:app-inject', initAppProvide()), uniViteInjectPlugin('uni:app-inject', initAppProvide()),
uniAppNVuePlugin(), uniAppNVuePlugin(),
] ]
......
import path from 'path' import path from 'path'
import {
dynamicImportPolyfill,
normalizePath,
parseVueRequest,
removeExt,
resolveMainPathOnce,
} from '@dcloudio/uni-cli-shared'
import { PreRenderedChunk } from 'rollup'
import { Plugin } from 'vite' import { Plugin } from 'vite'
import { nvueOutDir } from '../../utils'
export function uniAppNVuePlugin(): Plugin { export function uniAppNVuePlugin(): Plugin {
return { return {
name: 'uni:app-nvue', name: 'uni:app-nvue',
config() { config() {
const inputDir = process.env.UNI_INPUT_DIR
const mainPath = resolveMainPathOnce(inputDir)
return { return {
lib: {
// 必须使用 lib 模式,否则会生成 preload 等代码
fileName: 'main.js',
entry: mainPath,
formats: ['esm'],
},
build: { build: {
outDir: path.join(process.env.UNI_OUTPUT_DIR, '../.nvue'), outDir: nvueOutDir(),
rollupOptions: {}, 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'
}
}
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')
`,
}
}
},
}
}
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'
)}`
}
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: '' },
}
},
}
})
}
...@@ -6,7 +6,9 @@ import { ...@@ -6,7 +6,9 @@ import {
emptyDir, emptyDir,
isInHybridNVue, isInHybridNVue,
normalizePath, normalizePath,
resolveMainPathOnce,
} from '@dcloudio/uni-cli-shared' } from '@dcloudio/uni-cli-shared'
import { nvueOutDir } from '../utils'
export function buildOptions( export function buildOptions(
userConfig: UserConfig, userConfig: UserConfig,
...@@ -15,7 +17,12 @@ export function buildOptions( ...@@ -15,7 +17,12 @@ export function buildOptions(
const inputDir = process.env.UNI_INPUT_DIR const inputDir = process.env.UNI_INPUT_DIR
const outputDir = process.env.UNI_OUTPUT_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)) { if (fs.existsSync(outputDir)) {
emptyDir(outputDir) emptyDir(outputDir)
} }
...@@ -27,6 +34,7 @@ export function buildOptions( ...@@ -27,6 +34,7 @@ export function buildOptions(
assetsInlineLimit: 0, assetsInlineLimit: 0,
rollupOptions: { rollupOptions: {
external: ['vue'], external: ['vue'],
input: resolveMainPathOnce(inputDir),
output: { output: {
sourcemapPathTransform(relativeSourcePath, sourcemapPath) { sourcemapPathTransform(relativeSourcePath, sourcemapPath) {
const sourcePath = normalizePath( const sourcePath = normalizePath(
......
import path from 'path' import path from 'path'
export const templateDir = path.resolve(__dirname, '../lib/template/') export const templateDir = path.resolve(__dirname, '../lib/template/')
export function nvueOutDir() {
return path.join(process.env.UNI_OUTPUT_DIR, '../.nvue')
}
...@@ -2,7 +2,6 @@ import path from 'path' ...@@ -2,7 +2,6 @@ import path from 'path'
import fs from 'fs-extra' import fs from 'fs-extra'
import { import {
APP_SERVICE_FILENAME, APP_SERVICE_FILENAME,
resolveMainPathOnce,
parsePagesJsonOnce, parsePagesJsonOnce,
UniVitePlugin, UniVitePlugin,
} from '@dcloudio/uni-cli-shared' } from '@dcloudio/uni-cli-shared'
...@@ -13,14 +12,12 @@ import { configResolved } from './configResolved' ...@@ -13,14 +12,12 @@ import { configResolved } from './configResolved'
import { templateDir } from '../../utils' import { templateDir } from '../../utils'
export function uniAppVuePlugin(): UniVitePlugin { export function uniAppVuePlugin(): UniVitePlugin {
const inputDir = process.env.UNI_INPUT_DIR
return { return {
name: 'uni:app-vue', name: 'uni:app-vue',
config() { config() {
return { return {
build: { build: {
rollupOptions: { rollupOptions: {
input: resolveMainPathOnce(inputDir),
output: { output: {
name: 'AppService', name: 'AppService',
format: process.env.UNI_APP_CODE_SPLITING ? 'amd' : 'iife', format: process.env.UNI_APP_CODE_SPLITING ? 'amd' : 'iife',
......
...@@ -3,7 +3,7 @@ import { defineUniMainJsPlugin } from '@dcloudio/uni-cli-shared' ...@@ -3,7 +3,7 @@ import { defineUniMainJsPlugin } from '@dcloudio/uni-cli-shared'
export function uniMainJsPlugin() { export function uniMainJsPlugin() {
return defineUniMainJsPlugin((opts) => { return defineUniMainJsPlugin((opts) => {
return { return {
name: 'uni:app-main-js', name: 'uni:app-vue-main-js',
enforce: 'pre', enforce: 'pre',
transform(code, id) { transform(code, id) {
if (opts.filter(id)) { if (opts.filter(id)) {
...@@ -12,7 +12,7 @@ export function uniMainJsPlugin() { ...@@ -12,7 +12,7 @@ export function uniMainJsPlugin() {
: createLegacyApp(code) : createLegacyApp(code)
return { return {
code: `import './pages.json.js';` + code, code: `import './pages.json.js';` + code,
map: this.getCombinedSourcemap(), map: { mappings: '' },
} }
} }
}, },
......
...@@ -9,12 +9,11 @@ import { ...@@ -9,12 +9,11 @@ import {
parseManifestJsonOnce, parseManifestJsonOnce,
getLocaleFiles, getLocaleFiles,
} from '@dcloudio/uni-cli-shared' } from '@dcloudio/uni-cli-shared'
import { initWebpackNVueEntry } from '@dcloudio/uni-cli-nvue'
export function uniPagesJsonPlugin(): Plugin { export function uniPagesJsonPlugin(): Plugin {
return defineUniPagesJsonPlugin((opts) => { return defineUniPagesJsonPlugin((opts) => {
return { return {
name: 'uni:app-pages-json', name: 'uni:app-vue-pages-json',
enforce: 'pre', enforce: 'pre',
transform(code, id) { transform(code, id) {
if (!opts.filter(id)) { if (!opts.filter(id)) {
...@@ -27,16 +26,12 @@ export function uniPagesJsonPlugin(): Plugin { ...@@ -27,16 +26,12 @@ export function uniPagesJsonPlugin(): Plugin {
this.addWatchFile(filepath) this.addWatchFile(filepath)
}) })
const pagesJson = normalizePagesJson(code, process.env.UNI_PLATFORM) const pagesJson = normalizePagesJson(code, process.env.UNI_PLATFORM)
if (process.env.UNI_NVUE_COMPILER !== 'vue') {
initWebpackNVueEntry(pagesJson.pages)
}
// TODO subpackages
pagesJson.pages.forEach((page) => { pagesJson.pages.forEach((page) => {
this.addWatchFile( if (!page.style.isNVue) {
path.resolve(process.env.UNI_INPUT_DIR, page.path + '.vue') this.addWatchFile(
) path.resolve(process.env.UNI_INPUT_DIR, page.path + '.vue')
)
}
}) })
this.emitFile({ this.emitFile({
fileName: `app-config-service.js`, fileName: `app-config-service.js`,
...@@ -49,7 +44,7 @@ export function uniPagesJsonPlugin(): Plugin { ...@@ -49,7 +44,7 @@ export function uniPagesJsonPlugin(): Plugin {
return { return {
code: code:
`import './manifest.json.js'\n` + normalizeAppPagesJson(pagesJson), `import './manifest.json.js'\n` + normalizeAppPagesJson(pagesJson),
map: this.getCombinedSourcemap(), map: { mappings: '' },
} }
}, },
} }
......
...@@ -24,7 +24,7 @@ export function uniRenderjsPlugin(): Plugin { ...@@ -24,7 +24,7 @@ export function uniRenderjsPlugin(): Plugin {
let resolvedConfig: ResolvedConfig let resolvedConfig: ResolvedConfig
let changed: boolean = false let changed: boolean = false
return { return {
name: 'uni:app-renderjs', name: 'uni:app-vue-renderjs',
configResolved(config) { configResolved(config) {
resolvedConfig = config resolvedConfig = config
wxsModulesCache.set(resolvedConfig, new Map<string, string>()) wxsModulesCache.set(resolvedConfig, new Map<string, string>())
...@@ -78,7 +78,7 @@ export function uniRenderjsPlugin(): Plugin { ...@@ -78,7 +78,7 @@ export function uniRenderjsPlugin(): Plugin {
;(Comp.$${type} || (Comp.$${type} = [])).push('${name}') ;(Comp.$${type} || (Comp.$${type} = [])).push('${name}')
;(Comp.$${globalName} || (Comp.$${globalName} = {}))['${name}'] = '${moduleHashId}' ;(Comp.$${globalName} || (Comp.$${globalName} = {}))['${name}'] = '${moduleHashId}'
}`, }`,
map: null, map: { mappings: '' },
} }
}, },
generateBundle() { generateBundle() {
......
...@@ -26,3 +26,19 @@ export function definePageCode(pagesJson: Record<string, any>) { ...@@ -26,3 +26,19 @@ export function definePageCode(pagesJson: Record<string, any>) {
}) })
return importPagesCode.join('\n') + '\n' + definePagesCode.join('\n') return importPagesCode.join('\n') + '\n' + definePagesCode.join('\n')
} }
export function defineNVuePageCode(pagesJson: Record<string, any>) {
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')
}
import { globalCode, polyfillCode, restoreGlobalCode } from './code' import { globalCode, polyfillCode, restoreGlobalCode } from './code'
import { definePageCode } from './definePage' import { definePageCode, defineNVuePageCode } from './definePage'
import { normalizeAppUniConfig } from './uniConfig' import { normalizeAppUniConfig } from './uniConfig'
import { normalizeAppUniRoutes } from './uniRoutes' import { normalizeAppUniRoutes } from './uniRoutes'
...@@ -7,6 +7,10 @@ export function normalizeAppPagesJson(pagesJson: Record<string, any>) { ...@@ -7,6 +7,10 @@ export function normalizeAppPagesJson(pagesJson: Record<string, any>) {
return polyfillCode + restoreGlobalCode + definePageCode(pagesJson) return polyfillCode + restoreGlobalCode + definePageCode(pagesJson)
} }
export function normalizeAppNVuePagesJson(pagesJson: Record<string, any>) {
return defineNVuePageCode(pagesJson)
}
export function normalizeAppConfigService( export function normalizeAppConfigService(
pagesJson: UniApp.PagesJson, pagesJson: UniApp.PagesJson,
manifestJson: Record<string, any> manifestJson: Record<string, any>
......
import type { Plugin } from 'vite'
export function dynamicImportPolyfill(): Plugin {
return {
name: 'dynamic-import-polyfill',
renderDynamicImport() {
return {
left: '(',
right: ')',
}
},
}
}
...@@ -4,6 +4,7 @@ export * from './inject' ...@@ -4,6 +4,7 @@ export * from './inject'
export * from './mainJs' export * from './mainJs'
export * from './jsonJs' export * from './jsonJs'
export * from './console' export * from './console'
export * from './dynamicImportPolyfill'
export { assetPlugin, getAssetHash } from './vitejs/plugins/asset' export { assetPlugin, getAssetHash } from './vitejs/plugins/asset'
export { export {
......
...@@ -14,8 +14,9 @@ import { ...@@ -14,8 +14,9 @@ import {
isCSSRequest, isCSSRequest,
parseManifestJsonOnce, parseManifestJsonOnce,
M, M,
dynamicImportPolyfill,
} from '@dcloudio/uni-cli-shared' } from '@dcloudio/uni-cli-shared'
import { GetManualChunk, GetModuleInfo, Plugin, PreRenderedChunk } from 'rollup' import { GetManualChunk, GetModuleInfo, PreRenderedChunk } from 'rollup'
import { import {
isUniComponentUrl, isUniComponentUrl,
isUniPageUrl, isUniPageUrl,
...@@ -191,18 +192,6 @@ function createChunkFileNames( ...@@ -191,18 +192,6 @@ function createChunkFileNames(
} }
} }
function dynamicImportPolyfill(): Plugin {
return {
name: 'dynamic-import-polyfill',
renderDynamicImport() {
return {
left: '(',
right: ')',
}
},
}
}
export function notFound(filename: string): never { export function notFound(filename: string): never {
console.log() console.log()
console.error(M['file.notfound'].replace('{file}', filename)) console.error(M['file.notfound'].replace('{file}', filename))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册