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

wip(app): nvue

上级 8cf598ff
......@@ -28,5 +28,6 @@ declare namespace NodeJS {
UNI_MINIMIZE?: 'true'
UNI_COMPILER: 'vue' | 'nvue'
UNI_RENDERER_NATIVE: 'appService' | 'pages'
UNI_NVUE_APP_STYLES: string
}
}
......@@ -9,7 +9,13 @@ import {
SFCBlock,
SFCDescriptor,
} from '@vue/compiler-sfc'
import { hash, preNVueHtml, preNVueJs } from '@dcloudio/uni-cli-shared'
import {
hash,
normalizePath,
parseVueRequest,
preNVueHtml,
preNVueJs,
} from '@dcloudio/uni-cli-shared'
declare module '@vue/compiler-sfc' {
interface SFCDescriptor {
......@@ -20,8 +26,13 @@ declare module '@vue/compiler-sfc' {
export const APP_CSS_JS = './app.css.js'
export function uniAppCssPlugin(): Plugin {
const inputDir = process.env.UNI_INPUT_DIR
const appVueFilename = normalizePath(path.resolve(inputDir, 'App.vue'))
return {
name: 'uni:app-nvue-app-style',
// 提前到 @vite/plugin-vue 之前执行,因为在 nvue 编译时,仅 import 了 App.vue 的 styles,这样导致 descriptor
// 一直使用的是上一次的(plugin-vue 会在 transformMain 中生成新的 descriptor),故不再交由 plugin-vue 来 load
// 而是当前插件直接处理
enforce: 'pre',
resolveId(id) {
if (id === APP_CSS_JS) {
return APP_CSS_JS
......@@ -29,19 +40,30 @@ export function uniAppCssPlugin(): Plugin {
},
load(id) {
if (id === APP_CSS_JS) {
return genAppStylesCode(inputDir, this)
return genAppStylesCode(appVueFilename, this)
}
const { filename, query } = parseVueRequest(id)
if (query.vue && query.type === 'style' && appVueFilename === filename) {
const descriptor = createAppDescriptor(filename, this)
const block = descriptor.styles[query.index!]
if (block) {
return {
code: block.content,
map: '',
}
}
}
},
}
}
const defaultAppStylesCode = `export const AppStyles = []`
const defaultAppStylesCode = `exports.styles = []`
async function genAppStylesCode(
inputDir: string,
filename: string,
pluginContext: PluginContext
) {
const filename = path.resolve(inputDir, 'App.vue')
pluginContext.addWatchFile(filename)
const descriptor = createAppDescriptor(filename, pluginContext)
if (!descriptor.styles.length) {
return defaultAppStylesCode
......@@ -58,8 +80,9 @@ async function genAppStylesCode(
stylesCode += `\nimport _style_${i} from ${JSON.stringify(styleRequest)}`
styleVars.push(`_style_${i}`)
}
return `${stylesCode}
export const AppStyles = [${styleVars.join(',')}]
return `
${stylesCode}
exports.styles = [${styleVars.join(',')}]
`
}
......
......@@ -5,7 +5,11 @@ import path from 'path'
import fs from 'fs-extra'
import debug from 'debug'
import { removeExt, transformWithEsbuild } from '@dcloudio/uni-cli-shared'
import {
APP_CONFIG_SERVICE,
removeExt,
transformWithEsbuild,
} from '@dcloudio/uni-cli-shared'
import { nvueOutDir } from '../../utils'
import { esbuildGlobals } from '../utils'
......@@ -14,7 +18,6 @@ import { APP_CSS_JS } from './appCss'
const debugEsbuild = debug('uni:app-nvue-esbuild')
export function uniEsbuildPlugin({
renderer,
appService,
}: {
renderer?: 'native'
......@@ -49,9 +52,13 @@ export function uniEsbuildPlugin({
entryPoints.push(name)
}
})
if (!entryPoints.length) {
return
}
buildAppCss()
debugEsbuild('start', entryPoints.length, entryPoints)
for (const filename of entryPoints) {
await buildNVuePage(renderer, filename, buildOptions).then((code) => {
await buildNVuePage(filename, buildOptions).then((code) => {
return fs.outputFile(path.resolve(outputDir, filename), code)
})
}
......@@ -60,18 +67,42 @@ export function uniEsbuildPlugin({
}
}
function buildNVuePage(
renderer: 'native' | undefined,
filename: string,
options: BuildOptions
) {
/**
* 将 nvue 全局 css 样式注入 app-config-service.js
* @returns
*/
function buildAppCss() {
const appCssJsFilename = path.join(nvueOutDir(), APP_CSS_JS)
if (!fs.existsSync(appCssJsFilename)) {
return
}
const appConfigServiceFilename = path.join(
process.env.UNI_OUTPUT_DIR,
APP_CONFIG_SERVICE
)
if (!fs.existsSync(appConfigServiceFilename)) {
return
}
const appCssJsCode = fs.readFileSync(appCssJsFilename, 'utf8')
const appCssJsFn = new Function('exports', appCssJsCode)
const exports = { styles: [] }
appCssJsFn(exports)
const appCssJsonCode = JSON.stringify(exports.styles)
if (process.env.UNI_NVUE_APP_STYLES === appCssJsonCode) {
return
}
process.env.UNI_NVUE_APP_STYLES = appCssJsonCode
const appConfigServiceCode = fs.readFileSync(appConfigServiceFilename, 'utf8')
fs.writeFileSync(
appConfigServiceFilename,
wrapperNVueAppStyles(appConfigServiceCode)
)
}
function buildNVuePage(filename: string, options: BuildOptions) {
return transformWithEsbuild(
`import App from './${filename}'
${
renderer === 'native'
? 'const AppStyles = __uniConfig.styles || []'
: `import { AppStyles } from '${APP_CSS_JS}'`
}
const webview = plus.webview.currentWebview()
const __pageId = parseInt(webview.id)
const __pagePath = '${removeExt(filename)}'
......@@ -79,7 +110,7 @@ let __pageQuery = {}
try{ __pageQuery = JSON.parse(webview.__query__) }catch(e){}
App.mpType = 'page'
const app = Vue.createPageApp(App,{$store:getApp().$store,__pageId,__pagePath,__pageQuery})
app.provide('__globalStyles', Vue.useCssStyles([...AppStyles, ...(App.styles||[])]))
app.provide('__globalStyles', Vue.useCssStyles([...__uniConfig.styles, ...(App.styles||[])]))
app.mount('#root')`,
path.join(nvueOutDir(), 'main.js'),
options
......@@ -112,3 +143,10 @@ function esbuildGlobalPlugin(options: Record<string, string>) {
},
}
}
export function wrapperNVueAppStyles(code: string) {
return code.replace(
/__uniConfig.styles=(.*);\/\/styles/,
`__uniConfig.styles=${process.env.UNI_NVUE_APP_STYLES || '[]'};//styles`
)
}
......@@ -11,6 +11,8 @@ import {
MANIFEST_JSON_JS,
APP_CONFIG_SERVICE,
} from '@dcloudio/uni-cli-shared'
import { OutputAsset } from 'rollup'
import { wrapperNVueAppStyles } from '../../nvue/plugins/esbuild'
export function uniPagesJsonPlugin(): Plugin {
return defineUniPagesJsonPlugin((opts) => {
......@@ -50,6 +52,15 @@ export function uniPagesJsonPlugin(): Plugin {
map: { mappings: '' },
}
},
generateBundle(_, bundle) {
const outputFile = bundle[APP_CONFIG_SERVICE]
if (outputFile && outputFile.type === 'asset') {
// 补充 nvue styles
;(outputFile as OutputAsset).source = wrapperNVueAppStyles(
(outputFile as OutputAsset).source as string
)
}
},
}
})
}
......@@ -22,6 +22,7 @@ export function normalizeAppConfigService(
const __uniRoutes = ${normalizeAppUniRoutes(
pagesJson
)}.map(uniRoute=>(uniRoute.meta.route=uniRoute.path,__uniConfig.pages.push(uniRoute.path),uniRoute.path='/'+uniRoute.path,uniRoute));
__uniConfig.styles=${process.env.UNI_NVUE_APP_STYLES || '[]'};//styles
__uniConfig.onReady=function(callback){if(__uniConfig.ready){callback()}else{onReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"ready",{get:function(){return isReady},set:function(val){isReady=val;if(!isReady){return}const callbacks=onReadyCallbacks.slice(0);onReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
__uniConfig.onServiceReady=function(callback){if(__uniConfig.serviceReady){callback()}else{onServiceReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"serviceReady",{get:function(){return isServiceReady},set:function(val){isServiceReady=val;if(!isServiceReady){return}const callbacks=onServiceReadyCallbacks.slice(0);onServiceReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
service.register("uni-app-config",{create(a,b,c){if(!__uniConfig.viewport){var d=b.weex.config.env.scale,e=b.weex.config.env.deviceWidth,f=Math.ceil(e/d);Object.assign(__uniConfig,{viewport:f,defaultFontSize:16})}return{instance:{__uniConfig:__uniConfig,__uniRoutes:__uniRoutes,${globalCode}}}}});
......
......@@ -41,12 +41,11 @@ export async function runDev(options: CliOptions & ServerOptions) {
printStartupDuration(createLogger(options.logLevel), false)
)
}
if (process.env.UNI_APP_CHANGED_FILES) {
const files = process.env.UNI_APP_CHANGED_FILES
if (files) {
process.env.UNI_APP_CHANGED_FILES = ''
return console.log(
M['dev.watching.end.files'].replace(
'{files}',
process.env.UNI_APP_CHANGED_FILES
)
M['dev.watching.end.files'].replace('{files}', files)
)
}
return console.log(M['dev.watching.end'])
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册