Skip to content

Commit

Permalink
Use jiti.import + add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
webpro committed Oct 1, 2024
1 parent d9bb60c commit c07dfda
Show file tree
Hide file tree
Showing 12 changed files with 85 additions and 27 deletions.

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

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

Empty file.
4 changes: 4 additions & 0 deletions packages/knip/fixtures/load-cjs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "@fixtures/load-cjs",
"type": "commonjs"
}
22 changes: 22 additions & 0 deletions packages/knip/fixtures/load-esm-ts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SyntaxError: Cannot use 'import.meta' outside a module

import.meta;
import.meta.resolve;
import.meta.url;

// SyntaxError: Unexpected identifier 'Promise'

Promise;

// TypeError: Reflect.metadata is not a function

function meow(target: unknown, _: unknown) {}

@meow
export class Cat {
constructor() {}
}

// SyntaxError: await is only valid in async functions and the top level bodies of modules

await Promise.resolve('TLA');
4 changes: 4 additions & 0 deletions packages/knip/fixtures/load-esm-ts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "@fixtures/load-esm-ts",
"type": "module"
}
7 changes: 7 additions & 0 deletions packages/knip/fixtures/load-esm-ts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"module": "esnext",
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
18 changes: 18 additions & 0 deletions packages/knip/fixtures/load-esm/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// The CJS build of Vite's Node API is deprecated. See https://vitejs.dev/guide/troubleshooting.html#vite-cjs-node-api-deprecated for more details.

// SyntaxError: Cannot use 'import.meta' outside a module

import.meta;
import.meta.resolve;
import.meta.url;

// SyntaxError: await is only valid in async functions and the top level bodies of modules

// SyntaxError: missing ) after argument list

// SyntaxError: Unexpected identifier 'Promise'
Promise;

// Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined in [...]/node_modules/estree-walker/package.json

await Promise.resolve('TLA');
4 changes: 4 additions & 0 deletions packages/knip/fixtures/load-esm/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "@fixtures/load-esm",
"type": "module"
}
18 changes: 2 additions & 16 deletions packages/knip/src/util/fs.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { readFileSync, statSync } from 'node:fs';
import { statSync } from 'node:fs';
import { readFile } from 'node:fs/promises';
import yaml from 'js-yaml';
import { parse as parseTOML } from 'smol-toml';
import stripJsonComments from 'strip-json-comments';
import { timerify } from './Performance.js';
import { LoaderError } from './errors.js';
import { dirname, join } from './path.js';
import { join } from './path.js';

export const isDirectory = (filePath: string) => {
try {
Expand Down Expand Up @@ -64,18 +64,4 @@ export const parseYAML = (contents: string) => {
return yaml.load(contents);
};

export function isTypeModule(path: string) {
while (path && path !== '.' && path !== '/') {
path = dirname(path);
try {
const pkg = readFileSync(join(path, 'package.json'), 'utf-8');
try {
return JSON.parse(pkg).type === 'module';
} catch {}
break;
} catch {}
}
return false;
}

export const _loadJSON = timerify(loadJSON);
10 changes: 1 addition & 9 deletions packages/knip/src/util/loader.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { pathToFileURL } from 'node:url';
import { timerify } from './Performance.js';
import { LoaderError } from './errors.js';
import { loadFile, loadJSON, loadTOML, loadYAML, parseJSON, parseYAML } from './fs.js';
import { isTypeModule } from './fs.js';
import { jiti } from './jiti.js';
import { extname, isInternal } from './path.js';

Expand Down Expand Up @@ -39,13 +37,7 @@ const load = async (filePath: string) => {
return await loadTOML(filePath);
}

if (ext === '.mjs' || (ext === '.js' && isTypeModule(filePath))) {
const fileUrl = pathToFileURL(filePath);
const imported = await import(fileUrl.href);
return imported.default ?? imported;
}

return await jiti(filePath);
return await jiti.import(filePath);
} catch (error) {
throw new LoaderError(`Error loading ${filePath}`, { cause: error });
}
Expand Down
19 changes: 19 additions & 0 deletions packages/knip/test/util/load.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { test } from 'bun:test';
import assert from 'node:assert/strict';
import { _load as load } from '../../src/util/loader.js';
import { join, resolve } from '../../src/util/path.js';

test('Should load modules (CommonJS)', async () => {
const cwd = resolve('fixtures/load-cjs');
await assert.doesNotReject(load(join(cwd, 'index.js')));
});

test('Should load modules (ESM)', async () => {
const cwd = resolve('fixtures/load-esm');
await assert.doesNotReject(load(join(cwd, 'index.js')));
});

test('Should load modules (ESM/TS)', async () => {
const cwd = resolve('fixtures/load-esm-ts');
await assert.doesNotReject(load(join(cwd, 'index.ts')));
});

0 comments on commit c07dfda

Please sign in to comment.