From 8da8ca88be10019a31e2e8016185cb915e342f14 Mon Sep 17 00:00:00 2001 From: Max Metral Date: Tue, 12 Dec 2023 12:28:02 -0500 Subject: [PATCH] feat(esm): try and be a bit smarter about ESM generation --- package.json | 2 +- src/bin/cli.ts | 2 +- src/passthrough.ts | 27 +++++++++++++++++++-------- src/resolver.ts | 6 +++++- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 93d8e76..05a8938 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "coconfig", - "version": "1.1.0", + "version": "1.2.0", "description": "Centralize your per-package rc, dotfile and config files into one extensible config file", "main": "build/index.js", "types": "build/index.d.ts", diff --git a/src/bin/cli.ts b/src/bin/cli.ts index 20d1c70..f198693 100755 --- a/src/bin/cli.ts +++ b/src/bin/cli.ts @@ -21,7 +21,7 @@ async function run() { const pkgInfo = readPkgUp.sync({ cwd: argv.cwd, normalize: argv.normalize }); assert(pkgInfo, 'Cannot find package.json. Pass cwd option that points to a directory with a package.json'); const { packageJson, path } = pkgInfo; - const pkgValue = packageJson.config?.coconfig; + const pkgValue = packageJson.config?.coconfig as string | undefined; const { coconfigPath, config } = await resolveConfig(path, pkgValue); const coconfigEnv: CoConfigEnvironment = { diff --git a/src/passthrough.ts b/src/passthrough.ts index 6885230..b99faa4 100644 --- a/src/passthrough.ts +++ b/src/passthrough.ts @@ -30,13 +30,13 @@ function getModulePath(configRef: string) { return configRef; } -export function getFile( - env: CoConfigEnvironment, - key: string, - filename: string, -) { +export function getFile(env: CoConfigEnvironment, key: string, filename: string) { const configRef = configReference(env.coconfigPath, env.packagePath); - const modulePath = getModulePath(configRef); + const isModule = env.packageJson?.type === 'module' || /.m[jt]s/.test(path.extname(filename)); + + const modulePath = isModule ? configRef : getModulePath(configRef); + + const isTs = /\.[mc]?ts/.test(path.extname(filename)); const commonCode = ` const configItem = configModule.default || configModule.config || configModule; @@ -44,8 +44,7 @@ const { configuration } = configItem && configItem['${key}']; const resolved = typeof configuration === 'function' ? configuration() : configuration; `; - if (path.extname(filename) === '.ts') { - // Target is Typescript + if (isModule && isTs) { return `${header} import cjs from '${modulePath}'; import * as esmToCjs from '${modulePath}'; @@ -56,6 +55,18 @@ ${commonCode} // eslint-disable-next-line import/no-default-export export default resolved;\n`; } + + if (isModule) { + return `${header} +import cjs from '${modulePath}'; +import * as esmToCjs from '${modulePath}'; + +const configModule = cjs || esmToCjs; +${commonCode} +// eslint-disable-next-line import/no-default-export +export default resolved;\n`; + } + if (path.extname(env.coconfigPath) === '.ts') { // Target is JS, source is typescript (requires ts-node) return `${header} diff --git a/src/resolver.ts b/src/resolver.ts index 8ba020f..52eb8df 100644 --- a/src/resolver.ts +++ b/src/resolver.ts @@ -21,6 +21,10 @@ function getExport(module: Record) { return module; } +/** + * Try and dynamically load a coconfig file in a variety of + * environments - esm, cjs, ts, js, cjs esm, etc. + */ async function load(coconfigPath: string): Promise<{ coconfigPath: string; config: CoConfigFile }> { try { if (path.extname(coconfigPath) === '.ts') { @@ -45,7 +49,7 @@ async function load(coconfigPath: string): Promise<{ coconfigPath: string; confi } } -export async function resolveConfig(pkgPath: string, pkgValue?: any) { +export async function resolveConfig(pkgPath: string, pkgValue?: string) { if (typeof pkgValue === 'string') { if (pkgValue.startsWith('.')) { return load(path.resolve(path.dirname(pkgPath), pkgValue));