From e030dcffc332c3cdae5e3a10b9f1ebc26259521c Mon Sep 17 00:00:00 2001 From: yangbo <1442420648@qq.com> Date: Thu, 13 Jan 2022 08:45:04 +0800 Subject: [PATCH] yangbo198@huawei.com Signed-off-by: yangbo <1442420648@qq.com> Change-Id: I24e7b41956e3621418907638760f3041e0b100c8 --- compiler/main.js | 107 ++++++++++++++++++++--------- compiler/package.json | 1 + compiler/src/result_process.ts | 7 +- compiler/src/validate_ui_syntax.ts | 31 +++++++-- compiler/webpack.config.js | 11 ++- 5 files changed, 113 insertions(+), 44 deletions(-) diff --git a/compiler/main.js b/compiler/main.js index c2e4d00be..2e5721d37 100644 --- a/compiler/main.js +++ b/compiler/main.js @@ -33,7 +33,8 @@ const logger = getLogger('ETS'); const staticPreviewPage = process.env.aceStaticPreview; const abilityConfig = { abilityType: process.env.abilityType || 'page', - abilityEntryFile: null + abilityEntryFile: null, + projectAbilityPath: [] }; const projectConfig = {}; const resources = { @@ -49,26 +50,31 @@ function initProjectConfig(projectConfig) { path.resolve(projectConfig.projectPath, 'build'); projectConfig.manifestFilePath = projectConfig.manifestFilePath || process.env.aceManifestPath || path.join(projectConfig.projectPath, 'manifest.json'); - projectConfig.aceConfigPath = projectConfig.aceConfigPath || process.env.aceConfigPath; + projectConfig.aceProfilePath = projectConfig.aceProfilePath || process.env.aceProfilePath; + projectConfig.aceModuleJsonPath = projectConfig.aceModuleJsonPath || process.env.aceModuleJsonPath; } function loadEntryObj(projectConfig) { + let manifest = {}; initProjectConfig(projectConfig); - setEntryFile(projectConfig); - + if (process.env.aceManifestPath) { + setEntryFile(projectConfig); + } + if (process.env.aceModuleJsonPath) { + setAbilityPages(projectConfig) + } if(staticPreviewPage) { projectConfig.entryObj['./' + staticPreviewPage] = projectConfig.projectPath + path.sep + staticPreviewPage + '.ets?entry'; } else if (abilityConfig.abilityType === 'page') { - let manifest = {}; if (fs.existsSync(projectConfig.manifestFilePath)) { const jsonString = fs.readFileSync(projectConfig.manifestFilePath).toString(); manifest = JSON.parse(jsonString); - } else if (process.env.aceConfigPath && fs.existsSync( projectConfig.aceConfigPath)) { - buildManifest(manifest, projectConfig.aceConfigPath); + } else if (projectConfig.aceModuleJsonPath && fs.existsSync(projectConfig.aceModuleJsonPath)) { + buildManifest(manifest, projectConfig.aceConfigPath); } else { throw Error('\u001b[31m ERROR: the manifest file ' + projectConfig.manifestFilePath + - ' or config.json is lost or format is invalid. \u001b[39m').message; + ' or module.json is lost or format is invalid. \u001b[39m').message; } if (manifest.pages) { const pages = manifest.pages; @@ -89,56 +95,95 @@ function loadEntryObj(projectConfig) { function buildManifest(manifest, aceConfigPath) { try { - const configJson = JSON.parse(fs.readFileSync(aceConfigPath).toString()); + const moduleConfigJson = JSON.parse(fs.readFileSync(aceConfigPath).toString()); const srcPath = process.env.srcPath; manifest.type = process.env.abilityType; - if (configJson.module && configJson.module.abilities) { - manifest.pages = getPages(configJson, srcPath); + if (moduleConfigJson.module && moduleConfigJson.module.uiSyntax === 'ets') { + manifest.pages = getPages(moduleConfigJson, srcPath); } else { throw Error('\u001b[31m'+ - 'EERROR: the config.json file miss keyword module || module[abilities].' + + 'EERROR: the config.json file miss key word module || module[abilities].' + '\u001b[39m').message; } - manifest.minPlatformVersion = configJson.app.apiVersion.compatible; } catch (e) { - throw Error("\x1B[31m" + 'ERROR: the config.json file is lost or format is invalid.' + + throw Error("\x1B[31m" + 'ERROR: the module.json file is lost or format is invalid.' + "\x1B[39m").message; } } function getPages(configJson, srcPath) { const pages = [] - for (const ability of configJson.module.abilities){ - if (ability.srcPath === srcPath) { - readPages(ability, pages, configJson) - break; + const modulePagePath = path.resolve(projectConfig.aceProfilePath, + `${configJson.module.pages.replace(/\@profile\:/, '')}.json`); + if (fs.existsSync(modulePagePath)) { + const pagesConfig = JSON.parse(fs.readFileSync(modulePagePath, 'utf-8')); + if (pagesConfig && pagesConfig.src) { + return pagesConfig.src; } } return pages; } -function readPages(ability, pages, configJson) { - for (const js of configJson.module.js){ - if (ability.name === js.name) { - js.pages.forEach(page => { - pages.push(page) - }) - break; - } - } -} - function setEntryFile(projectConfig) { const entryFileName = abilityConfig.abilityType === 'page' ? 'app' : abilityConfig.abilityType; const extendFile = entryFileName === 'app' ? '.ets' : '.ts'; - abilityConfig.abilityEntryFile = entryFileName + extendFile; - const entryFilePath = path.join(projectConfig.projectPath, abilityConfig.abilityEntryFile); + const entryFileRealPath = entryFileName + extendFile; + const entryFilePath = path.join(projectConfig.projectPath, entryFileRealPath); + abilityConfig.abilityEntryFile = entryFilePath; if (!fs.existsSync(entryFilePath)) { throw Error(`\u001b[31m ERROR: missing ${entryFilePath}. \u001b[39m`).message; } projectConfig.entryObj[`./${entryFileName}`] = projectConfig.projectPath + `/${abilityConfig.abilityEntryFile}?entry`; } +function setAbilityPages(projectConfig) { + let abilityPages = []; + if (projectConfig.aceModuleJsonPath && fs.existsSync(projectConfig.aceModuleJsonPath)) { + const moduleJson = JSON.parse(fs.readFileSync(projectConfig.aceModuleJsonPath).toString()); + abilityPages = readAbilityEntrance(moduleJson); + setAbilityFile(projectConfig, abilityPages); + } +} + +function setAbilityFile(projectConfig, abilityPages) { + abilityPages.forEach(abilityPath => { + if (abilityPath && fs.existsSync(path.resolve(projectConfig.projectPath, '../', abilityPath))) { + const projectAbilityPath = path.resolve(projectConfig.projectPath, '../', abilityPath); + const entryPageKey = abilityPath.replace(/^\.\/ets\//, './').replace(/\.ts$/, ''); + abilityConfig.projectAbilityPath.push(projectAbilityPath); + if (fs.existsSync(projectAbilityPath)) { + projectConfig.entryObj[entryPageKey] = projectAbilityPath + '?entry'; + } + } + }); +} + +function readAbilityEntrance(moduleJson) { + let abilityPages = []; + if (moduleJson.module) { + if (moduleJson.module.srcEntrance) { + abilityPages.push(moduleJson.module.srcEntrance); + } + if (moduleJson.module.abilities && moduleJson.module.abilities.length > 0) { + setEntrance(moduleJson.module.abilities, abilityPages); + } + if (moduleJson.module.extensionAbilities && moduleJson.module.extensionAbilities.length > 0) { + setEntrance(moduleJson.module.extensionAbilities, abilityPages); + } + } + return abilityPages; +} + +function setEntrance(abilityConfig, abilityPages) { + if (abilityConfig && abilityConfig.length > 0) { + abilityConfig.forEach(ability => { + if (ability.srcEntrance) { + abilityPages.push(ability.srcEntrance); + } + }); + } +} + function loadWorker(projectConfig) { const workerPath = path.resolve(projectConfig.projectPath, WORKERS_DIR); if (fs.existsSync(workerPath)) { diff --git a/compiler/package.json b/compiler/package.json index 15cd82e13..0efc498ec 100644 --- a/compiler/package.json +++ b/compiler/package.json @@ -38,6 +38,7 @@ "clean-webpack-plugin": "^3.0.0", "copy-webpack-plugin": "^8.1.0", "deccjsunit": "^1.0.6", + "ignore-loader": "^0.1.2", "log4js": "^6.3.0", "ts-loader": "^8.0.12", "typescript": "^4.1.3", diff --git a/compiler/src/result_process.ts b/compiler/src/result_process.ts index 6dcc80657..46ea7920f 100644 --- a/compiler/src/result_process.ts +++ b/compiler/src/result_process.ts @@ -23,7 +23,8 @@ import { } from './process_ui_syntax'; import { propertyCollection, - linkCollection + linkCollection, + processSystemApi } from './validate_ui_syntax'; import { LogInfo, @@ -35,6 +36,7 @@ import { abilityConfig } from '../main'; module.exports = function resultProcess(source: string, map: any): void { process.env.compiler = BUILD_OFF; + source = processSystemApi(source, true); if (/\.ets$/.test(this.resourcePath)) { componentInfo.id = 0; propertyCollection.clear(); @@ -58,8 +60,7 @@ module.exports = function resultProcess(source: string, map: any): void { resetLog(); } } - const resourcePath: string = path.basename(this.resourcePath); - if (['app.ets', abilityConfig.abilityEntryFile].includes(resourcePath)) { + if ([abilityConfig.abilityEntryFile].concat(abilityConfig.projectAbilityPath).includes(this.resourcePath)) { source = source.replace(/exports\.default/, 'globalThis.exports.default'); } diff --git a/compiler/src/validate_ui_syntax.ts b/compiler/src/validate_ui_syntax.ts index 0bae01881..622cb93d6 100644 --- a/compiler/src/validate_ui_syntax.ts +++ b/compiler/src/validate_ui_syntax.ts @@ -800,19 +800,32 @@ function collectExtend(component: string, attribute: string, parameter: string): } } -export function processSystemApi(content: string): string { - const REG_SYSTEM: RegExp = - /import\s+(.+)\s+from\s+['"]@(system|ohos)\.(\S+)['"]|import\s+(.+)\s*=\s*require\(\s*['"]@(system|ohos)\.(\S+)['"]\s*\)/g; +export function processSystemApi(content: string, isProcessWhiteList: boolean = false): string { + let REG_SYSTEM: RegExp; + if (isProcessWhiteList) { + REG_SYSTEM = + /import\s+(.+)\s+from\s+['"]@(system|ohos)\.(\S+)['"]|(import|const)\s+(.+)\s*=\s*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; return content.replace(REG_LIB_SO, (_, item1, item2, item3, item4) => { const libSoValue: string = item1 || item3; const libSoKey: string = item2 || item4; return `var ${libSoValue} = globalThis.requireNapi("${libSoKey}", true);`; - }).replace(REG_SYSTEM, (item, item1, item2, item3, item4, item5, item6) => { - const moduleType: string = item2 || item5; - const systemKey: string = item3 || item6; - const systemValue: string = item1 || item4; + }).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 (!isProcessWhiteList && validateWhiteListModule(moduleType, systemKey)) { + return item; + } else if (isProcessWhiteList) { + systemValue = item5; + moduleType = item6; + systemKey = item7; + } moduleCollection.add(`${moduleType}.${systemKey}`); if (NATIVE_MODULE.has(`${moduleType}.${systemKey}`)) { item = `var ${systemValue} = globalThis.requireNativeModule('${moduleType}.${systemKey}')`; @@ -829,6 +842,10 @@ export function processSystemApi(content: string): string { }); } +function validateWhiteListModule(moduleType: string, systemKey: string): boolean { + return moduleType === 'ohos' && /^application\./g.test(systemKey); +} + export function resetComponentCollection() { componentCollection.entryComponent = null; componentCollection.previewComponent = null; diff --git a/compiler/webpack.config.js b/compiler/webpack.config.js index bebea8d56..4050b6c0f 100644 --- a/compiler/webpack.config.js +++ b/compiler/webpack.config.js @@ -78,7 +78,11 @@ function initConfig(config) { module: { rules: [ { - test: /\.(ets|ts)$/, + test: /\.d\.ts/, + loader: 'ignore-loader' + }, + { + test: /(?