Skip to content

Commit

Permalink
feat: enable just in time compilation/transpiling for esm & ts files
Browse files Browse the repository at this point in the history
  • Loading branch information
tada5hi committed Jan 30, 2023
1 parent 249da6a commit 732bb4b
Show file tree
Hide file tree
Showing 22 changed files with 579 additions and 361 deletions.
52 changes: 40 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@
"typescript": "^4.9.4"
},
"dependencies": {
"ebec": "^0.1.0",
"glob": "^8.1.0"
"ebec": "^0.2.1",
"glob": "^8.1.0",
"jiti": "^1.16.2"
},
"config": {
"commitizen": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
*/

export * from './script';
export * from './json';
export * from './json/module';
8 changes: 8 additions & 0 deletions src/loader/built-in/json/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* Copyright (c) 2023.
* Author Peter Placzek (tada5hi)
* For the full copyright and license information,
* view the LICENSE file that was distributed with this source code.
*/

export * from './module';
36 changes: 36 additions & 0 deletions src/loader/built-in/json/module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2022-2023.
* Author Peter Placzek (tada5hi)
* For the full copyright and license information,
* view the LICENSE file that was distributed with this source code.
*/

import fs from 'node:fs';
import { LocatorInfo } from '../../../locator';
import { handleFileLoadError } from '../../../utils';
import { Loader } from '../../type';
import { buildLoaderFilePath } from '../../utils';

export class JSONLoader implements Loader {
async execute(input: LocatorInfo) {
const filePath = buildLoaderFilePath(input, true);

try {
const file = await fs.promises.readFile(filePath);
return JSON.parse(file.toString('utf-8'));
} catch (e) {
return handleFileLoadError(e);
}
}

executeSync(input: LocatorInfo) {
const filePath = buildLoaderFilePath(input, true);

try {
const file = fs.readFileSync(filePath);
return JSON.parse(file.toString('utf-8'));
} catch (e) {
return handleFileLoadError(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* view the LICENSE file that was distributed with this source code.
*/

export * from './async';
export * from './sync';
export * from './module';
export * from './type';
export * from './utils';
200 changes: 200 additions & 0 deletions src/loader/built-in/script/module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
/*
* Copyright (c) 2023.
* Author Peter Placzek (tada5hi)
* For the full copyright and license information,
* view the LICENSE file that was distributed with this source code.
*/

import { BaseError } from 'ebec';
import type { JITI } from 'jiti';
import createJITI from 'jiti';
import { pathToFileURL } from 'node:url';
import { LocatorInfo, pathToLocatorInfo } from '../../../locator';
import { handleFileLoadError, hasStringProperty, isObject } from '../../../utils';
import { Loader } from '../../type';
import { buildLoaderFilePath } from '../../utils';
import { ScriptFileLoadOptions } from './type';

export class ScriptLoader implements Loader {
protected jiti : JITI;

constructor() {
/*
const loaderMap : Record<string, ESLoader> = {
'.mjs': 'js',
'.js': 'js',
'.jsx': 'jsx',
'.ts': 'ts',
'.tsx': 'tsx',
};
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
this.jiti = createJITI(undefined, {
esmResolve: true,
/*
transform: (options) => {
let loader : ESLoader = 'ts';
if (options.filename) {
const info = pathToLocatorInfo(options.filename, true);
if (loaderMap[info.extension]) {
loader = loaderMap[info.extension] as ESLoader;
}
}
return transformSync(options.source, {
target: 'ES2020',
jsx: 'transform',
format: 'cjs',
loader,
});
},
*/
});
}

async execute(info: LocatorInfo) {
const filePath = buildLoaderFilePath(info);

let output : any;

try {
output = await this.load(info);
} catch (e) {
output = this.jiti(filePath);
}

return output;
}

executeSync(info: LocatorInfo) {
const filePath = buildLoaderFilePath(info);

let output : any;

try {
output = this.loadSync(info);
} catch (e) {
output = this.jiti(filePath);
}

return output;
}

// ---------------------------------------------------------------------------

async load(
data: LocatorInfo | string,
options?: ScriptFileLoadOptions,
) : Promise<unknown> {
let locatorInfo : LocatorInfo;

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

options = options || {};

let filePath = buildLoaderFilePath(locatorInfo, options.withExtension);
if (options.withFilePrefix) {
filePath = pathToFileURL(filePath).href;
}

try {
return await import(filePath);
} 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,
});
}

throw new BaseError({
code: e.code,
message: hasStringProperty(e, 'message') ? e.message : undefined,
stack: hasStringProperty(e, 'stack') ? e.stack : undefined,
});
}

/* istanbul ignore next */
return handleFileLoadError(e);
}
}

loadSync(
data: LocatorInfo | string,
options?: ScriptFileLoadOptions,
) : unknown {
let locatorInfo : LocatorInfo;

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

options = options || {};

const filePath = buildLoaderFilePath(locatorInfo, options.withExtension);

try {
// eslint-disable-next-line global-require,import/no-dynamic-require
return require(filePath);
} 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,
});
}

throw new BaseError({
code: e.code,
message: hasStringProperty(e, 'message') ? e.message : undefined,
stack: hasStringProperty(e, 'stack') ? e.stack : undefined,
});
}

return handleFileLoadError(e);
}
}
}
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 732bb4b

Please sign in to comment.