From 5f7282785852c808d5e9225c0d88d8631b4483b8 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 11 Dec 2024 19:37:34 +0100 Subject: [PATCH 1/4] feat(defineEnv): support resolving paths --- build.config.ts | 1 + package.json | 1 + pnpm-lock.yaml | 3 +++ src/env.ts | 31 ++++++++++++++++++++++++++++++- src/types.ts | 18 ++++++++++++++++++ test/env.test.ts | 21 +++++++++++++++++++++ 6 files changed, 74 insertions(+), 1 deletion(-) diff --git a/build.config.ts b/build.config.ts index 987732fe..b889e6c5 100644 --- a/build.config.ts +++ b/build.config.ts @@ -4,6 +4,7 @@ export default defineBuildConfig({ declaration: true, rollup: { emitCJS: true, + cjsBridge: true, }, entries: [ "src/index", diff --git a/package.json b/package.json index 5cb1e1f6..c54bde2a 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ }, "dependencies": { "defu": "^6.1.4", + "mlly": "^1.7.3", "ohash": "^1.1.4", "pathe": "^1.1.2", "ufo": "^1.5.4" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8b1691d8..c921bc41 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: defu: specifier: ^6.1.4 version: 6.1.4 + mlly: + specifier: ^1.7.3 + version: 1.7.3 ohash: specifier: ^1.1.4 version: 1.1.4 diff --git a/src/env.ts b/src/env.ts index 58dbe4d3..4ab15fba 100644 --- a/src/env.ts +++ b/src/env.ts @@ -1,5 +1,5 @@ +import { resolvePathSync, type ResolveOptions } from "mlly"; import type { Preset, Environment, CreateEnvOptions } from "./types"; - import nodeCompatPreset from "./presets/nodeless"; /** @@ -32,6 +32,35 @@ export function defineEnv(opts: CreateEnvOptions = {}): { const resolvedEnv = env(...presets); + if (opts.resolve) { + const resolveOpts: ResolveOptions = { + url: [ + ...(opts.resolve === true ? [] : opts.resolve.paths || []), + __dirname, // unenv + ], + }; + const _resolve = (id: string) => resolvePathSync(id, resolveOpts); + + // Resolve aliases + for (const alias in resolvedEnv.alias) { + resolvedEnv.alias[alias] = _resolve(resolvedEnv.alias[alias]); + } + // Resolve polyfills + for (let i = 0; i < resolvedEnv.polyfill.length; i++) { + resolvedEnv.polyfill[i] = _resolve(resolvedEnv.polyfill[i]); + } + // Resolve injects + for (const global in resolvedEnv.inject) { + const inject = resolvedEnv.inject[global]; + if (Array.isArray(inject)) { + const [id, ...path] = inject; + resolvedEnv.inject[global] = [_resolve(id), ...path]; + } else { + resolvedEnv.inject[global] = _resolve(inject); + } + } + } + return { env: resolvedEnv }; } diff --git a/src/types.ts b/src/types.ts index c0907087..1232bae2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,6 +1,8 @@ export interface CreateEnvOptions { /** * Enable Node.js compatibility (nodeless) preset. + * + * Default: `false` */ nodeCompat?: boolean; @@ -13,6 +15,22 @@ export interface CreateEnvOptions { * Additional overrides. */ overrides?: Partial; + + /** + * Resolve paths in the environment to absolute paths. + * + * Default: `false` + */ + resolve?: boolean | EnvResolveOptions; +} + +export interface EnvResolveOptions { + /** + * Paths to resolve imports from. + * + * Always unenv path is appended. + */ + paths?: (string | URL)[]; } export interface Environment { diff --git a/test/env.test.ts b/test/env.test.ts index 7ac805e3..f6872c0f 100644 --- a/test/env.test.ts +++ b/test/env.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from "vitest"; import { defineEnv } from "../src"; import { builtinModules } from "node:module"; +import { existsSync } from "node:fs"; describe("defineEnv", () => { it("defaults", () => { @@ -29,4 +30,24 @@ describe("defineEnv", () => { } }); }); + + describe("resolvePath", () => { + it("resolves all nodeCompat paths", () => { + const { env } = defineEnv({ nodeCompat: true, resolve: true }); + for (const path of Object.values(env.alias)) { + if (path.startsWith("node:")) { + continue; // recursive + } + expect(existsSync(path)).toBe(true); + } + for (const path of env.polyfill) { + expect(existsSync(path)).toBe(true); + } + for (const inject of Object.values(env.inject)) { + expect(existsSync(Array.isArray(inject) ? inject[0] : inject)).toBe( + true, + ); + } + }); + }); }); From f86f05ee5e8fe2af2e6739265edbfcf635f68512 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 11 Dec 2024 19:41:33 +0100 Subject: [PATCH 2/4] ci: build before test --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff4ddb04..529eee87 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,10 +26,10 @@ jobs: - run: pnpm install - run: pnpm lint - run: pnpm test:types + - run: pnpm build - run: pnpm vitest - run: pnpm test:node - run: pnpm test:workerd - - run: pnpm build - name: nightly release if: | github.event_name == 'push' && From 63e4fe598c7b10e70038b70814c5ce93a58cbc83 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Thu, 12 Dec 2024 16:09:04 +0100 Subject: [PATCH 3/4] incl preset paths --- src/env.ts | 3 +++ src/types.ts | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/env.ts b/src/env.ts index 029ac033..b20895a9 100644 --- a/src/env.ts +++ b/src/env.ts @@ -38,6 +38,9 @@ export function defineEnv(opts: CreateEnvOptions = {}): { url: [ ...(opts.resolve === true ? [] : opts.resolve.paths || []), __dirname, // unenv + ...(presets + .map((preset) => preset.meta?.url) + .filter(Boolean) as string[]), ], }; const _resolve = (id: string) => resolvePathSync(id, resolveOpts); diff --git a/src/types.ts b/src/types.ts index 570f9a90..dfcfe671 100644 --- a/src/types.ts +++ b/src/types.ts @@ -53,9 +53,9 @@ export interface Preset { readonly version?: string; /** - * Path to preset directory usable for absolute path imports + * Path or URL to preset entry (used for resolving absolute paths). */ - readonly path?: string; + readonly url?: string | URL; }; alias?: Environment["alias"]; From cb641d19c52fe1fb588c01ad4311757a96cfd82c Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Thu, 12 Dec 2024 16:11:30 +0100 Subject: [PATCH 4/4] update paths --- src/env.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/env.ts b/src/env.ts index b20895a9..915a7a88 100644 --- a/src/env.ts +++ b/src/env.ts @@ -34,14 +34,15 @@ export function defineEnv(opts: CreateEnvOptions = {}): { const resolvedEnv = env(...presets); if (opts.resolve) { + const resolvePaths: (string | URL)[] = [ + ...(opts.resolve === true ? [] : opts.resolve.paths || []), + ...(presets + .map((preset) => preset.meta?.url) + .filter(Boolean) as string[]), + __filename, // unenv + ]; const resolveOpts: ResolveOptions = { - url: [ - ...(opts.resolve === true ? [] : opts.resolve.paths || []), - __dirname, // unenv - ...(presets - .map((preset) => preset.meta?.url) - .filter(Boolean) as string[]), - ], + url: resolvePaths, }; const _resolve = (id: string) => resolvePathSync(id, resolveOpts);