提交 4abb6a81 编写于 作者: fxy060608's avatar fxy060608 提交者: qiang

wip(uts): compiler

上级 5c8a8095
......@@ -51,7 +51,7 @@ function injectLifecycleHook(name, hook, publicThis, instance) {
}
function initHooks(options, instance, publicThis) {
const mpType = options.mpType || publicThis.$mpType;
if (!mpType) {
if (!mpType || mpType === 'component') {
// 仅 App,Page 类型支持在 options 中配置 on 生命周期,组件可以使用组合式 API 定义页面生命周期
return;
}
......
......@@ -7185,7 +7185,7 @@ function injectLifecycleHook(name, hook, publicThis, instance) {
}
function initHooks(options, instance, publicThis) {
const mpType = options.mpType || publicThis.$mpType;
if (!mpType) {
if (!mpType || mpType === "component") {
return;
}
Object.keys(options).forEach((name) => {
......
......@@ -14780,7 +14780,7 @@ function injectLifecycleHook(name, hook, publicThis, instance2) {
}
function initHooks(options, instance2, publicThis) {
const mpType = options.mpType || publicThis.$mpType;
if (!mpType) {
if (!mpType || mpType === "component") {
return;
}
Object.keys(options).forEach((name) => {
......
......@@ -16,8 +16,8 @@ var uniad_app_json = function (appJson) {
}
if (!appJson.plugins['uni-ad']) {
appJson.plugins['uni-ad'] = {
version: '1.1.0',
provider: 'wx999bf02c8e05dfc9',
version: '1.0.1',
provider: 'wxf72d316417b6767f',
};
}
if (!appJson.plugins['coral-adv']) {
......
......@@ -20,7 +20,6 @@
"@dcloudio/uts": "3.0.0-alpha-3060720221018007",
"@vue/shared": "3.2.41",
"adm-zip": "^0.5.9",
"execa": "^5.1.1",
"fast-glob": "^3.2.11",
"fs-extra": "^10.0.0",
"jsonc-parser": "^3.0.0"
......
#!/usr/bin/env node
require('../dist/cli.js')
......@@ -2,9 +2,6 @@
"name": "@dcloudio/uts",
"version": "3.0.0-alpha-3060720221018007",
"description": "uts",
"bin": {
"uts": "bin/uts.js"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
......@@ -16,16 +13,6 @@
"url": "git+https://github.com/dcloudio/uni-app.git",
"directory": "packages/uts"
},
"dependencies": {
"cac": "6.7.9",
"chokidar": "^3.5.3",
"fast-glob": "^3.2.11",
"fs-extra": "^10.0.0",
"picocolors": "^1.0.0"
},
"devDependencies": {
"@types/fs-extra": "^9.0.13"
},
"optionalDependencies": {
"@dcloudio/uts-darwin-arm64": "3.0.0-alpha-3060720221018007",
"@dcloudio/uts-darwin-x64": "3.0.0-alpha-3060720221018007",
......
......@@ -5,7 +5,7 @@ import {
ToOptions,
UtsTarget,
UtsTargetExtNames,
} from './index'
} from './index.bak'
const cli = cac('uts')
......
import path from 'path'
import fs from 'fs-extra'
import glob from 'fast-glob'
import chokidar from 'chokidar'
import { bundleKotlin, bundleSwift, toKotlin, toSwift } from './api'
import {
UtsBundleOptions,
UtsInputOptions,
UtsOptions,
UtsOutputOptions,
UtsResult,
UtsTarget,
} from './types'
import {
printDone,
printStartup,
printUtsResult,
printUtsResults,
timeEnd,
} from './utils'
export { UtsTarget, UtsResult } from './types'
export type UtsMode = 'dev' | 'build'
const UtsTargetDirs = {
[UtsTarget.KOTLIN]: 'app-android',
[UtsTarget.SWIFT]: 'app-ios',
} as const
export const UtsTargetExtNames = {
[UtsTarget.KOTLIN]: 'kt',
[UtsTarget.SWIFT]: 'swift',
} as const
export interface ToOptions {
/**
* 为 true 时,禁用日志输出,默认为 false
*/
silent?: boolean
input: {
/**
* 插件根目录
*/
dir: string
/**
* 文件后缀,默认 .uts
*/
extname?: string
}
output: {
/**
* 输出目录
*/
dir: string
/**
* 包名
*/
package?: string
/**
* 自动导入的包
*/
imports?: string[]
/**
* 是否生成 sourceMap,为 string 时,表示生成的 sourceMap 目标目录
*/
sourceMap?: boolean | string
/**
* sourceMap 中是否包含源码
*/
inlineSourcesContent?: boolean
extname?: string
}
}
function resolveDefaultOutputDir(mode: UtsMode, inputDir: string) {
return path.resolve(inputDir, '../dist/' + mode)
}
function parseOptions(
mode: UtsMode,
target: UtsTarget,
opts: Partial<ToOptions>
): ToOptions {
const { input } = opts
if (!input?.dir) {
throw new Error(`input.dir is required.`)
}
if (!fs.existsSync(input.dir)) {
throw new Error(`${input} is not found.`)
}
const inputSrcDir: string = resolveSrcDir(target, input.dir)
if (!fs.existsSync(inputSrcDir)) {
throw new Error(`${inputSrcDir} is not found.`)
}
if (!opts.output) {
opts.output = {
dir: '',
sourceMap: '',
extname: UtsTargetExtNames[target],
}
}
if (!opts.output.dir) {
opts.output.dir = resolveDefaultOutputDir(mode, input.dir)
}
if (!opts.output.extname) {
opts.output.extname = UtsTargetExtNames[target]
}
opts.silent = opts.silent === true
return opts as ToOptions
}
const EXTNAME = '.uts'
function resolveSrcDir(target: UtsTarget, dir: string) {
return path.join(dir, UtsTargetDirs[target])
}
function initInputOptions(_: UtsTarget, root: string): UtsInputOptions {
return {
root,
filename: '',
}
}
function initOutputOptions(
target: UtsTarget,
outDir: string,
pkg: string,
imports: string[] = [],
sourceMap: string | boolean | undefined,
inlineSourcesContent: boolean
): UtsOutputOptions {
return {
outDir,
package: pkg,
imports,
sourceMap: sourceMap ? sourceMap : false,
inlineSourcesContent,
extname: UtsTargetExtNames[target],
}
}
function initOptions(
target: UtsTarget,
{
input: { dir: inputDir },
output: {
dir: outputDir,
package: pkg,
imports,
sourceMap,
inlineSourcesContent,
},
}: ToOptions
) {
const inputSrcDir = resolveSrcDir(target, inputDir)
const outputSrcDir = resolveSrcDir(target, outputDir)
const input = initInputOptions(target, inputSrcDir)
const output = initOutputOptions(
target,
outputSrcDir,
pkg || '',
imports,
sourceMap,
!!inlineSourcesContent
)
return { input, output }
}
async function watch(target: UtsTarget, toOptions: ToOptions) {
fs.emptyDirSync(toOptions.output.dir)
const { input, output } = initOptions(target, toOptions)
const inputDir = toOptions.input.dir
const outputDir = toOptions.output.dir
const inputSrcDir = input.root
const outputSrcDir = output.outDir
const extname = toOptions.input.extname || EXTNAME
const silent = !!toOptions.silent
// 先完整编译后,再启用监听
doBuild(target, {
watch: true,
input,
output,
inputDir,
outputDir,
inputSrcDir,
outputSrcDir,
extname,
silent,
}).then(() => {
// TODO 监听动态添加的资源文件
chokidar
.watch('**/*' + extname, {
cwd: inputSrcDir,
ignored: ['**/*.d' + extname],
ignoreInitial: true,
})
.on('add', (filename) => {
buildFile(
target,
path.resolve(inputSrcDir, filename),
input,
output
).then((res) => {
if (!silent) {
printUtsResult(res)
printDone(true)
}
})
})
.on('change', (filename) => {
buildFile(
target,
path.resolve(inputSrcDir, filename),
input,
output
).then((res) => {
if (!silent) {
printUtsResult(res)
printDone(true)
}
})
})
.on('unlink', (filename) => {
try {
fs.unlinkSync(path.resolve(outputSrcDir, filename))
} catch (e) {}
})
})
}
interface DoBuildOptions {
watch: boolean
silent: boolean
input: UtsInputOptions
output: UtsOutputOptions
inputDir: string
inputSrcDir: string
outputDir: string
outputSrcDir: string
extname: string
}
function doBuild(
target: UtsTarget,
{ watch, silent, extname, inputSrcDir, input, output }: DoBuildOptions
) {
const files = glob.sync('**/*' + extname, {
absolute: true,
cwd: inputSrcDir,
ignore: ['**/*.d' + extname],
})
return Promise.all(
files.map((filename) =>
buildFile(target, filename, input, output).catch((error) => {
return {
error,
} as UtsResult
})
)
).then((res) => {
!silent && printUtsResults(res, watch)
return res
})
}
function build(target: UtsTarget, toOptions: ToOptions) {
fs.emptyDirSync(toOptions.output.dir)
const { input, output } = initOptions(target, toOptions)
const inputDir = toOptions.input.dir
const outputDir = toOptions.output.dir
const inputSrcDir = input.root
const outputSrcDir = output.outDir
const extname = toOptions.input.extname || EXTNAME
const silent = !!toOptions.silent
return doBuild(target, {
watch: false,
input,
output,
inputDir,
outputDir,
inputSrcDir,
outputSrcDir,
extname,
silent,
})
}
function buildFile(
target: UtsTarget,
filename: string,
input: UtsInputOptions,
output: UtsOutputOptions
) {
const toOptions: UtsOptions = {
input: {
...input,
filename,
},
output: {
...output,
},
}
const start = process.hrtime()
return (
target === UtsTarget.KOTLIN ? toKotlin(toOptions) : toSwift(toOptions)
).then((res) => {
res.time = timeEnd(start)
return res
})
}
export { parse, bundleKotlin, bundleSwift } from './api'
export function bundle(
target: UtsTarget,
opts: UtsBundleOptions
): Promise<UtsResult> {
if (target === UtsTarget.KOTLIN) {
return bundleKotlin(opts)
} else if (target === UtsTarget.SWIFT) {
return bundleSwift(opts)
}
return Promise.resolve({})
}
export function runDev(target: UtsTarget, opts: ToOptions) {
opts = parseOptions('dev', target, opts)
!opts.silent && printStartup(target, 'development')
watch(target, opts)
}
export function runBuild(target: UtsTarget, opts: ToOptions) {
opts = parseOptions('build', target, opts)
!opts.silent && printStartup(target, 'production')
build(target, opts)
}
import path from 'path'
import fs from 'fs-extra'
import glob from 'fast-glob'
import chokidar from 'chokidar'
import { bundleKotlin, bundleSwift, toKotlin, toSwift } from './api'
import {
UtsBundleOptions,
UtsInputOptions,
UtsOptions,
UtsOutputOptions,
UtsResult,
UtsTarget,
} from './types'
import {
printDone,
printStartup,
printUtsResult,
printUtsResults,
timeEnd,
} from './utils'
import { bundleKotlin, bundleSwift } from './api'
import { UtsBundleOptions, UtsResult, UtsTarget } from './types'
export { UtsTarget, UtsResult } from './types'
export type UtsMode = 'dev' | 'build'
const UtsTargetDirs = {
[UtsTarget.KOTLIN]: 'app-android',
[UtsTarget.SWIFT]: 'app-ios',
} as const
export const UtsTargetExtNames = {
[UtsTarget.KOTLIN]: 'kt',
[UtsTarget.SWIFT]: 'swift',
......@@ -74,249 +49,6 @@ export interface ToOptions {
}
}
function resolveDefaultOutputDir(mode: UtsMode, inputDir: string) {
return path.resolve(inputDir, '../dist/' + mode)
}
function parseOptions(
mode: UtsMode,
target: UtsTarget,
opts: Partial<ToOptions>
): ToOptions {
const { input } = opts
if (!input?.dir) {
throw new Error(`input.dir is required.`)
}
if (!fs.existsSync(input.dir)) {
throw new Error(`${input} is not found.`)
}
const inputSrcDir: string = resolveSrcDir(target, input.dir)
if (!fs.existsSync(inputSrcDir)) {
throw new Error(`${inputSrcDir} is not found.`)
}
if (!opts.output) {
opts.output = {
dir: '',
sourceMap: '',
extname: UtsTargetExtNames[target],
}
}
if (!opts.output.dir) {
opts.output.dir = resolveDefaultOutputDir(mode, input.dir)
}
if (!opts.output.extname) {
opts.output.extname = UtsTargetExtNames[target]
}
opts.silent = opts.silent === true
return opts as ToOptions
}
const EXTNAME = '.uts'
function resolveSrcDir(target: UtsTarget, dir: string) {
return path.join(dir, UtsTargetDirs[target])
}
function initInputOptions(_: UtsTarget, root: string): UtsInputOptions {
return {
root,
filename: '',
}
}
function initOutputOptions(
target: UtsTarget,
outDir: string,
pkg: string,
imports: string[] = [],
sourceMap: string | boolean | undefined,
inlineSourcesContent: boolean
): UtsOutputOptions {
return {
outDir,
package: pkg,
imports,
sourceMap: sourceMap ? sourceMap : false,
inlineSourcesContent,
extname: UtsTargetExtNames[target],
}
}
function initOptions(
target: UtsTarget,
{
input: { dir: inputDir },
output: {
dir: outputDir,
package: pkg,
imports,
sourceMap,
inlineSourcesContent,
},
}: ToOptions
) {
const inputSrcDir = resolveSrcDir(target, inputDir)
const outputSrcDir = resolveSrcDir(target, outputDir)
const input = initInputOptions(target, inputSrcDir)
const output = initOutputOptions(
target,
outputSrcDir,
pkg || '',
imports,
sourceMap,
!!inlineSourcesContent
)
return { input, output }
}
async function watch(target: UtsTarget, toOptions: ToOptions) {
fs.emptyDirSync(toOptions.output.dir)
const { input, output } = initOptions(target, toOptions)
const inputDir = toOptions.input.dir
const outputDir = toOptions.output.dir
const inputSrcDir = input.root
const outputSrcDir = output.outDir
const extname = toOptions.input.extname || EXTNAME
const silent = !!toOptions.silent
// 先完整编译后,再启用监听
doBuild(target, {
watch: true,
input,
output,
inputDir,
outputDir,
inputSrcDir,
outputSrcDir,
extname,
silent,
}).then(() => {
// TODO 监听动态添加的资源文件
chokidar
.watch('**/*' + extname, {
cwd: inputSrcDir,
ignored: ['**/*.d' + extname],
ignoreInitial: true,
})
.on('add', (filename) => {
buildFile(
target,
path.resolve(inputSrcDir, filename),
input,
output
).then((res) => {
if (!silent) {
printUtsResult(res)
printDone(true)
}
})
})
.on('change', (filename) => {
buildFile(
target,
path.resolve(inputSrcDir, filename),
input,
output
).then((res) => {
if (!silent) {
printUtsResult(res)
printDone(true)
}
})
})
.on('unlink', (filename) => {
try {
fs.unlinkSync(path.resolve(outputSrcDir, filename))
} catch (e) {}
})
})
}
interface DoBuildOptions {
watch: boolean
silent: boolean
input: UtsInputOptions
output: UtsOutputOptions
inputDir: string
inputSrcDir: string
outputDir: string
outputSrcDir: string
extname: string
}
function doBuild(
target: UtsTarget,
{ watch, silent, extname, inputSrcDir, input, output }: DoBuildOptions
) {
const files = glob.sync('**/*' + extname, {
absolute: true,
cwd: inputSrcDir,
ignore: ['**/*.d' + extname],
})
return Promise.all(
files.map((filename) =>
buildFile(target, filename, input, output).catch((error) => {
return {
error,
} as UtsResult
})
)
).then((res) => {
!silent && printUtsResults(res, watch)
return res
})
}
function build(target: UtsTarget, toOptions: ToOptions) {
fs.emptyDirSync(toOptions.output.dir)
const { input, output } = initOptions(target, toOptions)
const inputDir = toOptions.input.dir
const outputDir = toOptions.output.dir
const inputSrcDir = input.root
const outputSrcDir = output.outDir
const extname = toOptions.input.extname || EXTNAME
const silent = !!toOptions.silent
return doBuild(target, {
watch: false,
input,
output,
inputDir,
outputDir,
inputSrcDir,
outputSrcDir,
extname,
silent,
})
}
function buildFile(
target: UtsTarget,
filename: string,
input: UtsInputOptions,
output: UtsOutputOptions
) {
const toOptions: UtsOptions = {
input: {
...input,
filename,
},
output: {
...output,
},
}
const start = process.hrtime()
return (
target === UtsTarget.KOTLIN ? toKotlin(toOptions) : toSwift(toOptions)
).then((res) => {
res.time = timeEnd(start)
return res
})
}
export { parse, bundleKotlin, bundleSwift } from './api'
export function bundle(
......@@ -330,15 +62,3 @@ export function bundle(
}
return Promise.resolve({})
}
export function runDev(target: UtsTarget, opts: ToOptions) {
opts = parseOptions('dev', target, opts)
!opts.silent && printStartup(target, 'development')
watch(target, opts)
}
export function runBuild(target: UtsTarget, opts: ToOptions) {
opts = parseOptions('build', target, opts)
!opts.silent && printStartup(target, 'production')
build(target, opts)
}
import os from 'os'
import colors from 'picocolors'
import type { UtsTarget } from '.'
import { UtsResult } from './types'
export const isWindows = os.platform() === 'win32'
export function normalizePath(id: string): string {
return isWindows ? id.replace(/\\/g, '/') : id
}
const round = (number: number) => Number(number.toFixed(2))
const hrTimeToMilliseconds = (hrtime: [number, number]) =>
hrtime[0] * 1e3 + hrtime[1] / 1e6
export function timeEnd(start: [number, number]) {
return round(
hrTimeToMilliseconds(process.hrtime()) - hrTimeToMilliseconds(start)
)
}
export function printStartup(target: UtsTarget, mode: string) {
console.log(
colors.cyan(
`uts v${require('../package.json').version} ${colors.green(
`building ${target} for ${mode}...`
)}`
)
)
}
export function printDone(watch: boolean = false) {
if (watch) {
console.log(`DONE Build complete. Watching for changes...`)
} else {
console.log(`DONE Build complete.`)
}
}
export function printUtsResults(results: UtsResult[], watch: boolean = false) {
let longest = 0
let failed: UtsResult[] = []
let transformed: UtsResult[] = []
results.forEach((result) => {
if (result.error) {
failed.push(result)
} else {
transformed.push(result)
}
})
if (failed.length) {
console.log(colors.dim(`${colors.red(`✗`)} ${failed.length} files failed.`))
failed.forEach((result) => {
console.error(result.error!.message.split(`Caused by:`)[0])
})
}
if (transformed.length) {
for (const result of transformed) {
const l = result.filename!.length
if (l > longest) longest = l
}
console.log(
colors.dim(
`${colors.green(`✓`)} ${transformed.length} files transformed.`
)
)
transformed.forEach((result) => {
if (result.filename) {
printUtsResult(result, longest)
}
})
}
printDone(watch)
}
export function printUtsResult(result: UtsResult, maxLength = 0) {
console.log(
colors.green(result.filename!.padEnd(maxLength + 2)) +
' ' +
colors.dim(result.time + 'ms')
)
}
......@@ -804,7 +804,6 @@ importers:
'@types/fs-extra': ^9.0.13
'@vue/shared': 3.2.41
adm-zip: ^0.5.9
execa: ^5.1.1
fast-glob: ^3.2.11
fs-extra: ^10.0.0
jsonc-parser: ^3.0.0
......@@ -812,7 +811,6 @@ importers:
'@dcloudio/uts': link:../uts
'@vue/shared': 3.2.41
adm-zip: 0.5.9
execa: 5.1.1
fast-glob: 3.2.12
fs-extra: 10.1.0
jsonc-parser: 3.2.0
......@@ -834,25 +832,11 @@ importers:
'@dcloudio/uts-darwin-x64': 3.0.0-alpha-3060720221018007
'@dcloudio/uts-win32-ia32-msvc': 3.0.0-alpha-3060720221018007
'@dcloudio/uts-win32-x64-msvc': 3.0.0-alpha-3060720221018007
'@types/fs-extra': ^9.0.13
cac: 6.7.9
chokidar: ^3.5.3
fast-glob: ^3.2.11
fs-extra: ^10.0.0
picocolors: ^1.0.0
dependencies:
cac: 6.7.9
chokidar: 3.5.3
fast-glob: 3.2.12
fs-extra: 10.1.0
picocolors: 1.0.0
optionalDependencies:
'@dcloudio/uts-darwin-arm64': link:../uts-darwin-arm64
'@dcloudio/uts-darwin-x64': link:../uts-darwin-x64
'@dcloudio/uts-win32-ia32-msvc': link:../uts-win32-ia32-msvc
'@dcloudio/uts-win32-x64-msvc': link:../uts-win32-x64-msvc
devDependencies:
'@types/fs-extra': 9.0.13
packages/uts-darwin-arm64:
specifiers: {}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册