Skip to content

Commit

Permalink
fix: enhanced module loading
Browse files Browse the repository at this point in the history
  • Loading branch information
tada5hi committed Mar 10, 2023
1 parent cea0141 commit b7c99c6
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 100 deletions.
3 changes: 2 additions & 1 deletion src/loader/built-in/json/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
*/

import fs from 'node:fs';
import { buildFilePath, handleException } from '../../../utils';
import { buildFilePath } from '../../../locator';
import { handleException } from '../../../utils';
import type { Loader } from '../../type';

export class JSONLoader implements Loader {
Expand Down
147 changes: 81 additions & 66 deletions src/loader/built-in/module/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,16 @@ import type { JITI } from 'jiti';
import createJITI from 'jiti';
import { pathToFileURL } from 'node:url';
import type { LocatorInfo } from '../../../locator';
import { pathToLocatorInfo } from '../../../locator';
import {
buildFilePath, buildFilePathWithoutExtension, handleException, hasStringProperty, isObject,
buildFilePath,
buildFilePathWithoutExtension,
isLocatorInfo,
pathToLocatorInfo,
} from '../../../locator';
import {
handleException,
hasStringProperty, isFilePath,
isObject,
} from '../../../utils';
import type { Loader } from '../../type';
import type { ScriptFileLoadOptions } from './type';
Expand Down Expand Up @@ -65,60 +72,50 @@ export class ModuleLoader implements Loader {
data: LocatorInfo | string,
options?: ScriptFileLoadOptions,
) : Promise<unknown> {
const locatorInfo = this.buildLocatorInfo(data);

options = options || {};

let filePath : string;
if (options.withExtension) {
filePath = buildFilePath(locatorInfo);
} else {
filePath = buildFilePathWithoutExtension(locatorInfo);
}

if (options.withFilePrefix) {
filePath = pathToFileURL(filePath).href;
}
const [name, locatorInfo] = this.build(data, options);

try {
// segmentation fault
// issue: https://github.com/nodejs/node/issues/35889
if (isJestRuntimeEnvironment()) {
// eslint-disable-next-line global-require,import/no-dynamic-require
return require(filePath);
return require(name);
}

return await import(filePath);
return await import(name);
} catch (e) {
/* istanbul ignore next */
if (
isObject(e) &&
hasStringProperty(e, 'code')
) {
if (
!options.withExtension &&
(
e.code === 'ERR_MODULE_NOT_FOUND' ||
e.code === 'MODULE_NOT_FOUND'
)
) {
return this.load(locatorInfo, {
...options,
withExtension: true,
});
}

if (
!options.withFilePrefix &&
(
e.code === 'ERR_UNSUPPORTED_ESM_URL_SCHEME' ||
e.code === 'UNSUPPORTED_ESM_URL_SCHEME'
)
) {
return this.load(locatorInfo, {
...options,
withFilePrefix: true,
});
if (locatorInfo) {
if (
!options.withExtension &&
(
e.code === 'ERR_MODULE_NOT_FOUND' ||
e.code === 'MODULE_NOT_FOUND'
)
) {
return this.load(locatorInfo, {
...options,
withExtension: true,
});
}

if (
!options.withFilePrefix &&
(
e.code === 'ERR_UNSUPPORTED_ESM_URL_SCHEME' ||
e.code === 'UNSUPPORTED_ESM_URL_SCHEME'
)
) {
return this.load(locatorInfo, {
...options,
withFilePrefix: true,
});
}
}

throw new BaseError({
Expand All @@ -137,37 +134,31 @@ export class ModuleLoader implements Loader {
data: LocatorInfo | string,
options?: ScriptFileLoadOptions,
) : unknown {
const locatorInfo = this.buildLocatorInfo(data);

options = options || {};

let filePath : string;
if (options.withExtension) {
filePath = buildFilePath(locatorInfo);
} else {
filePath = buildFilePathWithoutExtension(locatorInfo);
}
const [name, locatorInfo] = this.build(data, options);

try {
// eslint-disable-next-line global-require,import/no-dynamic-require
return require(filePath);
return require(name);
} catch (e) {
/* istanbul ignore next */
if (
isObject(e) &&
hasStringProperty(e, 'code')
) {
if (
!options.withExtension &&
(
e.code === 'ERR_MODULE_NOT_FOUND' ||
e.code === 'MODULE_NOT_FOUND'
)
) {
return this.loadSync(locatorInfo, {
...options,
withExtension: true,
});
if (locatorInfo) {
if (
!options.withExtension &&
(
e.code === 'ERR_MODULE_NOT_FOUND' ||
e.code === 'MODULE_NOT_FOUND'
)
) {
return this.loadSync(locatorInfo, {
...options,
withExtension: true,
});
}
}

throw new BaseError({
Expand All @@ -181,11 +172,35 @@ export class ModuleLoader implements Loader {
}
}

private buildLocatorInfo(input: LocatorInfo | string) : LocatorInfo {
if (typeof input === 'string') {
return pathToLocatorInfo(input);
private build(
data: LocatorInfo | string,
options: ScriptFileLoadOptions,
) : [string, LocatorInfo | undefined] {
let name : string;
let locatorInfo : LocatorInfo | undefined;

options = options || {};

if (isLocatorInfo(data) || isFilePath(data)) {
if (typeof data === 'string') {
locatorInfo = pathToLocatorInfo(data);
} else {
locatorInfo = data;
}

if (options.withExtension) {
name = buildFilePath(locatorInfo);
} else {
name = buildFilePathWithoutExtension(locatorInfo);
}

if (options.withFilePrefix) {
name = pathToFileURL(name).href;
}
} else {
name = data;
}

return input;
return [name, locatorInfo];
}
}
2 changes: 1 addition & 1 deletion src/loader/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
* view the LICENSE file that was distributed with this source code.
*/

import { buildFilePath } from '../locator';
import type { LocatorInfo } from '../locator';
import { buildFilePath } from '../utils';
import { useLoader } from './singleton';
import type { Loader, Rule } from './type';

Expand Down
4 changes: 2 additions & 2 deletions src/loader/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
*/

import path from 'node:path';
import { isFilePath, pathToLocatorInfo } from '../locator';
import { buildFilePath } from '../utils';
import { buildFilePath, pathToLocatorInfo } from '../locator';
import { isFilePath } from '../utils';
import { JSONLoader, ModuleLoader } from './built-in';
import { LoaderId } from './constants';
import type { Loader, Rule } from './type';
Expand Down
40 changes: 34 additions & 6 deletions src/locator/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
*/

import path from 'node:path';
import { isObject, toArray } from '../utils';
import type { LocatorInfo, LocatorOptions } from './type';
import { toArray } from '../utils';

export function buildLocatorOptions(options?: Partial<LocatorOptions>) : LocatorOptions {
options = options || {};
Expand All @@ -23,11 +23,6 @@ export function buildLocatorOptions(options?: Partial<LocatorOptions>) : Locator
return options as LocatorOptions;
}

export function isFilePath(input: string) {
const info = path.parse(input);
return info.ext !== '';
}

export function pathToLocatorInfo(
input: string,
skipResolve?: boolean,
Expand All @@ -47,3 +42,36 @@ export function pathToLocatorInfo(
extension: info.ext,
};
}

export function isLocatorInfo(
input: unknown,
) : input is LocatorInfo {
return isObject(input) &&
typeof input.path === 'string' &&
typeof input.name === 'string' &&
typeof input.extension === 'string';
}

export function buildFilePath(input: LocatorInfo | string) {
if (typeof input === 'string') {
return input;
}

if (input.extension) {
return path.join(input.path, input.name) + input.extension;
}

return path.join(input.path, input.name);
}

export function buildFilePathWithoutExtension(input: LocatorInfo | string) {
let info: LocatorInfo;

if (typeof input === 'string') {
info = pathToLocatorInfo(input);
} else {
info = input;
}

return path.join(info.path, info.name);
}
27 changes: 3 additions & 24 deletions src/utils/file-path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,8 @@
* view the LICENSE file that was distributed with this source code.
*/
import path from 'node:path';
import type { LocatorInfo } from '../locator';
import { pathToLocatorInfo } from '../locator';

export function buildFilePath(input: LocatorInfo | string) {
if (typeof input === 'string') {
return input;
}

if (input.extension) {
return path.join(input.path, input.name) + input.extension;
}

return path.join(input.path, input.name);
}

export function buildFilePathWithoutExtension(input: LocatorInfo | string) {
let info: LocatorInfo;

if (typeof input === 'string') {
info = pathToLocatorInfo(input);
} else {
info = input;
}

return path.join(info.path, info.name);
export function isFilePath(input: string) {
const extension = path.extname(input);
return extension && extension !== '';
}

0 comments on commit b7c99c6

Please sign in to comment.