Skip to content

Commit

Permalink
feat(uts): 混编支持console日志重写
Browse files Browse the repository at this point in the history
  • Loading branch information
fxy060608 committed Feb 15, 2025
1 parent 08484b9 commit 6b71588
Show file tree
Hide file tree
Showing 10 changed files with 343 additions and 16 deletions.
109 changes: 109 additions & 0 deletions packages/uni-cli-shared/__tests__/__snapshots__/console.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,114 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`console appendConsoleExpr 1`] = `
"// 基础测试用例
console.log('简单字符串', ' at test.ts:2')
console.info('双引号字符串', ' at test.ts:3')
console.warn(\`模板字符串\`, ' at test.ts:4')
console.error('带分号的', ' at test.ts:5')
console.debug('不带分号的', ' at test.ts:6')
// 多参数测试
console.log('参数1', '参数2', '参数3', ' at test.ts:9')
console.info(1, true, null, undefined, ' at test.ts:10')
console.warn('混合类型', 123, true, null, ' at test.ts:11')
// 对象和数组测试
console.log({ name: 'test', age: 18 }, ' at test.ts:14')
console.log(['a', 'b', 'c'], ' at test.ts:15')
console.log({ a: 1 }, ['x', 'y'], { b: 2 }, ' at test.ts:16')
// 表达式测试
console.log(1 + 2, ' at test.ts:19')
console.log(foo(), ' at test.ts:20')
console.log(a ? b : c, ' at test.ts:21')
console.log(obj.method(), ' at test.ts:22')
// 模板字符串测试
console.log(\`Hello \${name}\`, ' at test.ts:25')
console.log(\`多行
模板字符串
测试\`, ' at test.ts:26')
console.log(\`\${obj.method()}\${arr[0]}\`, ' at test.ts:29')
// 多行格式测试
console.log('多行参数1', '多行参数2', '多行参数3', ' at test.ts:32')
console.log({
name: 'test',
age: 18,
nested: {
a: 1,
b: 2,
},
}, ' at test.ts:34')
// 嵌套括号测试
console.log(getData('test'), ' at test.ts:44')
console.log(outer(inner()), ' at test.ts:45')
console.log((a + b) * c, ' at test.ts:46')
// 函数调用测试
console.log(foo.bar(), ' at test.ts:49')
console.log(new Date(), ' at test.ts:50')
console.log(Array.from(set), ' at test.ts:51')
// 复杂混合测试
console.log(\`用户 \${user.name}\`,
{
id: user.id,
time: new Date(),
data: getData(user.id),
},
process.env.NODE_ENV === 'development' && '开发环境', ' at test.ts:54')
// 注释和特殊字符测试
console.log("包含'单引号'", ' at test.ts:65')
console.log('包含"双引号"', ' at test.ts:66')
console.log(\`包含\\\`反引号\\\`\`, ' at test.ts:67')
console.log('包含/正斜杠/', ' at test.ts:68')
console.log('包含\\\\反斜杠\\\\', ' at test.ts:69')
// 正则表达式测试
console.log(/test/g, ' at test.ts:72')
console.log(new RegExp('test', 'g'), ' at test.ts:73')
// 特殊语法测试
console.log(...args, ' at test.ts:76')
console.log?.('optional chaining')
// 带注释的测试
console.log('test', // 行尾注释
/* 块注释 */ 'test2',
'test3' /* 行内块注释 */, ' at test.ts:80')
// 空参数测试
console.log(, ' at test.ts:87')
console.log('', ' at test.ts:88')
console.log(, ' at test.ts:89')
// 连续调用测试
console.log('test1', ' at test.ts:92')
console.log('test2', ' at test.ts:93')
console.log('test1', ' at test.ts:94')
console.log('test2', ' at test.ts:95')
// 条件语句中的测试
if (true) console.log('条件语句', ' at test.ts:98')
if (true) {
console.log('条件语句块', ' at test.ts:100')
}
// 箭头函数中的测试
const fn = () => console.log('箭头函数', ' at test.ts:104')
const fn2 = () => {
console.log('箭头函数块', ' at test.ts:106')
}
console.log(\`console.log('test')\`, ' at test.ts:109')
"
`;

exports[`console console.debug 1`] = `"__f__('info','at foo.vue:1',a,b,c);"`;

exports[`console console.error 1`] = `"__f__('info','at foo.vue:1',a,b,c);"`;
Expand Down
10 changes: 9 additions & 1 deletion packages/uni-cli-shared/__tests__/console.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { rewriteConsoleExpr } from '../src/logs/console'
import fs from 'fs'
import path from 'path'
import { appendConsoleExpr, rewriteConsoleExpr } from '../src/logs/console'
const filename = 'foo.vue'
const METHOD = '__f__'
describe('console', () => {
Expand Down Expand Up @@ -52,4 +54,10 @@ console.log(a,b,c);
.code
).toMatchSnapshot()
})

test('appendConsoleExpr', () => {
const filename = path.resolve(__dirname, 'examples/console/test.ts')
const content = fs.readFileSync(filename, 'utf-8')
expect(appendConsoleExpr('test.ts', content)).toMatchSnapshot()
})
})
109 changes: 109 additions & 0 deletions packages/uni-cli-shared/__tests__/examples/console/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// 基础测试用例
console.log('简单字符串')
console.info('双引号字符串')
console.warn(`模板字符串`)
console.error('带分号的')
console.debug('不带分号的')

// 多参数测试
console.log('参数1', '参数2', '参数3')
console.info(1, true, null, undefined)
console.warn('混合类型', 123, true, null)

// 对象和数组测试
console.log({ name: 'test', age: 18 })
console.log(['a', 'b', 'c'])
console.log({ a: 1 }, ['x', 'y'], { b: 2 })

// 表达式测试
console.log(1 + 2)
console.log(foo())
console.log(a ? b : c)
console.log(obj.method())

// 模板字符串测试
console.log(`Hello ${name}`)
console.log(`多行
模板字符串
测试`)
console.log(`${obj.method()}${arr[0]}`)

// 多行格式测试
console.log('多行参数1', '多行参数2', '多行参数3')

console.log({
name: 'test',
age: 18,
nested: {
a: 1,
b: 2,
},
})

// 嵌套括号测试
console.log(getData('test'))
console.log(outer(inner()))
console.log((a + b) * c)

// 函数调用测试
console.log(foo.bar())
console.log(new Date())
console.log(Array.from(set))

// 复杂混合测试
console.log(
`用户 ${user.name}`,
{
id: user.id,
time: new Date(),
data: getData(user.id),
},
process.env.NODE_ENV === 'development' && '开发环境'
)

// 注释和特殊字符测试
console.log("包含'单引号'")
console.log('包含"双引号"')
console.log(`包含\`反引号\``)
console.log('包含/正斜杠/')
console.log('包含\\反斜杠\\')

// 正则表达式测试
console.log(/test/g)
console.log(new RegExp('test', 'g'))

// 特殊语法测试
console.log(...args)
console.log?.('optional chaining')

// 带注释的测试
console.log(
'test', // 行尾注释
/* 块注释 */ 'test2',
'test3' /* 行内块注释 */
)

// 空参数测试
console.log()
console.log('')
console.log()

// 连续调用测试
console.log('test1')
console.log('test2')
console.log('test1')
console.log('test2')

// 条件语句中的测试
if (true) console.log('条件语句')
if (true) {
console.log('条件语句块')
}

// 箭头函数中的测试
const fn = () => console.log('箭头函数')
const fn2 = () => {
console.log('箭头函数块')
}

console.log(`console.log('test')`)
28 changes: 28 additions & 0 deletions packages/uni-cli-shared/src/logs/console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,31 @@ function getLocator(source: string) {
return { line, column }
}
}

export function appendConsoleExpr(filename: string, code: string) {
filename = normalizePath(filename)
// 使用更复杂的正则来匹配可能包含换行、括号等的参数
const re =
/(console\.(log|info|debug|warn|error))\s*\(([\s\S]*?)(?=\)[;\n]|\)$)/g
const locate = getLocator(code)
const s = new MagicString(code)
let match: RegExpExecArray | null

while ((match = re.exec(code))) {
const [full, _, type, args] = match
const endPos = match.index + full.length + 1 // +1 to include the closing parenthesis
s.overwrite(
match.index,
endPos,
// 重要,需要用双引号,因为混编的kt,swift,java不能用单引号(char类型)
`console.${type}(${args.trim()}, " at ${filename}:${
locate(match.index).line + 1
}")`
)
}

if (s.hasChanged()) {
return s.toString()
}
return code
}
20 changes: 19 additions & 1 deletion packages/uni-cli-shared/src/vite/plugins/uts/uni_modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { parseManifestJsonOnce } from '../../../json'
import { emptyDir } from '../../../fs'
import { initScopedPreContext } from '../../../preprocess/context'
import { isInHBuilderX } from '../../../hbx'
import { rewriteConsoleExpr } from '../../../logs/console'
import { appendConsoleExpr, rewriteConsoleExpr } from '../../../logs/console'

/* eslint-disable no-restricted-globals */
const { preprocess } = require('../../../../lib/preprocess')
Expand All @@ -65,6 +65,22 @@ export function rewriteUniModulesConsoleExpr(
return content
}

function appendUniModulesConsoleExpr(fileName: string, content: string) {
// 仅开发模式补充console.log的at信息
if (process.env.NODE_ENV !== 'development') {
return content
}
if (content.includes('console.')) {
return appendConsoleExpr(
normalizePath(
path.relative(process.env.UNI_INPUT_DIR, fileName.split('?')[0])
),
content
)
}
return content
}

function createUniModulesSyncFilePreprocessor(
platform: UniApp.PLATFORM,
utsPlatform: 'app-android' | 'app-ios' | 'app-harmony',
Expand Down Expand Up @@ -457,6 +473,7 @@ export function uniUTSAppUniModulesPlugin(
isX: !!options.x,
isExtApi,
sourceMap: enableSourceMap(),
rewriteConsoleExpr: appendUniModulesConsoleExpr,
transform: {
uniExtApiProviderName: extApiProvider?.name,
uniExtApiProviderService: extApiProvider?.service,
Expand Down Expand Up @@ -489,6 +506,7 @@ export function uniUTSAppUniModulesPlugin(
extApis: options.extApis,
sourceMap: enableSourceMap(),
uni_modules: deps,
rewriteConsoleExpr: appendUniModulesConsoleExpr,
transform: {
uniExtApiProviderName: extApiProvider?.name,
uniExtApiProviderService: extApiProvider?.service,
Expand Down
20 changes: 18 additions & 2 deletions packages/uni-uts-v1/src/arkts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ interface ArkTSCompilerOptions {
isExtApi?: boolean
isOhpmPackage?: boolean
sourceMap?: boolean
rewriteConsoleExpr?: (fileName: string, content: string) => string
transform?: {
uniExtApiProviderName?: string
uniExtApiProviderService?: string
Expand Down Expand Up @@ -135,7 +136,13 @@ export async function compileArkTSExtApi(
rootDir: string,
pluginDir: string,
outputDir: string,
{ isExtApi, isX, isOhpmPackage = false, sourceMap }: ArkTSCompilerOptions
{
isExtApi,
isX,
isOhpmPackage = false,
sourceMap,
rewriteConsoleExpr,
}: ArkTSCompilerOptions
): Promise<CompileResult | void> {
const filename = resolveAppHarmonyIndexFile(pluginDir)
if (!filename) {
Expand Down Expand Up @@ -208,10 +215,19 @@ export async function compileArkTSExtApi(
const depEtsFiles: string[] = []
for (const etsFile of etsFiles) {
const srcFile = path.resolve(pluginDir, etsFile)
const destFile = path.resolve(outputUniModuleDir, etsFile)
if (etsFile.endsWith('.ets')) {
depEtsFiles.push(srcFile)
if (rewriteConsoleExpr) {
const content = fs.readFileSync(srcFile, 'utf8')
const newContent = rewriteConsoleExpr(srcFile, content)
fs.outputFileSync(destFile, newContent)
} else {
fs.copySync(srcFile, destFile)
}
} else {
fs.copySync(srcFile, destFile)
}
fs.copySync(srcFile, path.resolve(outputUniModuleDir, etsFile))
}

// generate oh-package.json5
Expand Down
3 changes: 3 additions & 0 deletions packages/uni-uts-v1/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ export interface UTSPluginCompilerOptions {
>
androidPreprocessor?: SyncUniModulesFilePreprocessor
iosPreprocessor?: SyncUniModulesFilePreprocessor
rewriteConsoleExpr?: (fileName: string, content: string) => string
}

// 重要:当调整参数时,需要同步调整 vue2 编译器 uni-cli-shared/lib/uts/uts-loader.js
Expand Down Expand Up @@ -180,6 +181,7 @@ export async function compile(
sourceMap,
isSingleThread,
uni_modules,
rewriteConsoleExpr,
} = compilerOptions

let isPlugin = compilerOptions.isPlugin
Expand Down Expand Up @@ -520,6 +522,7 @@ export async function compile(
cacheDir,
pluginRelativeDir,
is_uni_modules: pkg.is_uni_modules,
rewriteConsoleExpr,
extApis,
transform: await initCompilerOptionsTransform(
compilerType,
Expand Down
Loading

0 comments on commit 6b71588

Please sign in to comment.