mirror of
https://github.com/openharmony/developtools_ace-ets2bundle.git
synced 2026-07-19 16:43:34 -04:00
!1086 增量检查+热加载性能劣化挑单3.1release
Merge pull request !1086 from houhaoyu/release
This commit is contained in:
@@ -33,7 +33,6 @@ import {
|
||||
moduleCollection,
|
||||
useOSFiles
|
||||
} from './validate_ui_syntax';
|
||||
import { projectConfig } from '../main';
|
||||
import {
|
||||
circularFile,
|
||||
mkDir,
|
||||
@@ -50,7 +49,10 @@ import {
|
||||
importModuleCollection,
|
||||
createWatchCompilerHost
|
||||
} from './ets_checker';
|
||||
import { globalProgram } from '../main';
|
||||
import {
|
||||
globalProgram,
|
||||
projectConfig
|
||||
} from '../main';
|
||||
|
||||
configure({
|
||||
appenders: { 'ETS': {type: 'stderr', layout: {type: 'messagePassThrough'}}},
|
||||
@@ -69,6 +71,21 @@ interface Info {
|
||||
};
|
||||
}
|
||||
|
||||
export interface CacheFileName {
|
||||
mtimeMs: number,
|
||||
children: string[],
|
||||
parent: string[],
|
||||
error: boolean
|
||||
}
|
||||
|
||||
interface NeedUpdateFlag {
|
||||
flag: boolean;
|
||||
}
|
||||
|
||||
export let cache: Cache = {};
|
||||
export const shouldResolvedFiles: Set<string> = new Set()
|
||||
type Cache = Record<string, CacheFileName>;
|
||||
|
||||
export class ResultStates {
|
||||
private mStats: Stats;
|
||||
private mErrorCount: number = 0;
|
||||
@@ -171,7 +188,16 @@ export class ResultStates {
|
||||
createWatchCompilerHost(rootFileNames, this.printDiagnostic.bind(this),
|
||||
this.delayPrintLogCount.bind(this)));
|
||||
} else {
|
||||
const languageService: ts.LanguageService = createLanguageService(rootFileNames);
|
||||
let languageService: ts.LanguageService = null;
|
||||
let cacheFile: string = null;
|
||||
if (projectConfig.xtsMode) {
|
||||
languageService = createLanguageService(rootFileNames);
|
||||
} else {
|
||||
cacheFile = path.resolve(projectConfig.cachePath, '../.ts_checker_cache');
|
||||
cache = fs.existsSync(cacheFile) ? JSON.parse(fs.readFileSync(cacheFile).toString()) : {};
|
||||
const filterFiles: string[] = filterInput(rootFileNames);
|
||||
languageService = createLanguageService(filterFiles);
|
||||
}
|
||||
globalProgram.program = languageService.getProgram();
|
||||
const allDiagnostics: ts.Diagnostic[] = globalProgram.program
|
||||
.getSyntacticDiagnostics()
|
||||
@@ -180,6 +206,9 @@ export class ResultStates {
|
||||
allDiagnostics.forEach((diagnostic: ts.Diagnostic) => {
|
||||
this.printDiagnostic(diagnostic);
|
||||
});
|
||||
if (process.env.watchMode !== 'true' && !projectConfig.xtsMode) {
|
||||
fs.writeFileSync(cacheFile, JSON.stringify(cache, null, 2));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -200,15 +229,26 @@ export class ResultStates {
|
||||
this.printResult();
|
||||
});
|
||||
|
||||
compiler.hooks.watchRun.tap('Listening State', (compiler: Compiler) => {
|
||||
if (compiler.modifiedFiles) {
|
||||
const isTsAndEtsFile: boolean = [...compiler.modifiedFiles].some((item: string) => {
|
||||
compiler.hooks.watchRun.tap('Listening State', (comp: Compiler) => {
|
||||
comp.modifiedFiles = comp.modifiedFiles || [];
|
||||
comp.removedFiles = comp.removedFiles || [];
|
||||
const watchModifiedFiles: string[] = [...comp.modifiedFiles];
|
||||
const watchRemovedFiles: string[] = [...comp.removedFiles];
|
||||
if (watchModifiedFiles.length) {
|
||||
const isTsAndEtsFile: boolean = watchModifiedFiles.some((item: string) => {
|
||||
return /.(ts|ets)$/.test(item);
|
||||
});
|
||||
if (!isTsAndEtsFile) {
|
||||
process.env.watchTs = 'end';
|
||||
}
|
||||
}
|
||||
const changedFiles: string[] = [...watchModifiedFiles, ...watchRemovedFiles];
|
||||
if (changedFiles.length) {
|
||||
shouldResolvedFiles.clear();
|
||||
}
|
||||
changedFiles.forEach((file) => {
|
||||
this.judgeFileShouldResolved(file, shouldResolvedFiles)
|
||||
})
|
||||
});
|
||||
|
||||
if (!projectConfig.isPreview) {
|
||||
@@ -221,6 +261,25 @@ export class ResultStates {
|
||||
}
|
||||
}
|
||||
|
||||
private judgeFileShouldResolved(file: string, shouldResolvedFiles: Set<string>): void {
|
||||
if (shouldResolvedFiles.has(file)) {
|
||||
return;
|
||||
}
|
||||
shouldResolvedFiles.add(file);
|
||||
if (cache && cache[file] && cache[file].parent) {
|
||||
cache[file].parent.forEach((item)=>{
|
||||
this.judgeFileShouldResolved(item, shouldResolvedFiles);
|
||||
})
|
||||
cache[file].parent = [];
|
||||
}
|
||||
if (cache && cache[file] && cache[file].children) {
|
||||
cache[file].children.forEach((item)=>{
|
||||
this.judgeFileShouldResolved(item, shouldResolvedFiles);
|
||||
})
|
||||
cache[file].children = [];
|
||||
}
|
||||
}
|
||||
|
||||
private generateCollectionFile() {
|
||||
if (projectConfig.aceSuperVisualPath && fs.existsSync(projectConfig.aceSuperVisualPath)) {
|
||||
appComponentCollection.clear();
|
||||
@@ -246,6 +305,9 @@ export class ResultStates {
|
||||
private printDiagnostic(diagnostic: ts.Diagnostic): void {
|
||||
const message: string = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
||||
if (this.validateError(message)) {
|
||||
if (process.env.watchMode !== 'true' && !projectConfig.xtsMode) {
|
||||
updateErrorFileCache(diagnostic);
|
||||
}
|
||||
this.mErrorCount += 1;
|
||||
if (diagnostic.file) {
|
||||
const { line, character }: ts.LineAndCharacter =
|
||||
@@ -415,3 +477,45 @@ export class ResultStates {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
function updateErrorFileCache(diagnostic: ts.Diagnostic): void {
|
||||
if (diagnostic.file && cache[path.resolve(diagnostic.file.fileName)]) {
|
||||
cache[path.resolve(diagnostic.file.fileName)].error = true;
|
||||
}
|
||||
}
|
||||
|
||||
function filterInput(rootFileNames: string[]): string[] {
|
||||
return rootFileNames.filter((file: string) => {
|
||||
const needUpdate: NeedUpdateFlag = { flag: false };
|
||||
const alreadyCheckedFiles: Set<string> = new Set();
|
||||
checkNeedUpdateFiles(path.resolve(file), needUpdate, alreadyCheckedFiles);
|
||||
return needUpdate.flag;
|
||||
});
|
||||
}
|
||||
|
||||
function checkNeedUpdateFiles(file: string, needUpdate: NeedUpdateFlag, alreadyCheckedFiles: Set<string>): void {
|
||||
if (alreadyCheckedFiles.has(file)) {
|
||||
return;
|
||||
} else {
|
||||
alreadyCheckedFiles.add(file);
|
||||
}
|
||||
|
||||
if (needUpdate.flag) {
|
||||
return;
|
||||
}
|
||||
|
||||
const value: CacheFileName = cache[file];
|
||||
const mtimeMs: number = fs.statSync(file).mtimeMs;
|
||||
if (value) {
|
||||
if (value.error || value.mtimeMs !== mtimeMs) {
|
||||
needUpdate.flag = true;
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < value.children.length; ++i) {
|
||||
checkNeedUpdateFiles(value.children[i], needUpdate, alreadyCheckedFiles);
|
||||
}
|
||||
} else {
|
||||
cache[file] = { mtimeMs, children: [], parent: [], error: false };
|
||||
needUpdate.flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
+83
-43
@@ -38,7 +38,12 @@ import {
|
||||
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 {
|
||||
props,
|
||||
CacheFileName,
|
||||
cache,
|
||||
shouldResolvedFiles
|
||||
} from './compile_info';
|
||||
|
||||
function readDeaclareFiles(): string[] {
|
||||
const declarationsFileNames: string[] = [];
|
||||
@@ -112,54 +117,89 @@ export function createLanguageService(rootFileNames: string[]): ts.LanguageServi
|
||||
return ts.createLanguageService(servicesHost, ts.createDocumentRegistry());
|
||||
}
|
||||
|
||||
const resolvedModulesCache: Map<string, ts.ResolvedModuleFull[]> = new Map();
|
||||
|
||||
function resolveModuleNames(moduleNames: string[], containingFile: string): ts.ResolvedModuleFull[] {
|
||||
const resolvedModules: ts.ResolvedModuleFull[] = [];
|
||||
for (const moduleName of moduleNames) {
|
||||
const result = ts.resolveModuleName(moduleName, containingFile, compilerOptions, {
|
||||
fileExists(fileName: string): boolean {
|
||||
return ts.sys.fileExists(fileName);
|
||||
},
|
||||
readFile(fileName: string): string | undefined {
|
||||
return ts.sys.readFile(fileName);
|
||||
}
|
||||
});
|
||||
if (result.resolvedModule) {
|
||||
resolvedModules.push(result.resolvedModule);
|
||||
} else if (/^@(system|ohos)/i.test(moduleName.trim())) {
|
||||
const modulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ts');
|
||||
if (systemModules.includes(moduleName + '.d.ts') && ts.sys.fileExists(modulePath)) {
|
||||
resolvedModules.push(getResolveModule(modulePath, '.d.ts'));
|
||||
if (![...shouldResolvedFiles].length || shouldResolvedFiles.has(path.resolve(containingFile)) ||
|
||||
!resolvedModulesCache[path.resolve(containingFile)]) {
|
||||
for (const moduleName of moduleNames) {
|
||||
const result = ts.resolveModuleName(moduleName, containingFile, compilerOptions, {
|
||||
fileExists(fileName: string): boolean {
|
||||
return ts.sys.fileExists(fileName);
|
||||
},
|
||||
readFile(fileName: string): string | undefined {
|
||||
return ts.sys.readFile(fileName);
|
||||
}
|
||||
});
|
||||
if (result.resolvedModule) {
|
||||
resolvedModules.push(result.resolvedModule);
|
||||
} else if (/^@(system|ohos)/i.test(moduleName.trim())) {
|
||||
const modulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ts');
|
||||
if (systemModules.includes(moduleName + '.d.ts') && ts.sys.fileExists(modulePath)) {
|
||||
resolvedModules.push(getResolveModule(modulePath, '.d.ts'));
|
||||
} else {
|
||||
resolvedModules.push(null);
|
||||
}
|
||||
} else if (/\.ets$/.test(moduleName)) {
|
||||
const modulePath: string = path.resolve(path.dirname(containingFile), moduleName);
|
||||
if (ts.sys.fileExists(modulePath)) {
|
||||
resolvedModules.push(getResolveModule(modulePath, '.ets'));
|
||||
} else {
|
||||
resolvedModules.push(null);
|
||||
}
|
||||
} else if (/\.ts$/.test(moduleName)) {
|
||||
const modulePath: string = path.resolve(path.dirname(containingFile), moduleName);
|
||||
if (ts.sys.fileExists(modulePath)) {
|
||||
resolvedModules.push(getResolveModule(modulePath, '.ts'));
|
||||
} else {
|
||||
resolvedModules.push(null);
|
||||
}
|
||||
} else {
|
||||
resolvedModules.push(null);
|
||||
}
|
||||
} else if (/\.ets$/.test(moduleName)) {
|
||||
const modulePath: string = path.resolve(path.dirname(containingFile), moduleName);
|
||||
if (ts.sys.fileExists(modulePath)) {
|
||||
resolvedModules.push(getResolveModule(modulePath, '.ets'));
|
||||
} else {
|
||||
resolvedModules.push(null);
|
||||
}
|
||||
} else if (/\.ts$/.test(moduleName)) {
|
||||
const modulePath: string = path.resolve(path.dirname(containingFile), moduleName);
|
||||
if (ts.sys.fileExists(modulePath)) {
|
||||
resolvedModules.push(getResolveModule(modulePath, '.ts'));
|
||||
} else {
|
||||
resolvedModules.push(null);
|
||||
}
|
||||
} else {
|
||||
const modulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ts');
|
||||
const suffix: string = /\.js$/.test(moduleName) ? '' : '.js';
|
||||
const jsModulePath: string = path.resolve(__dirname, '../node_modules', moduleName + suffix);
|
||||
if (ts.sys.fileExists(modulePath)) {
|
||||
resolvedModules.push(getResolveModule(modulePath, '.d.ts'));
|
||||
} else if (ts.sys.fileExists(jsModulePath)) {
|
||||
resolvedModules.push(getResolveModule(modulePath, '.js'));
|
||||
} else {
|
||||
resolvedModules.push(null);
|
||||
const modulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ts');
|
||||
const suffix: string = /\.js$/.test(moduleName) ? '' : '.js';
|
||||
const jsModulePath: string = path.resolve(__dirname, '../node_modules', moduleName + suffix);
|
||||
if (ts.sys.fileExists(modulePath)) {
|
||||
resolvedModules.push(getResolveModule(modulePath, '.d.ts'));
|
||||
} else if (ts.sys.fileExists(jsModulePath)) {
|
||||
resolvedModules.push(getResolveModule(modulePath, '.js'));
|
||||
} else {
|
||||
resolvedModules.push(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!projectConfig.xtsMode) {
|
||||
createOrUpdateCache(resolvedModules, containingFile);
|
||||
}
|
||||
resolvedModulesCache[path.resolve(containingFile)] = resolvedModules;
|
||||
return resolvedModules;
|
||||
}
|
||||
return resolvedModules;
|
||||
return resolvedModulesCache[path.resolve(containingFile)];
|
||||
}
|
||||
|
||||
function createOrUpdateCache(resolvedModules: ts.ResolvedModuleFull[], containingFile: string): void {
|
||||
const children: string[] = [];
|
||||
const error: boolean = false;
|
||||
resolvedModules.forEach(moduleObj => {
|
||||
if (moduleObj && moduleObj.resolvedFileName && /(?<!\.d)\.(ets|ts)$/.test(moduleObj.resolvedFileName)) {
|
||||
const file: string = path.resolve(moduleObj.resolvedFileName);
|
||||
const mtimeMs: number = fs.statSync(file).mtimeMs;
|
||||
children.push(file);
|
||||
const value: CacheFileName = cache[file];
|
||||
if (value) {
|
||||
value.mtimeMs = mtimeMs;
|
||||
value.error = error;
|
||||
value.parent = value.parent || [];
|
||||
value.parent.push(path.resolve(containingFile));
|
||||
value.parent = [...new Set(value.parent)];
|
||||
} else {
|
||||
cache[file] = { mtimeMs, children: [], parent: [containingFile], error };
|
||||
}
|
||||
}
|
||||
});
|
||||
cache[path.resolve(containingFile)] = { mtimeMs: fs.statSync(containingFile).mtimeMs, children,
|
||||
parent: cache[path.resolve(containingFile)] && cache[path.resolve(containingFile)].parent ?
|
||||
cache[path.resolve(containingFile)].parent : [], error };
|
||||
}
|
||||
|
||||
export function createWatchCompilerHost(rootFileNames: string[],
|
||||
|
||||
@@ -130,7 +130,7 @@ function initConfig(config) {
|
||||
new ResultStates()
|
||||
]
|
||||
});
|
||||
if (!/ets_loader_ark$/.test(__dirname)) {
|
||||
if (!projectConfig.xtsMode) {
|
||||
config.cache = {
|
||||
type: "filesystem",
|
||||
cacheDirectory: path.resolve(projectConfig.cachePath, '.ets_cache')
|
||||
|
||||
Reference in New Issue
Block a user