From 3070c3c1c7dc8acc053981c17ee0c7f5637c5ea7 Mon Sep 17 00:00:00 2001 From: Akhmad Salafudin Date: Tue, 14 Nov 2023 23:45:14 +0700 Subject: [PATCH] feat: custom extension for resolveFullPath and add regex for minified js (#203) --- src/helpers/replacers.ts | 16 ++++++++++++---- src/index.ts | 10 ++++++++-- src/interfaces.ts | 1 + src/utils/import-path-resolver.ts | 21 +++++++++++++-------- 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/helpers/replacers.ts b/src/helpers/replacers.ts index 73bb633..05aec83 100644 --- a/src/helpers/replacers.ts +++ b/src/helpers/replacers.ts @@ -128,11 +128,18 @@ export async function importReplacers( export async function replaceAlias( config: IConfig, file: string, - resolveFullPath?: boolean + resolveFullPath?: boolean, + resolveFullExtension?: string ): Promise { config.output.debug('Starting to replace file:', file); const code = await fsp.readFile(file, 'utf8'); - const tempCode = replaceAliasString(config, file, code, resolveFullPath); + const tempCode = replaceAliasString( + config, + file, + code, + resolveFullPath, + resolveFullExtension + ); if (code !== tempCode) { config.output.debug('replaced file with changes:', file); @@ -155,7 +162,8 @@ export function replaceAliasString( config: IConfig, file: string, code: string, - resolveFullPath?: boolean + resolveFullPath?: boolean, + resolveFullExtension?: string ): string { config.replacers.forEach((replacer) => { code = replaceSourceImportPaths(code, file, (orig) => @@ -170,7 +178,7 @@ export function replaceAliasString( // Fully resolve all import paths (not just aliased ones) // *after* the aliases are resolved if (resolveFullPath) { - code = resolveFullImportPaths(code, file); + code = resolveFullImportPaths(code, file, resolveFullExtension); } return code; diff --git a/src/index.ts b/src/index.ts index eeaadc3..5366416 100644 --- a/src/index.ts +++ b/src/index.ts @@ -60,7 +60,12 @@ export async function replaceTscAliasPaths( const replaceList = await Promise.all( files.map((file) => OpenFilesLimit(() => - replaceAlias(config, file, options?.resolveFullPaths) + replaceAlias( + config, + file, + options?.resolveFullPaths, + options?.resolveFullExtension + ) ) ) ); @@ -116,7 +121,8 @@ export async function prepareSingleFileReplaceTscAliasPaths( config, filePath, fileContents, - options?.resolveFullPaths + options?.resolveFullPaths, + options?.resolveFullExtension ); }; } diff --git a/src/interfaces.ts b/src/interfaces.ts index 10b3c08..781156c 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -61,6 +61,7 @@ export interface ReplaceTscAliasPathsOptions { verbose?: boolean; debug?: boolean; resolveFullPaths?: boolean; + resolveFullExtension?: '.js' | '.mjs' | '.cjs'; replacers?: string[]; output?: IOutput; aliasTrie?: TrieNode; diff --git a/src/utils/import-path-resolver.ts b/src/utils/import-path-resolver.ts index 7746f4c..6e7fce3 100644 --- a/src/utils/import-path-resolver.ts +++ b/src/utils/import-path-resolver.ts @@ -39,13 +39,17 @@ const importString = `(?:${anyQuote}${pathStringContent}${anyQuote})`; // so that they can be strung together in one big pattern. const funcStyle = `(?:\\b(?:import|require)\\s*\\(\\s*(\\/\\*.*\\*\\/\\s*)?${importString}\\s*\\))`; const globalStyle = `(?:\\bimport\\s+${importString})`; +const globalMinimizedStyle = `(?:\\bimport${importString})`; const fromStyle = `(?:\\bfrom\\s+${importString})`; +const fromMinimizedStyle = `(?:\\bfrom${importString})`; const moduleStyle = `(?:\\bmodule\\s+${importString})`; const importRegexString = `(?:${[ funcStyle, globalStyle, + globalMinimizedStyle, fromStyle, + fromMinimizedStyle, moduleStyle ].join(`|`)})`; @@ -73,7 +77,7 @@ class ImportPathResolver { * and resolve them to full filenames (including the .js extension). * If no matching file is found for a path, leave it alone. */ - resolveFullImportPaths() { + resolveFullImportPaths(ext = '.js') { this.replaceSourceImportPaths((importStatement) => { // Find substring that is just quotes const importPathMatch = importStatement.match(newStringRegex()); @@ -81,7 +85,7 @@ class ImportPathResolver { return importStatement; } const { path, pathWithQuotes } = importPathMatch.groups; - const fullPath = normalizePath(this.resolveFullPath(path)); + const fullPath = normalizePath(this.resolveFullPath(path, ext)); return importStatement.replace( pathWithQuotes, pathWithQuotes.replace(path, fullPath) @@ -94,19 +98,19 @@ class ImportPathResolver { * Given an import path, resolve the full path (including extension). * If no corresponding file can be found, return the original path. */ - private resolveFullPath(importPath: string) { - if (importPath.match(/\.js$/)) { + private resolveFullPath(importPath: string, ext = '.js') { + if (importPath.match(new RegExp(`\${ext}$`))) { return importPath; } // Try adding the extension (if not obviously a directory) if (!importPath.match(/[/\\]$/)) { - const asFilePath = `${importPath}.js`; + const asFilePath = `${importPath}${ext}`; if (existsSync(resolve(this.sourceDir, asFilePath))) { return asFilePath; } } // Assume the path is a folder; try adding index.js - let asFilePath = join(importPath, 'index.js'); + let asFilePath = join(importPath, 'index' + ext); if ( (importPath.startsWith('./') || importPath === '.') && !asFilePath.startsWith('./') @@ -128,8 +132,9 @@ class ImportPathResolver { return new RegExp(importRegexString, flags); } - static resolveFullImportPaths(code: string, path: string) { - return new ImportPathResolver(code, path).resolveFullImportPaths().source; + static resolveFullImportPaths(code: string, path: string, ext = '.js') { + return new ImportPathResolver(code, path).resolveFullImportPaths(ext) + .source; } static replaceSourceImportPaths(