Skip to content

Commit

Permalink
feat(defineEnv): support resolving paths (#373)
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 authored Dec 12, 2024
1 parent ec0747a commit af71c96
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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' &&
Expand Down
1 change: 1 addition & 0 deletions build.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export default defineBuildConfig({
declaration: true,
rollup: {
emitCJS: true,
cjsBridge: true,
},
entries: [
"src/index",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

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

35 changes: 34 additions & 1 deletion src/env.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { resolvePathSync, type ResolveOptions } from "mlly";
import type { Preset, Environment, CreateEnvOptions } from "./types";

import nodeCompatPreset from "./presets/nodeless";

/**
Expand Down Expand Up @@ -33,6 +33,39 @@ 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: resolvePaths,
};
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, presets };
}

Expand Down
22 changes: 20 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export interface CreateEnvOptions {
/**
* Enable Node.js compatibility (nodeless) preset.
*
* Default: `false`
*/
nodeCompat?: boolean;

Expand All @@ -13,6 +15,22 @@ export interface CreateEnvOptions {
* Additional overrides.
*/
overrides?: Partial<Environment>;

/**
* 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 {
Expand All @@ -35,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"];
Expand Down
21 changes: 21 additions & 0 deletions test/env.test.ts
Original file line number Diff line number Diff line change
@@ -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", () => {
Expand Down Expand Up @@ -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,
);
}
});
});
});

0 comments on commit af71c96

Please sign in to comment.