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

wip(uts): compiler

上级 c007f809
......@@ -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
},
......
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,
}
}
......@@ -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 ''
}
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',
})
}
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
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册