UNPKG

uview-plus

Version:

零云®uview-plus已兼容vue3支持多语言,120+全面的组件和便捷的工具会让您信手拈来。近期新增拖动排序、条码、图片裁剪、下拉刷新、虚拟列表、签名、Markdown等。

152 lines (128 loc) 5.01 kB
import { dirname, relative, resolve } from 'node:path' import { fileURLToPath } from 'node:url' import process from 'node:process' import { existsSync, mkdirSync, statSync, writeFileSync } from 'node:fs' import { createFilter, normalizePath } from 'vite' import { transformNvuePage, transformPage } from './page.js' import { rebuildUpApp, registerUpApp } from './root.js' import { loadPagesJson, normalizePlatformPath, toArray } from './utils.js' const rootLibPath = normalizePath(dirname(fileURLToPath(import.meta.url))) export default function UniUpRoot(options = {}) { const rootOptions = { enabledVirtualHost: false, enabledGlobalRef: false, rootFileName: 'App.up', autoCreateRootFile: true, excludePages: [], ...options, } const rootFileName = String(rootOptions.rootFileName || 'App.up').replace(/\.vue$/i, '') const detectProjectRoot = () => { const cwd = normalizePath(process.env.INIT_CWD || process.cwd()) const envInputDir = process.env.UNI_INPUT_DIR ? normalizePath(process.env.UNI_INPUT_DIR) : '' const cliRootPath = normalizePath(resolve(cwd, 'src')) const hbuilderRootPath = cwd const isPageRoot = (path) => existsSync(resolve(path, 'pages.json')) if (envInputDir && isPageRoot(envInputDir)) { const projectType = envInputDir.endsWith('/src') ? 'cli' : 'hbuilder' return { rootPath: envInputDir, projectType } } if (isPageRoot(cliRootPath)) { return { rootPath: cliRootPath, projectType: 'cli' } } if (isPageRoot(hbuilderRootPath)) { return { rootPath: hbuilderRootPath, projectType: 'hbuilder' } } return { rootPath: envInputDir || cliRootPath, projectType: envInputDir && !envInputDir.endsWith('/src') ? 'hbuilder' : 'cli', } } const projectInfo = detectProjectRoot() const rootPath = normalizePath(projectInfo.rootPath) const appUpPath = normalizePath(resolve(rootPath, `${rootFileName}.vue`)) const rootToastHostPath = normalizePath(resolve(rootLibPath, 'root-toast-host.vue')) const nvueRootPath = normalizePath(resolve(rootPath, 'uni_modules/uview-plus/libs/root/nvue-root.vue')) const themeRuntimePath = normalizePath(resolve(rootPath, 'uni_modules/uview-plus/libs/theme/runtime.js')) const pagesPath = normalizePath(resolve(rootPath, 'pages.json')) const excludedPaths = toArray(rootOptions.excludePages) .filter(Boolean) .map(path => normalizePath(resolve(rootPath, path))) const mainFiles = [ normalizePath(resolve(rootPath, 'main.ts')), normalizePath(resolve(rootPath, 'main.js')), ] const getRelativeImportPath = (fromFile, toFile) => { let importPath = normalizePath(relative(dirname(fromFile), toFile)) if (!importPath.startsWith('.')) { importPath = `./${importPath}` } return importPath } let pagesJson = [] let pagesJsonMtimeMs = 0 let hasPlatformPlugin = false const ensureRootFile = () => { if (!rootOptions.autoCreateRootFile) return if (existsSync(appUpPath)) return const defaultRootSfc = `<template> \t<UpRootView /> </template> ` mkdirSync(dirname(appUpPath), { recursive: true }) writeFileSync(appUpPath, defaultRootSfc, 'utf-8') } const refreshPagesJson = () => { if (!existsSync(pagesPath)) return const mtimeMs = statSync(pagesPath).mtimeMs if (mtimeMs === pagesJsonMtimeMs && pagesJson.length) return pagesJson = loadPagesJson(pagesPath, rootPath) pagesJsonMtimeMs = mtimeMs } return { name: 'vite-plugin-uni-up-root', enforce: 'pre', configResolved({ plugins }) { hasPlatformPlugin = plugins.some(v => v.name === 'vite-plugin-uni-platform') }, buildStart() { ensureRootFile() refreshPagesJson() }, async transform(code, id) { let ms = null const isSfcBlock = id.includes('?') const cleanId = normalizePath(id.split('?')[0]) const filterMain = createFilter(mainFiles) if (filterMain(cleanId)) { ms = await registerUpApp(code, rootFileName, getRelativeImportPath(cleanId, rootToastHostPath)) } const filterUpRoot = createFilter(appUpPath) if (filterUpRoot(cleanId)) { ms = await rebuildUpApp(code, rootOptions.enabledVirtualHost) } refreshPagesJson() const pageId = hasPlatformPlugin ? normalizePlatformPath(cleanId) : cleanId const filterPage = createFilter(pagesJson, excludedPaths) if (!isSfcBlock && filterPage(pageId)) { if (cleanId.endsWith('.nvue')) { ms = await transformNvuePage( code, getRelativeImportPath(cleanId, nvueRootPath), getRelativeImportPath(cleanId, themeRuntimePath), rootOptions.enabledGlobalRef ) } else { ms = await transformPage(code, rootOptions.enabledGlobalRef) } } if (ms) { return { code: ms.toString(), map: ms.generateMap({ hires: true }), } } return null }, } }