mirror of
https://github.com/openharmony/developtools_ace-ets2bundle.git
synced 2026-07-18 16:04:32 -04:00
compile with ohm_url module
Signed-off-by: hufeng <hufeng20@huawei.com> Change-Id: I84ebf3292aae496a0e2acf546328063eb91d9c33
This commit is contained in:
@@ -36,6 +36,7 @@ import { JS_BIND_COMPONENTS } from './component_map';
|
||||
import { getName } from './process_component_build';
|
||||
import { INNER_COMPONENT_NAMES } from './component_map';
|
||||
import { props } from './compile_info';
|
||||
import { resolveSourceFile } from './resolve_ohm_url';
|
||||
|
||||
function readDeaclareFiles(): string[] {
|
||||
const declarationsFileNames: string[] = [];
|
||||
@@ -109,6 +110,21 @@ export function createLanguageService(rootFileNames: string[]): ts.LanguageServi
|
||||
return ts.createLanguageService(servicesHost, ts.createDocumentRegistry());
|
||||
}
|
||||
|
||||
function getOhmUrlFile(moduleName: string): {modulePath: string, suffix: string} {
|
||||
let modulePath = resolveSourceFile(moduleName);
|
||||
let suffix: string;
|
||||
if (modulePath.endsWith('.ets')) {
|
||||
suffix = '.ets';
|
||||
} else if (modulePath.endsWith('.ts')) {
|
||||
suffix = '.ts';
|
||||
} else {
|
||||
modulePath = modulePath.replace('.js', '.d.ts');
|
||||
suffix = '.d.ts';
|
||||
}
|
||||
|
||||
return {modulePath, suffix};
|
||||
}
|
||||
|
||||
function resolveModuleNames(moduleNames: string[], containingFile: string): ts.ResolvedModuleFull[] {
|
||||
const resolvedModules: ts.ResolvedModuleFull[] = [];
|
||||
for (const moduleName of moduleNames) {
|
||||
@@ -122,6 +138,13 @@ function resolveModuleNames(moduleNames: string[], containingFile: string): ts.R
|
||||
});
|
||||
if (result.resolvedModule) {
|
||||
resolvedModules.push(result.resolvedModule);
|
||||
} else if (/^@bundle:/.test(moduleName.trim())) {
|
||||
const module = getOhmUrlFile(moduleName.trim());
|
||||
if (ts.sys.fileExists(module.modulePath)) {
|
||||
resolvedModules.push(getResolveModule(module.modulePath, module.suffix));
|
||||
} else {
|
||||
resolvedModules.push(null);
|
||||
}
|
||||
} else if (/^@(system|ohos)/.test(moduleName.trim())) {
|
||||
const modulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ts');
|
||||
if (ts.sys.fileExists(modulePath)) {
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { logger } from './compile_info';
|
||||
const { projectConfig } = require('../main');
|
||||
|
||||
const red: string = '\u001b[31m';
|
||||
const reset: string = '\u001b[39m';
|
||||
|
||||
const REG_OHM_URL = /^@bundle:(\S+)\/(\S+)\/(ets|js|node_modules)\/(\S+)$/;
|
||||
|
||||
export class OHMResolverPlugin {
|
||||
private source: any;
|
||||
private target: any;
|
||||
|
||||
constructor(source = 'resolve', target = 'resolve') {
|
||||
this.source = source;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
apply(resolver) {
|
||||
const target = resolver.ensureHook(this.target);
|
||||
resolver.getHook(this.source).tapAsync("OHMResolverPlugin", (request, resolveContext, callback) => {
|
||||
if (/^@bundle:/.test(request.request)) {
|
||||
var resolvedSourceFile: string = resolveSourceFile(request.request);
|
||||
var obj = Object.assign({}, request, {
|
||||
request: resolvedSourceFile
|
||||
});
|
||||
return resolver.doResolve(target, obj, null, resolveContext, callback);
|
||||
}
|
||||
callback();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveSourceFile(ohmUrl: string): string {
|
||||
const result = ohmUrl.match(REG_OHM_URL);
|
||||
// let bundleName = result[1];
|
||||
let moduleName = result[2];
|
||||
let srcKind = result[3];
|
||||
let file = path.join(projectConfig.projectPath, '../../../../../', moduleName, 'src/main', srcKind, result[4]);
|
||||
if(srcKind == 'ets') {
|
||||
if (!file.endsWith('.ets') && !file.endsWith('ts')) {
|
||||
if (fs.existsSync(file + '.ets') && fs.statSync(file + '.ets').isFile()) {
|
||||
file += '.ets';
|
||||
} else {
|
||||
file += '.ts';
|
||||
}
|
||||
}
|
||||
} else if(srcKind == 'js') {
|
||||
if (!file.endsWith('.js')) {
|
||||
file += '.js';
|
||||
}
|
||||
} else {
|
||||
// Todo: node_modules
|
||||
}
|
||||
|
||||
if (!fs.existsSync(file) || !fs.statSync(file).isFile()) {
|
||||
logger.error(red, `ETS:ERROR Failed to resolve existed file by this ohm url ${ohmUrl} `, reset);
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
@@ -126,6 +126,7 @@ export const localStoragePropCollection: Map<string, Map<string, Set<string>>> =
|
||||
|
||||
export const isStaticViewCollection: Map<string, boolean> = new Map();
|
||||
|
||||
export const packageCollection: Map<string, Array<string>> = new Map();
|
||||
export const moduleCollection: Set<string> = new Set();
|
||||
export const useOSFiles: Set<string> = new Set();
|
||||
|
||||
@@ -829,56 +830,155 @@ export function preprocessNewExtend(content: string, extendCollection?: Set<stri
|
||||
});
|
||||
}
|
||||
|
||||
function getPackageInfo(configFile: string): Array<string> {
|
||||
if (packageCollection.has(configFile)) {
|
||||
return packageCollection.get(configFile);
|
||||
}
|
||||
|
||||
const rawData: string = fs.readFileSync(configFile, 'utf-8');
|
||||
const data = JSON.parse(rawData);
|
||||
const bundleName = data.app.bundleName;
|
||||
const moduleName = data.module.distro.moduleName;
|
||||
packageCollection.set(configFile, [bundleName, moduleName]);
|
||||
return [bundleName, moduleName];
|
||||
}
|
||||
|
||||
function replaceSystemApi(item: string, systemValue: string, moduleType: string, systemKey: string) {
|
||||
moduleCollection.add(`${moduleType}.${systemKey}`);
|
||||
if (NATIVE_MODULE.has(`${moduleType}.${systemKey}`)) {
|
||||
item = `var ${systemValue} = globalThis.requireNativeModule('${moduleType}.${systemKey}')`;
|
||||
} else if (moduleType === SYSTEM_PLUGIN) {
|
||||
item = `var ${systemValue} = isSystemplugin('${systemKey}', '${SYSTEM_PLUGIN}') ? ` +
|
||||
`globalThis.systemplugin.${systemKey} : globalThis.requireNapi('${systemKey}')`;
|
||||
} else if (moduleType === OHOS_PLUGIN) {
|
||||
item = `var ${systemValue} = globalThis.requireNapi('${systemKey}') || ` +
|
||||
`(isSystemplugin('${systemKey}', '${OHOS_PLUGIN}') ? ` +
|
||||
`globalThis.ohosplugin.${systemKey} : isSystemplugin('${systemKey}', '${SYSTEM_PLUGIN}') ` +
|
||||
`? globalThis.systemplugin.${systemKey} : undefined)`;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
function replaceLibSo(importValue: string, libSoKey: string, sourcePath: string = null) {
|
||||
if (sourcePath) {
|
||||
useOSFiles.add(sourcePath);
|
||||
}
|
||||
return `var ${importValue} = globalThis.requireNapi("${libSoKey}", true);`;
|
||||
}
|
||||
|
||||
function replaceOhmUrl(isSystemModule: boolean, item: string, importValue: string, moduleRequest: string, sourcePath: string = null) {
|
||||
const result = moduleRequest.match(/^@(\S+):(\S+)$/)
|
||||
let urlType: string = result[1];
|
||||
let url: string = result[2];
|
||||
switch(urlType) {
|
||||
case 'bundle': {
|
||||
let urlResult = url.match(/^(\S+)\/(\S+)\/(\S+)\/(\S+)$/);
|
||||
let moduleKind = urlResult[3];
|
||||
if (moduleKind == 'lib') {
|
||||
item = replaceLibSo(importValue, moduleRequest, sourcePath);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'module': {
|
||||
let urlResult = url.match(/^(\S+)\/(\S+)\/(\S+)$/);
|
||||
let moduleName = urlResult[1];
|
||||
let moduleKind = urlResult[2];
|
||||
let modulePath = urlResult[3];
|
||||
const configJsonFile: string =
|
||||
path.join(projectConfig.projectPath, '../../../../../', moduleName, 'src/main/config.json');
|
||||
let bundleName = getPackageInfo(configJsonFile)[0];
|
||||
moduleRequest = `@bundle:${bundleName}/${moduleName}/${moduleKind}/${modulePath}`;
|
||||
item = moduleKind == 'lib' ?
|
||||
replaceLibSo(importValue, moduleRequest, sourcePath) : item.replace(/['"](\S+)['"]/, moduleRequest);
|
||||
break;
|
||||
}
|
||||
case 'ohos': {
|
||||
url = url.replace('/', '.');
|
||||
let urlResult = url.match(/^system\.(\S+)/)
|
||||
moduleRequest = urlResult ? `@${url}` : `@ohos.${url}`;
|
||||
if (!isSystemModule) {
|
||||
item = item.replace(/['"](\S+)['"]/, moduleRequest);
|
||||
} else {
|
||||
let moduleType = urlResult ? 'system' : 'ohos';
|
||||
let systemKey = urlResult ? url.substring(7) : url;
|
||||
item = replaceSystemApi(item, importValue, moduleType, systemKey);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'lib': {
|
||||
item = replaceLibSo(importValue, url, sourcePath);
|
||||
break;
|
||||
}
|
||||
case 'local': {
|
||||
let result = sourcePath.match(/(S+)\/src\/main\/(S+)/);
|
||||
const configJsonFile: string = `${result[1]}/src/main/config.json`;
|
||||
let packageInfo = getPackageInfo(configJsonFile);
|
||||
let urlResult = url.match(/^(ets|js|lib)\/(S+)$/);
|
||||
let moduleKind = urlResult[1];
|
||||
let modulePath = urlResult[2];
|
||||
if (moduleKind == 'lib') {
|
||||
item = replaceLibSo(importValue, modulePath, sourcePath);
|
||||
} else {
|
||||
moduleRequest = `@bundle:${packageInfo[0]}/${packageInfo[1]}/${moduleKind}/${modulePath}`;
|
||||
item = item.replace(/['"](\S+)['"]/, moduleRequest);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
console.error("Incorrect OpenHarmony module kind: ", urlType);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
function replaceRelativePath(moduleRequest: string, sourcePath: string) {
|
||||
let filePath = path.resolve(sourcePath, moduleRequest);
|
||||
let result = filePath.match(/(S+)\/src\/main\/(ets|js)\/(S+)/);
|
||||
const configJsonFile: string = `${result[1]}/src/main/config.json`;
|
||||
let packageInfo = getPackageInfo(configJsonFile);
|
||||
let bundleName = packageInfo[0];
|
||||
let moduleName = packageInfo[1];
|
||||
|
||||
return `@bundle:${bundleName}/${moduleName}/${result[2]}/${result[3]}`;
|
||||
}
|
||||
|
||||
export function processSystemApi(content: string, isProcessAllowList: boolean = false,
|
||||
sourcePath: string = null, isSystemModule: boolean = false): string {
|
||||
let REG_SYSTEM: RegExp;
|
||||
if (isProcessAllowList) {
|
||||
REG_SYSTEM =
|
||||
/(import|const)\s+(.+)\s*=\s*(\_\_importDefault\()?require\(\s*['"]@(system|ohos)\.(\S+)['"]\s*\)(\))?/g;
|
||||
} else {
|
||||
REG_SYSTEM =
|
||||
/import\s+(.+)\s+from\s+['"]@(system|ohos)\.(\S+)['"]|import\s+(.+)\s*=\s*require\(\s*['"]@(system|ohos)\.(\S+)['"]\s*\)/g;
|
||||
}
|
||||
const REG_LIB_SO: RegExp =
|
||||
/import\s+(.+)\s+from\s+['"]lib(\S+)\.so['"]|import\s+(.+)\s*=\s*require\(\s*['"]lib(\S+)\.so['"]\s*\)/g;
|
||||
const systemValueCollection: Set<string> = new Set();
|
||||
const newContent: string = content.replace(REG_LIB_SO, (_, item1, item2, item3, item4) => {
|
||||
const libSoValue: string = item1 || item3;
|
||||
const libSoKey: string = item2 || item4;
|
||||
if (sourcePath) {
|
||||
useOSFiles.add(sourcePath);
|
||||
const REG_IMPORT_DECL = isProcessAllowList ?
|
||||
/(import|const)\s+(.+)\s*=\s*(\_\_importDefault\()?require\(\s*['"]@(system|ohos)\.(\S+)['"]\s*\)(\))?/g :
|
||||
/import\s+(.+)\s+from\s+['"](\S+)['"]|import\s+(.+)\s*=\s*require\(\s*['"](\S+)['"]\s*\)/g;
|
||||
|
||||
const processedContent: string = content.replace(REG_IMPORT_DECL, (item, item1, item2, item3, item4, item5) => {
|
||||
let importValue: string = isProcessAllowList ? item2 : item1 || item3;
|
||||
|
||||
if (isProcessAllowList) {
|
||||
systemValueCollection.add(importValue);
|
||||
return replaceSystemApi(item, importValue, item4, item5);
|
||||
}
|
||||
return `var ${libSoValue} = globalThis.requireNapi("${libSoKey}", true);`;
|
||||
}).replace(REG_SYSTEM, (item, item1, item2, item3, item4, item5, item6, item7) => {
|
||||
let moduleType: string = item2 || item5;
|
||||
let systemKey: string = item3 || item6;
|
||||
let systemValue: string = item1 || item4;
|
||||
if (!VALIDATE_MODULE.includes(systemValue)) {
|
||||
importModuleCollection.add(systemValue);
|
||||
}
|
||||
if (!isProcessAllowList && !isSystemModule) {
|
||||
return item;
|
||||
} else if (isProcessAllowList) {
|
||||
systemValue = item2;
|
||||
moduleType = item4;
|
||||
systemKey = item5;
|
||||
systemValueCollection.add(systemValue);
|
||||
}
|
||||
moduleCollection.add(`${moduleType}.${systemKey}`);
|
||||
if (NATIVE_MODULE.has(`${moduleType}.${systemKey}`)) {
|
||||
item = `var ${systemValue} = globalThis.requireNativeModule('${moduleType}.${systemKey}')`;
|
||||
} else if (moduleType === SYSTEM_PLUGIN) {
|
||||
item = `var ${systemValue} = isSystemplugin('${systemKey}', '${SYSTEM_PLUGIN}') ? ` +
|
||||
`globalThis.systemplugin.${systemKey} : globalThis.requireNapi('${systemKey}')`;
|
||||
} else if (moduleType === OHOS_PLUGIN) {
|
||||
item = `var ${systemValue} = globalThis.requireNapi('${systemKey}') || ` +
|
||||
`(isSystemplugin('${systemKey}', '${OHOS_PLUGIN}') ? ` +
|
||||
`globalThis.ohosplugin.${systemKey} : isSystemplugin('${systemKey}', '${SYSTEM_PLUGIN}') ` +
|
||||
`? globalThis.systemplugin.${systemKey} : undefined)`;
|
||||
|
||||
let moduleRequest: string = item2 || item4;
|
||||
if (/^@(\S+):/.test(moduleRequest)) { // ohmURL
|
||||
return replaceOhmUrl(isSystemModule, item, importValue, moduleRequest, sourcePath);
|
||||
} else if (/^@(system|ohos)\./.test(moduleRequest)) { //ohos/system.api
|
||||
// ets & ts file need compile with .d.ts, so do not replace at the phase of pre_process
|
||||
if (!isSystemModule) {
|
||||
return item;
|
||||
}
|
||||
let result = moduleRequest.match(/^@(system|ohos)\.(\S+)$/);
|
||||
let moduleType: string = result[1];
|
||||
let apiName: string = result[2];
|
||||
return replaceSystemApi(item, importValue, moduleType, apiName);
|
||||
} else if (/^(\.|\.\.)\//.test(moduleRequest)) { // relativePath
|
||||
return replaceRelativePath(moduleRequest, sourcePath);
|
||||
} else if (/^lib(\S+)\.so$/.test(moduleRequest)) { // libxxx.so
|
||||
let result = moduleRequest.match(/^lib(\S+)\.so$/);
|
||||
let libSoKey = result[1];
|
||||
return replaceLibSo(importValue, libSoKey, sourcePath);
|
||||
}
|
||||
// node_modules
|
||||
return item;
|
||||
});
|
||||
return processInnerModule(newContent, systemValueCollection);
|
||||
return isProcessAllowList ? processInnerModule(processedContent, systemValueCollection) : processedContent;
|
||||
}
|
||||
|
||||
function processInnerModule(content: string, systemValueCollection: Set<string>): string {
|
||||
|
||||
@@ -18,6 +18,7 @@ const fs = require('fs');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const Webpack = require('webpack');
|
||||
const { GenAbcPlugin } = require('./lib/gen_abc_plugin');
|
||||
const { OHMResolverPlugin } = require('./lib/resolve_ohm_url');
|
||||
const buildPipeServer = require('./server/build_pipe_server');
|
||||
|
||||
const {
|
||||
@@ -100,6 +101,7 @@ function initConfig(config) {
|
||||
global: false
|
||||
},
|
||||
resolve: {
|
||||
plugins: [new OHMResolverPlugin()],
|
||||
extensions: ['.js', '.ets', '.ts', '.d.ts'],
|
||||
modules: [
|
||||
projectPath,
|
||||
|
||||
Reference in New Issue
Block a user