From ebcfd194c4b98189387a30baba9cf2039c6915c2 Mon Sep 17 00:00:00 2001 From: fxy060608 Date: Thu, 8 Sep 2022 12:21:01 +0800 Subject: [PATCH] wip(uts): compiler --- packages/uni-uts-vite/src/plugins/v1.ts | 36 ++++-- .../uni-uts-vite/src/utils/compiler/index.ts | 15 +++ .../utils/{compiler.ts => compiler/kotlin.ts} | 122 +++++------------- .../uni-uts-vite/src/utils/compiler/swift.ts | 45 +++++++ .../uni-uts-vite/src/utils/compiler/utils.ts | 90 +++++++++++++ 5 files changed, 204 insertions(+), 104 deletions(-) create mode 100644 packages/uni-uts-vite/src/utils/compiler/index.ts rename packages/uni-uts-vite/src/utils/{compiler.ts => compiler/kotlin.ts} (66%) create mode 100644 packages/uni-uts-vite/src/utils/compiler/swift.ts create mode 100644 packages/uni-uts-vite/src/utils/compiler/utils.ts diff --git a/packages/uni-uts-vite/src/plugins/v1.ts b/packages/uni-uts-vite/src/plugins/v1.ts index 50f21f86c..71a6294a2 100644 --- a/packages/uni-uts-vite/src/plugins/v1.ts +++ b/packages/uni-uts-vite/src/plugins/v1.ts @@ -16,7 +16,7 @@ import { TsTypeAnnotation, VariableDeclaration, } from '../../types/types' -import { compile, parsePackage } from '../utils/compiler' +import { getCompiler } from '../utils/compiler' export function uniUtsV1Plugin(): Plugin { let isFirst = true @@ -28,14 +28,20 @@ export function uniUtsV1Plugin(): Plugin { if (opts && opts.ssr) { return } - // 目前仅支持app-android - if (process.env.UNI_UTS_PLATFORM !== 'app-android') { + // 目前仅支持 app-android|app-ios + if ( + process.env.UNI_UTS_PLATFORM !== 'app-android' && + process.env.UNI_UTS_PLATFORM !== 'app-ios' + ) { return } const { filename } = parseVueRequest(id) if (path.extname(filename) !== '.uts') { return } + const { compile, parsePackage } = getCompiler( + process.env.UNI_UTS_PLATFORM === 'app-ios' ? 'swift' : 'kotlin' + ) const pkg = parsePackage(filename) if (!pkg) { return @@ -50,18 +56,20 @@ const pkg = '${pkg}' const cls = 'IndexKt' ${genProxyCode(ast)} ` - const dexFile = await compile(id) - if (!isFirst && dexFile) { - const files = [] - if (process.env.UNI_APP_CHANGED_DEX_FILES) { - try { - files.push(...JSON.parse(process.env.UNI_APP_CHANGED_DEX_FILES)) - } catch (e) {} + const res = await compile(id) + if (process.env.UNI_UTS_PLATFORM === 'app-android') { + if (!isFirst && res) { + const files = [] + if (process.env.UNI_APP_CHANGED_DEX_FILES) { + try { + files.push(...JSON.parse(process.env.UNI_APP_CHANGED_DEX_FILES)) + } catch (e) {} + } + files.push(res) + process.env.UNI_APP_CHANGED_DEX_FILES = JSON.stringify([ + ...new Set(files), + ]) } - files.push(dexFile) - process.env.UNI_APP_CHANGED_DEX_FILES = JSON.stringify([ - ...new Set(files), - ]) } return code }, diff --git a/packages/uni-uts-vite/src/utils/compiler/index.ts b/packages/uni-uts-vite/src/utils/compiler/index.ts new file mode 100644 index 000000000..adeedc73b --- /dev/null +++ b/packages/uni-uts-vite/src/utils/compiler/index.ts @@ -0,0 +1,15 @@ +import { compileKotlin, parseKotlinPackage } from './kotlin' +import { compileSwift, parseSwiftPackage } from './swift' + +export function getCompiler(type: 'kotlin' | 'swift') { + if (type === 'swift') { + return { + compile: compileKotlin, + parsePackage: parseKotlinPackage, + } + } + return { + compile: compileSwift, + parsePackage: parseSwiftPackage, + } +} diff --git a/packages/uni-uts-vite/src/utils/compiler.ts b/packages/uni-uts-vite/src/utils/compiler/kotlin.ts similarity index 66% rename from packages/uni-uts-vite/src/utils/compiler.ts rename to packages/uni-uts-vite/src/utils/compiler/kotlin.ts index 0fb489037..53bfaff5e 100644 --- a/packages/uni-uts-vite/src/utils/compiler.ts +++ b/packages/uni-uts-vite/src/utils/compiler/kotlin.ts @@ -3,7 +3,7 @@ import fs from 'fs-extra' import path from 'path' import AdmZip from 'adm-zip' import { sync } from 'fast-glob' -import type { parse, bundle, UtsTarget } from '@dcloudio/uts' + import { installHBuilderXPlugin, isInHBuilderX, @@ -11,16 +11,30 @@ import { resolveSourceMapPath, } from '@dcloudio/uni-cli-shared' import { camelize } from '@vue/shared' +import { + genUTSPlatformResource, + getUtsCompiler, + resolveAndroidDir, + resolveUTSPlatformFile, + UTSPlatformResourceOptions, +} from './utils' + +export function parseKotlinPackage(filepath: string) { + const parts = normalizePath(filepath).split('/') -export function getUtsCompiler(): { - parse: typeof parse - bundle: typeof bundle - UtsTarget: typeof UtsTarget -} { - // eslint-disable-next-line no-restricted-globals - return require('@dcloudio/uts') + const isUniModules = parts.includes('uni_modules') + const index = isUniModules + ? parts.findIndex((part) => part === 'uni_modules') + : parts.findIndex((part) => part === 'utssdk') + if (index > -1) { + return ( + 'uts.sdk.' + (isUniModules ? 'modules.' : '') + camelize(parts[index + 1]) + ) + } + return '' } -export async function compile(filename: string) { + +export async function compileKotlin(filename: string) { if (!process.env.UNI_HBUILDERX_PLUGINS) { return } @@ -36,7 +50,7 @@ export async function compile(filename: string) { }, output: { outDir: outputDir, - package: parsePackage(filename), + package: parseKotlinPackage(filename), sourceMap: resolveSourceMapPath( process.env.UNI_OUTPUT_DIR, process.env.UNI_PLATFORM @@ -54,35 +68,16 @@ export async function compile(filename: string) { }, }) // console.log('uts compile time: ' + (Date.now() - time) + 'ms') - - const kotlinFile = resolveKotlinFile(filename, inputDir, outputDir) + const utsPlatformOptions: UTSPlatformResourceOptions = { + inputDir, + outputDir, + platform: 'app-android', + extname: '.kt', + } if (process.env.NODE_ENV === 'production') { - const androidInputDir = resolveAndroidDir(filename) - const androidOutputDir = resolveAndroidDir(kotlinFile) - - // 拷贝所有非uts文件及目录 - fs.copySync(androidInputDir, androidOutputDir, { - filter(src) { - return path.extname(src) !== '.uts' - }, - }) - - // 生产模式下,需要将 kt 文件转移到 src 下 - const srcDir = path.resolve(androidOutputDir, 'src') - if (!fs.existsSync(srcDir)) { - fs.mkdirSync(srcDir) - } - if (fs.existsSync(kotlinFile)) { - fs.moveSync(kotlinFile, path.resolve(androidOutputDir, 'src/index.kt')) - } - const kotlinMapFile = kotlinFile + '.map' - if (fs.existsSync(kotlinMapFile)) { - fs.moveSync( - kotlinMapFile, - path.resolve(androidOutputDir, 'src/index.map.kt') - ) - } + genUTSPlatformResource(filename, utsPlatformOptions) } else if (process.env.NODE_ENV === 'development') { + const kotlinFile = resolveUTSPlatformFile(filename, utsPlatformOptions) // 开发模式下,需要生成 dex if (fs.existsSync(kotlinFile)) { const compilerServer = getCompilerServer() @@ -177,44 +172,6 @@ function resolveDexFile(jarFile: string) { return normalizePath(path.resolve(path.dirname(jarFile), 'classes.dex')) } -function resolveAndroidDir(filename: string) { - const maybeAndroidDir = path.dirname(filename) - // 如果是根目录的index.uts编译出来的index.kt,则移动到app-android下 - const isRootIndex = path.basename(maybeAndroidDir) !== 'app-android' - if (isRootIndex) { - if (maybeAndroidDir.includes('uni_modules')) { - return path.join(maybeAndroidDir, 'utssdk/app-android') - } - return path.join(maybeAndroidDir, 'app-android') - } - return maybeAndroidDir -} - -function resolveKotlinFile( - filename: string, - inputDir: string, - outputDir: string -) { - let ktFile = path - .resolve(outputDir, path.relative(inputDir, filename)) - .replace(path.extname(filename), '.kt') - const maybeModuleDir = path.dirname(filename) - // 如果是根目录的index.uts编译出来的index.kt,则移动到app-android下 - const isRootIndex = path.basename(maybeModuleDir) !== 'app-android' - if (isRootIndex) { - if (fs.existsSync(ktFile)) { - const newKtFile = path.resolve( - path.dirname(ktFile), - (maybeModuleDir.includes('uni_modules') ? 'utssdk/' : '') + - 'app-android/index.kt' - ) - fs.moveSync(ktFile, newKtFile) - ktFile = newKtFile - } - } - return ktFile -} - function resolveDexPath(filename: string) { return path.dirname(filename) } @@ -249,18 +206,3 @@ const getCompilerServer = (): } return false } - -export function parsePackage(filepath: string) { - const parts = normalizePath(filepath).split('/') - - const isUniModules = parts.includes('uni_modules') - const index = isUniModules - ? parts.findIndex((part) => part === 'uni_modules') - : parts.findIndex((part) => part === 'utssdk') - if (index > -1) { - return ( - 'uts.sdk.' + (isUniModules ? 'modules.' : '') + camelize(parts[index + 1]) - ) - } - return '' -} diff --git a/packages/uni-uts-vite/src/utils/compiler/swift.ts b/packages/uni-uts-vite/src/utils/compiler/swift.ts new file mode 100644 index 000000000..1e20ebd27 --- /dev/null +++ b/packages/uni-uts-vite/src/utils/compiler/swift.ts @@ -0,0 +1,45 @@ +import { isInHBuilderX, resolveSourceMapPath } from '@dcloudio/uni-cli-shared' +import { genUTSPlatformResource, getUtsCompiler } from './utils' + +export function parseSwiftPackage(filename: string) { + return '' +} +export async function compileSwift(filename: string) { + // 开发阶段不编译 + if (process.env.NODE_ENV !== 'production') { + return + } + if (!process.env.UNI_HBUILDERX_PLUGINS) { + return + } + const { bundle, UtsTarget } = getUtsCompiler() + const inputDir = process.env.UNI_INPUT_DIR + const outputDir = process.env.UNI_OUTPUT_DIR + // let time = Date.now() + await bundle({ + target: UtsTarget.SWIFT, + input: { + root: inputDir, + filename, + }, + output: { + outDir: outputDir, + package: '', + sourceMap: resolveSourceMapPath( + process.env.UNI_OUTPUT_DIR, + process.env.UNI_PLATFORM + ), + extname: 'kt', + imports: [], + logFilename: true, + noColor: isInHBuilderX(), + }, + }) + + genUTSPlatformResource(filename, { + inputDir, + outputDir, + platform: 'app-ios', + extname: '.swift', + }) +} diff --git a/packages/uni-uts-vite/src/utils/compiler/utils.ts b/packages/uni-uts-vite/src/utils/compiler/utils.ts new file mode 100644 index 000000000..7920f31cb --- /dev/null +++ b/packages/uni-uts-vite/src/utils/compiler/utils.ts @@ -0,0 +1,90 @@ +import path from 'path' +import fs from 'fs-extra' +import type { parse, bundle, UtsTarget } from '@dcloudio/uts' + +export function getUtsCompiler(): { + parse: typeof parse + bundle: typeof bundle + UtsTarget: typeof UtsTarget +} { + // eslint-disable-next-line no-restricted-globals + return require('@dcloudio/uts') +} + +export interface UTSPlatformResourceOptions { + inputDir: string + outputDir: string + platform: typeof process.env.UNI_UTS_PLATFORM + extname: '.kt' | '.swift' +} +export function genUTSPlatformResource( + filename: string, + options: UTSPlatformResourceOptions +) { + const platformFile = resolveUTSPlatformFile(filename, options) + const { platform } = options + const utsInputDir = resolveUTSPlatformDir(filename, platform) + const utsOutputDir = resolveUTSPlatformDir(platformFile, platform) + + // 拷贝所有非uts文件及目录 + fs.copySync(utsInputDir, utsOutputDir, { + filter(src) { + return path.extname(src) !== '.uts' + }, + }) + + // 生产模式下,需要将 kt 文件转移到 src 下 + const srcDir = path.resolve(utsOutputDir, 'src') + if (!fs.existsSync(srcDir)) { + fs.mkdirSync(srcDir) + } + if (fs.existsSync(platformFile)) { + fs.moveSync(platformFile, path.resolve(utsOutputDir, 'src/index.kt')) + } +} + +export function resolveAndroidDir(filename: string) { + return resolveUTSPlatformDir(filename, 'app-android') +} + +function resolveUTSPlatformDir( + filename: string, + platform: typeof process.env.UNI_UTS_PLATFORM +) { + const maybePlatformDir = path.dirname(filename) + // 如果是根目录的 index.uts,需要定向到真正的平台目录 + const isRootIndex = path.basename(maybePlatformDir) !== platform + if (isRootIndex) { + if (maybePlatformDir.includes('uni_modules')) { + return path.join(maybePlatformDir, 'utssdk/' + platform) + } + return path.join(maybePlatformDir, platform) + } + return maybePlatformDir +} + +export function resolveUTSPlatformFile( + filename: string, + { inputDir, outputDir, platform, extname }: UTSPlatformResourceOptions +) { + let platformFile = path + .resolve(outputDir, path.relative(inputDir, filename)) + .replace(path.extname(filename), extname) + const maybeModuleDir = path.dirname(filename) + // 如果是根目录的 index.uts 编译出来的 index.kt,则移动到平台目录下 + const isRootIndex = path.basename(maybeModuleDir) !== platform + if (isRootIndex) { + if (fs.existsSync(platformFile)) { + const newPlatformFile = path.resolve( + path.dirname(platformFile), + (maybeModuleDir.includes('uni_modules') ? 'utssdk/' : '') + + platform + + '/index' + + extname + ) + fs.moveSync(platformFile, newPlatformFile) + platformFile = newPlatformFile + } + } + return platformFile +} -- GitLab