Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vite-plugin-native-modules",
"version": "2.4.0",
"version": "2.4.1",
"description": "A Vite plugin for integrating Node.js native modules into your Vite project",
"keywords": [
"electron",
Expand Down
13 changes: 11 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -816,8 +816,6 @@ export default nativeModule;

name,

enforce: "pre",

async resolveId(source, importer) {
// Check if enabled
const enabled = options.forced ?? command === "build";
Expand Down Expand Up @@ -1933,6 +1931,17 @@ export default nativeModule;
},
};

const resolveId = plugin.resolveId;
if (typeof resolveId === "function") {
plugin.resolveId = {
call(context: unknown, ...args: unknown[]) {
return Reflect.apply(resolveId, context, args);
},
handler: resolveId,
order: "pre",
} as Plugin["resolveId"];
}

const generateBundle = plugin.generateBundle;
if (typeof generateBundle === "function") {
plugin.generateBundle = {
Expand Down
86 changes: 86 additions & 0 deletions test/vite-static-import-compat.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,33 @@ import { build as buildVite7 } from "vite7";
import vite7Package from "vite7/package.json";
import { build as buildVite8 } from "vite8";
import vite8Package from "vite8/package.json";
import type { Rollup } from "vite";
import nativeFilePlugin from "../src/index.js";

type ViteBuild = (config: unknown) => Promise<unknown>;

function outputs(
result: Rollup.RollupOutput | Rollup.RollupOutput[],
): Array<Rollup.OutputAsset | Rollup.OutputChunk> {
return (Array.isArray(result) ? result : [result]).flatMap((output) => output.output);
}

function expectNativeAddonOutput(result: Rollup.RollupOutput | Rollup.RollupOutput[]): void {
const generated = outputs(result);
const bundledCode = generated
.filter((output): output is Rollup.OutputChunk => output.type === "chunk")
.map((output) => output.code)
.join("\n");

expect(
generated.some(
(output) => output.type === "asset" && /addon-[A-F0-9]{8}\.node/.test(output.fileName),
),
).toBe(true);
expect(bundledCode).toMatch(/addon-[A-F0-9]{8}\.node/);
expect(bundledCode).not.toContain('"./addon.node"');
}

const viteVersions = [
{ build: buildVite7 as ViteBuild, major: 7, version: vite7Package.version },
{ build: buildVite8 as ViteBuild, major: 8, version: vite8Package.version },
Expand Down Expand Up @@ -47,5 +70,68 @@ describe.each(viteVersions)(
root: tempDir,
});
});

it("bundles a TypeScript module that loads a native addon with require", async () => {
const entryPath = path.join(tempDir, "index.ts");
fs.writeFileSync(path.join(tempDir, "addon.node"), Buffer.from("fake native module"));
fs.writeFileSync(
entryPath,
`
export interface NativeAddon {
ping(): string;
}

const addon: NativeAddon = require("./addon.node");
export const ping = () => addon.ping();
`,
);

const result = (await build({
build: {
rollupOptions: { input: entryPath, output: { format: "es" } },
ssr: true,
write: false,
},
configFile: false,
logLevel: "silent",
plugins: [nativeFilePlugin()],
root: tempDir,
})) as Rollup.RollupOutput | Rollup.RollupOutput[];

expectNativeAddonOutput(result);
});

it("bundles an ESM TypeScript module that loads a native addon with createRequire", async () => {
const entryPath = path.join(tempDir, "index.ts");
fs.writeFileSync(path.join(tempDir, "addon.node"), Buffer.from("fake native module"));
fs.writeFileSync(
entryPath,
`
import { createRequire } from "node:module";

type NativeAddon = {
ping(): string;
};

const require = createRequire(import.meta.url);
const addon: NativeAddon = require("./addon.node");
export const ping = () => addon.ping();
`,
);

const result = (await build({
build: {
rollupOptions: { input: entryPath, output: { format: "es" } },
ssr: true,
write: false,
},
configFile: false,
logLevel: "silent",
plugins: [nativeFilePlugin()],
root: tempDir,
})) as Rollup.RollupOutput | Rollup.RollupOutput[];

expectNativeAddonOutput(result);
});
},
);
Loading