Skip to content
Open
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
82 changes: 29 additions & 53 deletions typescript/packages/nextjs-plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ function getNextJsVersion(): string | null {
});
const nextPackageJson = require(projectNextPath);
return nextPackageJson.version || null;
} catch (error) {
} catch {
try {
// Fallback to checking in the plugin's dependencies
const nextPackageJson = require('next/package.json');
return nextPackageJson.version || null;
} catch (error) {
} catch {
console.warn(
'Warning: Could not determine Next.js version, defaulting to latest config',
);
Expand Down Expand Up @@ -43,7 +43,7 @@ export interface BamlNextConfig {
webpack?: ((config: Configuration, context: any) => Configuration) | null;
}

export function withBaml(bamlConfig: BamlNextConfig = {}) {
export function withBaml(_bamlConfig: BamlNextConfig = {}) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _bamlConfig parameter is currently unused. Consider removing it or using it for configurable behavior to avoid confusion.

return function withBamlConfig<T extends GenericNextConfig>(
nextConfig: T = {} as T,
): T {
Expand All @@ -55,65 +55,46 @@ export function withBaml(bamlConfig: BamlNextConfig = {}) {
const useNewConfig = majorVersion >= 14;
const isTurbo = Boolean(process.env.TURBOPACK === '1');

if (isTurbo) {
console.warn(
'\x1b[33m%s\x1b[0m',
`
⚠️ Warning: @boundaryml/baml-nextjs-plugin does not yet support Turbopack
Please remove the --turbo flag from your "next dev" command.
Example: "next dev" instead of "next dev --turbo"
`,
);
}

const turboConfig = isTurbo
? {
...(nextConfig.experimental?.turbo || {}),
rules: {
...(nextConfig.experimental?.turbo?.rules || {}),
'*.node': { loaders: ['nextjs-node-loader'], as: '*.js' },
},
}
: undefined;

return {
...nextConfig,
...(useNewConfig
? {
experimental: {
...(nextConfig.experimental || {}),
...(isTurbo ? { turbo: turboConfig } : {}),
},
// In Turbo mode, we don't add it to serverExternalPackages to avoid the conflict
...(isTurbo
? {}
: {
serverExternalPackages: [
...(nextConfig?.serverExternalPackages || []),
'@boundaryml/baml',
],
}),
// Always add BAML to serverExternalPackages for both webpack and Turbopack
serverExternalPackages: [
...(nextConfig?.serverExternalPackages || []),
'@boundaryml/baml',
'@boundaryml/baml-darwin-arm64',
'@boundaryml/baml-darwin-x64',
'@boundaryml/baml-linux-arm64-gnu',
'@boundaryml/baml-linux-arm64-musl',
'@boundaryml/baml-linux-x64-gnu',
'@boundaryml/baml-linux-x64-musl',
'@boundaryml/baml-win32-arm64-msvc',
'@boundaryml/baml-win32-x64-msvc',
],
}
: {
experimental: {
...(nextConfig.experimental || {}),
serverComponentsExternalPackages: [
...((nextConfig.experimental as any)
?.serverComponentsExternalPackages || []),
...(nextConfig.experimental?.serverComponentsExternalPackages ||
[]),
'@boundaryml/baml',
],
...(isTurbo ? { turbo: turboConfig } : {}),
},
}),
webpack: (config: Configuration, context: any) => {
let webpackConfig = config;
if (typeof nextConfig.webpack === 'function') {
config = nextConfig.webpack(config, context);
webpackConfig = nextConfig.webpack(config, context);
}

if (context.isServer) {
// Externalize the native module
config.externals = [
...(Array.isArray(config.externals) ? config.externals : []),
webpackConfig.externals = [
...(Array.isArray(webpackConfig.externals)
? webpackConfig.externals
: []),
'@boundaryml/baml',
'@boundaryml/baml-darwin-arm64',
'@boundaryml/baml-darwin-x64',
Expand All @@ -128,27 +109,22 @@ export function withBaml(bamlConfig: BamlNextConfig = {}) {

// Only add webpack rules if not using Turbo
if (!isTurbo) {
config.module = config.module || {};
config.module.rules = config.module.rules || [];
config.module.rules.push({
webpackConfig.module = webpackConfig.module || {};
webpackConfig.module.rules = webpackConfig.module.rules || [];
webpackConfig.module.rules.push({
test: /\.node$/,
use: [
{
loader: 'nextjs-node-loader',
options: {
outputPath: config.output?.path,
outputPath: webpackConfig.output?.path,
},
},
],
});
}

// Ensure module and rules are defined
config.module = config.module || {};
config.module.rules = config.module.rules || [];
// Add WebAssembly loading configuration (properly indented)

return config;
return webpackConfig;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correctness: webpackConfig is not returned if context.isServer is false, causing plugin webpack modifications to be lost in client builds.

🤖 AI Agent Prompt for Cursor/Windsurf

📋 Copy this prompt to your AI coding assistant (Cursor, Windsurf, etc.) to get help fixing this issue

In typescript/packages/nextjs-plugin/src/index.ts, line 129, ensure that the function always returns the modified `webpackConfig` object, not the original `config`, regardless of whether `context.isServer` is true or false. This prevents loss of plugin webpack modifications in client builds. Double-check that all plugin modifications are applied to `webpackConfig` and that it is always returned.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@seawatts is this a real bug?

},
} as T;
};
Expand Down
Loading