Skip to content

Commit

Permalink
fix: use require to load CJS plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
bmish committed Oct 17, 2022
1 parent ce363e3 commit 0a8e579
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 107 deletions.
110 changes: 56 additions & 54 deletions lib/package-json.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { join, resolve, extname } from 'node:path';
import { join, resolve, extname, relative, dirname } from 'node:path';
import { existsSync, readFileSync, readdirSync } from 'node:fs';
import { importAbs } from './import.js';
import { createRequire } from 'node:module';
import type { Plugin } from './types.js';
import type { PackageJson } from 'type-fest';
import { fileURLToPath } from 'node:url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const require = createRequire(import.meta.url);

export function getPluginRoot(path: string) {
return join(process.cwd(), path);
Expand All @@ -23,66 +28,63 @@ function loadPackageJson(path: string): PackageJson {

export async function loadPlugin(path: string): Promise<Plugin> {
const pluginRoot = getPluginRoot(path);
const pluginPackageJson = loadPackageJson(path);

// Check for the entry point on the `exports` or `main` field in package.json.
let pluginEntryPoint;
const exports = pluginPackageJson.exports;
if (typeof exports === 'string') {
pluginEntryPoint = exports;
} else if (
typeof exports === 'object' &&
exports !== null &&
!Array.isArray(exports)
) {
// Check various properties on the `exports` object.
// https://nodejs.org/api/packages.html#conditional-exports
const propertiesToCheck: (keyof PackageJson.ExportConditions)[] = [
'.',
'node',
'import',
'require',
'default',
];
for (const prop of propertiesToCheck) {
// @ts-expect-error -- The union type for the object is causing trouble.
const value = exports[prop];
if (typeof value === 'string') {
pluginEntryPoint = value;
break;
try {
return require(relative(__dirname, pluginRoot)); // eslint-disable-line import/no-dynamic-require
} catch (error) {
console.log({ e: error });
// Check for the entry point on the `exports` or `main` field in package.json.
const pluginPackageJson = loadPackageJson(path);
let pluginEntryPoint;
const exports = pluginPackageJson.exports;
if (typeof exports === 'string') {
pluginEntryPoint = exports;
} else if (
typeof exports === 'object' &&
exports !== null &&
!Array.isArray(exports)
) {
// Check various properties on the `exports` object.
// https://nodejs.org/api/packages.html#conditional-exports
const propertiesToCheck: (keyof PackageJson.ExportConditions)[] = [
'.',
'node',
'import',
'require',
'default',
];
for (const prop of propertiesToCheck) {
// @ts-expect-error -- The union type for the object is causing trouble.
const value = exports[prop];
if (typeof value === 'string') {
pluginEntryPoint = value;
break;
}
}
}
} else if (typeof pluginPackageJson.main === 'string') {
pluginEntryPoint = pluginPackageJson.main;
}

if (!pluginEntryPoint) {
pluginEntryPoint = 'index.js'; // This is the default value for the `main` field: https://docs.npmjs.com/cli/v8/configuring-npm/package-json#main
}
if (!pluginEntryPoint) {
throw new Error('Unable to find plugin entry point.');
}

if (pluginEntryPoint.endsWith('/')) {
// The `main` field is allowed to specify a directory.
pluginEntryPoint = `${pluginEntryPoint}/index.js`;
}
const SUPPORTED_FILE_TYPES = ['.js', '.cjs', '.mjs'];
if (!SUPPORTED_FILE_TYPES.includes(extname(pluginEntryPoint))) {
throw new Error(
`Unsupported file type for plugin entry point. Current types supported: ${SUPPORTED_FILE_TYPES.join(
', '
)}. Entry point detected: ${pluginEntryPoint}`
);
}

const SUPPORTED_FILE_TYPES = ['.js', '.cjs', '.mjs'];
if (!SUPPORTED_FILE_TYPES.includes(extname(pluginEntryPoint))) {
throw new Error(
`Unsupported file type for plugin entry point. Current types supported: ${SUPPORTED_FILE_TYPES.join(
', '
)}. Entry point detected: ${pluginEntryPoint}`
);
}
const pluginEntryPointAbs = join(pluginRoot, pluginEntryPoint);
if (!existsSync(pluginEntryPointAbs)) {
throw new Error(
`Could not find entry point for ESLint plugin. Tried: ${pluginEntryPoint}`
);
}

const pluginEntryPointAbs = join(pluginRoot, pluginEntryPoint);
if (!existsSync(pluginEntryPointAbs)) {
throw new Error(
`Could not find entry point for ESLint plugin. Tried: ${pluginEntryPoint}`
);
const { default: plugin } = await importAbs(pluginEntryPointAbs);
return plugin;
}

const { default: plugin } = await importAbs(pluginEntryPointAbs);
return plugin;
}

export function getPluginPrefix(path: string): string {
Expand Down

0 comments on commit 0a8e579

Please sign in to comment.