SDK中的API文件名称@ohos标识无法更改问题分析报告
1 关键字
SDK;API文件名称;@ohos;
2 问题描述
问题现象:SDK中的API文件名称@ohos无法更改自定义名称,只能以@ohos
和@system
为标识,才可正确识别为API文件和调用。
3 问题原因
(1)更改API文件名称为以其他标识开头的文件名称,例如:将@ohos.power.d.ts
改为@tvos.power.d.ts
.
(2)在页面中引入API模块,并调用接口。
import Power from '@tvos.power'
@Entry
@Component
export default struct Test {
build() {
Column() {
Button('重启')
.onClick(() => {
Power_tv.rebootDevice('')
})
}
.height('100%')
.width('100%')
}
}
(3)编译代码。
3.1 正常机制
编译后API引入代码:
var _power_1 = globalThis.requireNapi('power') || (isSystemplugin('power', 'ohos') ? globalThis.ohosplugin.power : isSystemplugin('power', 'system') ? globalThis.systemplugin.power : undefined);
3.2 异常机制
编译后API引入代码如下,未识别为API进行正确的引入。
const _power_1 = __importDefault(__webpack_require__(/*! @tvos.power */ "../../api/@tvos.power.d.ts"));
4 解决方案
修改OpenHarmony应用编译仓(ace_ets2bundle)的源码,使应用编译工具支持自定义的API文件标识。
(1)修改文件developtools/ace_ets2bundle/compiler/src/pre_define.ts
,增加新标识。
export const SYSTEM_PLUGIN: string = 'system'; // 原有标识 export const OHOS_PLUGIN: string = 'ohos'; // 原有标识 export const TVOS_PLUGIN: string = 'tvos'; // 增加新标识
(2)修改文件developtools/ace_ets2bundle/compiler/src/validate_ui_syntax.ts
,增加判断和编译逻辑。
···
import {
···
TVOS_PLUGIN, // 引入新增的标识
···
} from './pre_define';
···
function replaceSystemApi(item: string, systemValue: string, moduleType: string, systemKey: string): string {
···
} else if (moduleType === TVOS_PLUGIN) { // 增加新标识的编译逻辑
item = `var ${systemValue} = globalThis.requireNapi('${systemKey}') || ` +
`(isSystemplugin('${systemKey}', '${OHOS_PLUGIN}') ? ` +
`globalThis.ohosplugin.${systemKey} : isSystemplugin('${systemKey}', '${SYSTEM_PLUGIN}') ` +
`? globalThis.systemplugin.${systemKey} : undefined)`;
}
return item;
}
···
export function processSystemApi(content: string, isProcessAllowList: boolean = false,
sourcePath: string = null, isSystemModule: boolean = false): string {
if (isProcessAllowList && projectConfig.compileMode === ESMODULE) {
const REG_UNUSED_SYSTEM_IMPORT: RegExp = /import(?:\s*)['"]@(system|ohos|tvos)\.(\S+)['"]/g; // 增加移除未使用API时的标识
content = content.replace(REG_UNUSED_SYSTEM_IMPORT, '');
}
const REG_IMPORT_DECL: RegExp = isProcessAllowList ? projectConfig.compileMode === ESMODULE ? // 增加新标识
/import\s+(.+)\s+from\s+['"]@(system|ohos|tvos)\.(\S+)['"]/g :
/(import|const)\s+(.+)\s*=\s*(\_\_importDefault\()?require\(\s*['"]@(system|ohos|tvos)\.(\S+)['"]\s*\)(\))?/g :
/(import|export)\s+(?:(.+)|\{([\s\S]+)\})\s+from\s+['"](\S+)['"]|import\s+(.+)\s*=\s*require\(\s*['"](\S+)['"]\s*\)/g;
const systemValueCollection: Set<string> = new Set();
const processedContent: string = content.replace(REG_IMPORT_DECL, (item, item1, item2, item3, item4, item5, item6) => {
···
if (isOhmUrl(moduleRequest)) {
return replaceOhmUrl(isSystemModule, item, importValue, moduleRequest, sourcePath);
} else if (/^@(system|ohos|tvos)\./.test(moduleRequest)) { // 增加新标识
if (!isSystemModule) {
return item;
}
const result: RegExpMatchArray = moduleRequest.match(/^@(system|ohos|tvos)\.(\S+)$/); // 增加新标识
const moduleType: string = result[1];
const apiName: string = result[2];
return replaceSystemApi(item, importValue, moduleType, apiName);
}
···
return item;
});
return processInnerModule(processedContent, systemValueCollection);
}
···
function collectSourcemapNames(sourcePath: string, changedName: string, originalName: string): void {
···
for (let entry of originalImportNamesMap.entries()) {
const key: string = entry[0];
const value: string = entry[1];
if (value === '@ohos.' + originalName || value === '@system.' + originalName || value === '@tvos.' + originalName) { // 增加新标识
map.set(changedName.trim(), key);
sourcemapNamesCollection.set(cleanSourcePath, map);
originalImportNamesMap.delete(key);
break;
}
}
}
5 定位过程
(1)在页面中引入@ohos
标识的API模块,查看编译后生成的js
文件,发现API被requireNapi
方法进行加载。
var _power_1 = globalThis.requireNapi('power') || (isSystemplugin('power', 'ohos') ? globalThis.ohosplugin.power : isSystemplugin('power', 'system') ? globalThis.systemplugin.power : undefined);
(2)在应用编译仓(ace_ets2bundle)源码中搜索requireNapi
方法,发现在developtools/ace_ets2bundle/compiler/src/validate_ui_syntax.ts
文件中对API的加载进行了处理。
(3)逆向查找replaceSystemApi
方法调用位置,依次修改判断条件和逻辑,增加新标识。
6 知识分享
修改、编译和替换SDK步骤:
(1)修改源码 ace_ets2bundle 项目代码。项目仓地址:https://gitee.com/openharmony/developtools_ace_ets2bundle。仓库在OpenHarmony源码的位置developtools/ace_ets2bundle 如下图:
(2)执行SDK编译指令:./build.sh --product-name ohos-sdk
(3)编译成功后,在out/sdk/packages/ohos-sdk中生成相应SDK的压缩包。
(4)解压后更改目录名称为SDK版本名称,放入SDK的ets目录中。
更多推荐
所有评论(0)