From 75659944d7763187eb9c01418f8a96a91454bd2c Mon Sep 17 00:00:00 2001 From: devfive Date: Sun, 30 Aug 2026 12:42:24 +0900 Subject: [PATCH 1/2] fix(next-plugin): resolve isolated WASM dependency # Conflicts: # .changepacks/changepack_log_fixWasmLiteResolution20260830.json --- ..._fixBunIsolatedWasmResolution20260830.json | 7 +++ .../next-plugin/src/__tests__/wasm.test.ts | 59 ++++++++++++++++++- packages/next-plugin/src/wasm.ts | 7 ++- 3 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 .changepacks/changepack_log_fixBunIsolatedWasmResolution20260830.json diff --git a/.changepacks/changepack_log_fixBunIsolatedWasmResolution20260830.json b/.changepacks/changepack_log_fixBunIsolatedWasmResolution20260830.json new file mode 100644 index 00000000..75e4d676 --- /dev/null +++ b/.changepacks/changepack_log_fixBunIsolatedWasmResolution20260830.json @@ -0,0 +1,7 @@ +{ + "changes": { + "packages/next-plugin/package.json": "Patch" + }, + "note": "Resolve WASM from the plugin's physical install location in Bun isolated installs", + "date": "2026-08-30T03:43:34.977Z" +} diff --git a/packages/next-plugin/src/__tests__/wasm.test.ts b/packages/next-plugin/src/__tests__/wasm.test.ts index e323b41c..b03be167 100644 --- a/packages/next-plugin/src/__tests__/wasm.test.ts +++ b/packages/next-plugin/src/__tests__/wasm.test.ts @@ -1,20 +1,42 @@ +import { + mkdirSync, + mkdtempSync, + rmSync, + symlinkSync, + writeFileSync, +} from 'node:fs' +import { tmpdir } from 'node:os' +import { join } from 'node:path' import * as wasm from '@devup-ui/wasm' import * as webpackPlugin from '@devup-ui/webpack-plugin' -import { afterEach, describe, expect, it } from 'bun:test' +import { afterAll, afterEach, beforeAll, describe, expect, it } from 'bun:test' import { loadWasm, loadWebpackPlugin, + requireFromPlugin, requireWasm, setWasmForTesting, setWebpackPluginForTesting, } from '../wasm' +const originalCwd = process.cwd() +let tempRoots: string[] = [] + +beforeAll(() => { + tempRoots = [] +}) + afterEach(() => { + process.chdir(originalCwd) setWasmForTesting(undefined) setWebpackPluginForTesting(undefined) }) +afterAll(() => { + for (const root of tempRoots) rmSync(root, { recursive: true, force: true }) +}) + describe('WASM selection', () => { it('uses an injected namespace in tests', () => { setWasmForTesting(wasm) @@ -27,6 +49,41 @@ describe('WASM selection', () => { expect(typeof loadWasm(true).codeExtract).toBe('function') }) + it('resolves dependencies from a Bun-style isolated install', () => { + const root = mkdtempSync(join(tmpdir(), 'devup-ui-next-isolated-')) + tempRoots.push(root) + const isolatedNodeModules = join( + root, + 'node_modules/.bun/next-plugin/node_modules', + ) + const pluginDir = join(isolatedNodeModules, '@devup-ui/next-plugin') + const wasmDir = join(isolatedNodeModules, '@devup-ui/wasm') + const rootScope = join(root, 'node_modules/@devup-ui') + mkdirSync(pluginDir, { recursive: true }) + mkdirSync(wasmDir, { recursive: true }) + mkdirSync(rootScope, { recursive: true }) + writeFileSync( + join(pluginDir, 'package.json'), + JSON.stringify({ name: '@devup-ui/next-plugin' }), + ) + writeFileSync( + join(wasmDir, 'package.json'), + JSON.stringify({ name: '@devup-ui/wasm', main: 'index.cjs' }), + ) + writeFileSync(join(wasmDir, 'index.cjs'), 'module.exports = { isolated: true }') + symlinkSync( + pluginDir, + join(rootScope, 'next-plugin'), + process.platform === 'win32' ? 'junction' : 'dir', + ) + + process.chdir(root) + + expect(requireFromPlugin<{ isolated: boolean }>('@devup-ui/wasm')).toEqual({ + isolated: true, + }) + }) + it.each(['MODULE_NOT_FOUND', 'ERR_PACKAGE_PATH_NOT_EXPORTED'])( 'falls back to the full package when the lite export fails with %s', (code) => { diff --git a/packages/next-plugin/src/wasm.ts b/packages/next-plugin/src/wasm.ts index 50bd97e1..e38bcccc 100644 --- a/packages/next-plugin/src/wasm.ts +++ b/packages/next-plugin/src/wasm.ts @@ -1,4 +1,4 @@ -import { existsSync } from 'node:fs' +import { existsSync, realpathSync } from 'node:fs' import { createRequire } from 'node:module' import { join } from 'node:path' @@ -11,7 +11,8 @@ let fullWasm: DevupWasm | undefined let liteWasm: DevupWasm | undefined let webpackPlugin: DevupWebpackPlugin | undefined -function requireFromPlugin(specifier: string): T { +/** @internal Resolve dependencies from the plugin's physical install location. */ +export function requireFromPlugin(specifier: string): T { const installedPackage = join( process.cwd(), 'node_modules/@devup-ui/next-plugin/package.json', @@ -25,7 +26,7 @@ function requireFromPlugin(specifier: string): T { : existsSync(workspacePackage) ? workspacePackage : join(process.cwd(), 'package.json') - return createRequire(requireBase)(specifier) as T + return createRequire(realpathSync(requireBase))(specifier) as T } type WasmLoader = (specifier: string) => DevupWasm From 3eab3aa25a6255a6b9def5175f830086a3835591 Mon Sep 17 00:00:00 2001 From: devfive Date: Sun, 30 Aug 2026 12:52:06 +0900 Subject: [PATCH 2/2] test(next-plugin): format isolated install regression --- packages/next-plugin/src/__tests__/wasm.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/next-plugin/src/__tests__/wasm.test.ts b/packages/next-plugin/src/__tests__/wasm.test.ts index b03be167..da10f9b3 100644 --- a/packages/next-plugin/src/__tests__/wasm.test.ts +++ b/packages/next-plugin/src/__tests__/wasm.test.ts @@ -7,6 +7,7 @@ import { } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' + import * as wasm from '@devup-ui/wasm' import * as webpackPlugin from '@devup-ui/webpack-plugin' import { afterAll, afterEach, beforeAll, describe, expect, it } from 'bun:test' @@ -70,7 +71,10 @@ describe('WASM selection', () => { join(wasmDir, 'package.json'), JSON.stringify({ name: '@devup-ui/wasm', main: 'index.cjs' }), ) - writeFileSync(join(wasmDir, 'index.cjs'), 'module.exports = { isolated: true }') + writeFileSync( + join(wasmDir, 'index.cjs'), + 'module.exports = { isolated: true }', + ) symlinkSync( pluginDir, join(rootScope, 'next-plugin'),