`million/compiler` failed to check nextjs `app` dir inside `src` dir
What version of million are you using?
3.0.3
Are you using an SSR adapter? If so, which one?
None
What package manager are you using?
pnpm
What operating system are you using?
Mac
What browser are you using?
Chrome
Describe the Bug
million/compiler failed to auto-determine whether the user is using app dir inside src dir. This caused the compiler to fail to compile RSC.
https://github.com/aidenybai/million/blob/ec34eba56d9640b2a57d3ab4fd5246bdc94db5cd/packages/compiler/index.ts#L35
What's the expected result?
The compiler should correctly determine whether the user is using app dir inside src dir or not.
Workaround
Manually set CompilerOptions.rsc to true.
export default million.next(nextConfig, { auto: { rsc: true }, rsc: true });
Link to Minimal Reproducible Example
https://stackblitz.com/edit/stackblitz-starters-vmkrup
Participation
- [X] I am willing to submit a pull request for this issue.
Thanks for opening this issue! A maintainer will review it soon.
I thought it was happening only for either localized or multi plugin projects cause:
/** @type {import('next').NextConfig} */
import createNextIntlPlugin from "next-intl/plugin";
import million from "million/compiler";
const withNextIntl = createNextIntlPlugin();
const millionConfig = {
auto: true,
};
const nextConfig = {
experimental: {
instrumentationHook: true,
},
webpack(config, { isServer }) {
if (isServer) {
if (Array.isArray(config.resolve.alias)) {
config.resolve.alias.push({ name: "msw/browser", alias: false });
} else {
config.resolve.alias["msw/browser"] = false;
}
} else {
if (Array.isArray(config.resolve.alias)) {
config.resolve.alias.push({ name: "msw/node", alias: false });
} else {
config.resolve.alias["msw/node"] = false;
}
}
return config;
},
productionBrowserSourceMaps: true,
reactStrictMode: true,
};
export default million.next(withNextIntl(nextConfig, millionConfig));
It was failing on loading.
After applying the workaround, running dev does fail anymore, even if we use auto: true, i.e., we don't use the workaround.
It is very weird.
@SalahAdDin I don't think that is the correct way to use the million.next function. To override the million config and use the custom plugin you should chain the plugin like this:
export default million.next(withNextIntl(nextConfig), millionConfig);
You don't need to use this workaround if your project doesn't use RSC. The workaround only useful for the project that using app dir and it's living inside src dir.
@SalahAdDin I don't think that is the correct way to use the
million.nextfunction. To override the million config and use the custom plugin you should chain the plugin like this:export default million.next(withNextIntl(nextConfig), millionConfig);You don't need to use this workaround if your project doesn't use RSC. The workaround only useful for the project that using
appdir and it's living insidesrcdir.
Well, You made me the key to remember the issue:
pnpm dev ✔ 20.11.0
> [email protected] dev /home/luisalaguna/Projects/TRT/twe_fe_next
> next dev
▲ Next.js 14.1.0
- Local: http://localhost:3000
- Experiments (use at your own risk):
· instrumentationHook
✓ Ready in 2.3s
⚠ Found a change in next.config.mjs. Restarting the server to apply the changes...
▲ Next.js 14.1.0
- Local: http://localhost:3000
- Experiments (use at your own risk):
· instrumentationHook
✓ Ready in 2.1s
✓ Compiled /src/middleware in 314ms (86 modules)
⚡ Million.js 3.0.3
- Tip: use // million-ignore for errors
- Hotline: https://million.dev/hotline
○ Compiling /[locale] ...
✓ Compiled /[locale] in 4s (1060 modules)
⨯ node_modules/.pnpm/@[email protected]_@[email protected][email protected]/node_modules/@radix-ui/react-direction/dist/index.mjs (4:82) @ undefined
⨯ TypeError: (0 , react__WEBPACK_IMPORTED_MODULE_0__.createContext) is not a function
at eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@[email protected]_@[email protected][email protected]/node_modules/@radix-ui/react-direction/dist/index.mjs:9:114)
at (rsc)/./node_modules/.pnpm/@[email protected]_@[email protected][email protected]/node_modules/@radix-ui/react-direction/dist/index.mjs (/home/luisalaguna/Projects/TRT/twe_fe_next/.next/server/vendor-chunks/@[email protected]_@[email protected][email protected]:20:1)
at __webpack_require__ (/home/luisalaguna/Projects/TRT/twe_fe_next/.next/server/webpack-runtime.js:33:42)
at eval (webpack-internal:///(rsc)/./src/app/[locale]/layout.tsx:11:83)
at (rsc)/./src/app/[locale]/layout.tsx (/home/luisalaguna/Projects/TRT/twe_fe_next/.next/server/app/[locale]/page.js:237:1)
at Function.__webpack_require__ (/home/luisalaguna/Projects/TRT/twe_fe_next/.next/server/webpack-runtime.js:33:42)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async collectGenerateParams (/home/luisalaguna/Projects/TRT/twe_fe_next/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/next/dist/build/utils.js:919:21)
at async Object.loadStaticPaths (/home/luisalaguna/Projects/TRT/twe_fe_next/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/next/dist/server/dev/static-paths-worker.js:46:13) {
type: 'TypeError',
page: '/en'
}
null
○ Compiling /_error ...
✓ Compiled /_error in 3.5s (1167 modules)
It happens when we use export default million.next(withNextIntl(nextConfig), millionConfig); and const millionConfig = { auto: true,};!!!
When we use const millionConfig = { auto: { rsc: true }, }; it still happens.
So, it is not a workaround in this case.
Workaround
Our solution is export default million.next(withNextIntl(nextConfig, millionConfig));.
Update:
Now, it does not work, again!
@SalahAdDin As I said in the workaround you need to manually set CompilerOptions.rsc to true. So your config should be something like this.
export default million.next(withNextIntl(nextConfig), { auto: { rsc: true }, rsc: true });
millionConfig is the object that passes to override the default config of million.next. It doesn't do anything if you chain it to nextConfig.
export default million.next(withNextIntl(nextConfig), { auto: { rsc: true }, rsc: true });
Not working for me:
- Experiments (use at your own risk):
· auto-rsc
✓ Compiled /[locale] in 6.9s (1051 modules)
⨯ node_modules/.pnpm/@[email protected]_@[email protected][email protected]/node_modules/@radix-ui/react-direction/dist/index.mjs (4:82) @ undefined
⨯ TypeError: (0 , react__WEBPACK_IMPORTED_MODULE_0__.createContext) is not a function
at eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@[email protected]_@[email protected][email protected]/node_modules/@radix-ui/react-direction/dist/index.mjs:9:114)
at (rsc)/./node_modules/.pnpm/@[email protected]_@[email protected][email protected]/node_modules/@radix-ui/react-direction/dist/index.mjs (/home/luisalaguna/Projects/TRT/twe_fe_next/.next/server/vendor-chunks/@[email protected]_@[email protected][email protected]:20:1)
at __webpack_require__ (/home/luisalaguna/Projects/TRT/twe_fe_next/.next/server/webpack-runtime.js:33:42)
at eval (webpack-internal:///(rsc)/./src/app/[locale]/layout.tsx:10:83)
at (rsc)/./src/app/[locale]/layout.tsx (/home/luisalaguna/Projects/TRT/twe_fe_next/.next/server/app/[locale]/page.js:237:1)
at Function.__webpack_require__ (/home/luisalaguna/Projects/TRT/twe_fe_next/.next/server/webpack-runtime.js:33:42)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async collectGenerateParams (/home/luisalaguna/Projects/TRT/twe_fe_next/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/next/dist/build/utils.js:919:21)
at async Object.loadStaticPaths (/home/luisalaguna/Projects/TRT/twe_fe_next/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/next/dist/server/dev/static-paths-worker.js:46:13) {
type: 'TypeError',
page: '/en'
}
null
○ Compiling /_error ...
✓ Compiled /_error in 2.3s (1158 modules)
⨯ node_modules/.pnpm/@[email protected]_@[email protected][email protected]/node_modules/@radix-ui/react-direction/dist/index.mjs (4:82) @ undefined
⨯ TypeError: (0 , react__WEBPACK_IMPORTED_MODULE_0__.createContext) is not a function
at eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@[email protected]_@[email protected][email protected]/node_modules/@radix-ui/react-direction/dist/index.mjs:9:114)
at (rsc)/./node_modules/.pnpm/@[email protected]_@[email protected][email protected]/node_modules/@radix-ui/react-direction/dist/index.mjs (/home/luisalaguna/Projects/TRT/twe_fe_next/.next/server/vendor-chunks/@[email protected]_@[email protected][email protected]:20:1)
at __webpack_require__ (/home/luisalaguna/Projects/TRT/twe_fe_next/.next/server/webpack-runtime.js:33:42)
at eval (webpack-internal:///(rsc)/./src/app/[locale]/layout.tsx:10:83)
at (rsc)/./src/app/[locale]/layout.tsx (/home/luisalaguna/Projects/TRT/twe_fe_next/.next/server/app/[locale]/page.js:237:1)
at Function.__webpack_require__ (/home/luisalaguna/Projects/TRT/twe_fe_next/.next/server/webpack-runtime.js:33:42)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async collectGenerateParams (/home/luisalaguna/Projects/TRT/twe_fe_next/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/next/dist/build/utils.js:919:21)
at async Object.loadStaticPaths (/home/luisalaguna/Projects/TRT/twe_fe_next/node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/next/dist/server/dev/static-paths-worker.js:46:13) {
type: 'TypeError',
page: '/en'
}
null
@SalahAdDin Then I think it's not related to the issue. From the error, it seems like you're using DirectionProvider directly in the server component without re-export it from @radix-ui/react-direction. As the error said createContext is not a function which means the compiler thinks that component is a server component. If you want to use a third-party react ui component such as radix-ui you need to re-export it with "use client" directive.
@SalahAdDin As I said in the workaround you need to manually set
CompilerOptions.rsctotrue. So your config should be something like this.export default million.next(withNextIntl(nextConfig), { auto: { rsc: true }, rsc: true });
millionConfigis the object that passes to override the default config ofmillion.next. It doesn't do anything if you chain it tonextConfig.
Well, it is working well after removing the provider.
In your opinion this workaround should not be required, right?
Thank you!
@SalahAdDin The workaround is required if you're using app directory inside src directory as I said at first.
@SalahAdDin The workaround is required if you're using
appdirectory insidesrcdirectory as I said at first.
But it should be working without the workaround, right?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs within the next 7 days.
@aidenybai any news on this issue?
bump here, same issue -- anyone got around this?
bump
Workaround doesn't work for me on Nextjs 14 with app dir inside src.
Workaround doesn't work for me on Nextjs 14 with app dir inside src.
Can I see the config?
await import("./src/env.js");
import bundleAnalyzer from "@next/bundle-analyzer";
import million from "million/compiler";
const withBundleAnalyzer = bundleAnalyzer({
enabled: process.env.ANALYZE === "true",
});
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
i18n: {
locales: ["en", "fr", "nl", "pt"],
defaultLocale: "en",
},
};
/* const millionConfig = {
auto: true,
};
export default million.next(withBundleAnalyzer(nextConfig), millionConfig); */
export default million.next(withBundleAnalyzer(nextConfig), {
auto: { rsc: true },
rsc: true,
});
I think it actually has to do with the type of NextConfig being passed to million.next.
Argument of type 'NextConfig' is not assignable to parameter of type '{ appDir?: boolean | undefined; basePath?: string | undefined; webpack?: ((config: Record<string, any>, options: any) => any) | undefined; }'.
Types of property 'webpack' are incompatible.
Type 'NextJsWebpackConfig | null | undefined' is not assignable to type '((config: Record<string, any>, options: any) => any) | undefined'.
Type 'null' is not assignable to type '((config: Record<string, any>, options: any) => any) | undefined'.ts(2345)
My project also has several plugins and uses src/app/[locale] structure. For me reason of my problems was 'next-compose-plugins'.
I tried to pass it like that :
export default million.next(withPlugins([withPWA, withBundleAnalyzer, withNextIntlConfig], nextConfig), {
auto: { rsc: true },
rsc: true,
});
as soon as i changed it to this it started working:
export default million.next(withBundleAnalyzer(withPWA(withNextIntlConfig(nextConfig))), {
auto: { rsc: true },
rsc: true,
});
My next.config.mjs :
import withNextIntl from 'next-intl/plugin'
//import withPlugins from 'next-compose-plugins'
import bundleAnalyzer from '@next/bundle-analyzer'
import withPWAInit from '@ducanh2912/next-pwa';
import million from "million/compiler";
const withNextIntlConfig = withNextIntl('./src/libs/i18n.ts');
const withBundleAnalyzer = bundleAnalyzer({
enabled: process.env.ANALYZE === 'true',
});
const withPWA = withPWAInit({
dest: 'public',
cacheOnFrontEndNav: true,
aggressiveFrontEndNavCaching: true,
reloadOnOnline: true,
disable: false,
workboxOptions: {
disableDevLogs: true,
maximumFileSizeToCacheInBytes: 250000
}
/*register: true,
skipWaiting: true*/
})
const nextConfig = {
//output: 'standalone',
//distDir: 'build',
productionBrowserSourceMaps: true,
async headers() {
const headers = [];
headers.push({
source: '/:all*(svg|jpg|jpeg|png|gif|ico|webp)',
locale: false,
headers: [
{
key: 'Cache-Control',
value: 'public, max-age=31536000, stale-while-revalidate',
},
],
});
// Prevent search engines from indexing the site if it is not live
// This is useful for staging environments before they are ready to go live
headers.push({
headers: [
{
key: 'X-Robots-Tag',
value: 'noindex',
},
],
source: '/:path*',
});
return headers;
},
webpack(config, {isServer}) {
config.module.rules.push({
test: /\.svg$/i,
issuer: /\.[jt]sx?$/,
use: ['@svgr/webpack'],
});
config.externals.push({
bufferutil: 'bufferutil',
'utf-8-validate': 'utf-8-validate',
});
if (isServer) {
if (Array.isArray(config.resolve.alias)) {
config.resolve.alias.push({ name: "msw/browser", alias: false });
} else {
config.resolve.alias["msw/browser"] = false;
}
} else {
if (Array.isArray(config.resolve.alias)) {
config.resolve.alias.push({ name: "msw/node", alias: false });
} else {
config.resolve.alias["msw/node"] = false;
}
}
return config;
},
images: {
deviceSizes: [320, 428, 744, 1024, 1440, 1920, 2048],
formats: ['image/avif', 'image/webp'],
domains: [
'localhost',
process.env.NEXT_PUBLIC_API_URL,
]
.filter(Boolean)
.map(url => url.replace(/https?:\/\//, '')),
},
};
/** @type {import('next').NextConfig} */
//withPlugins([withPWA, withBundleAnalyzer, withNextIntlConfig,], nextConfig)
export default million.next(withBundleAnalyzer(withPWA(withNextIntlConfig(nextConfig))), {
auto: { rsc: true },
rsc: true,
});
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs within the next 7 days.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs within the next 7 days.
Up!
Are you still experiencing this issue @SalahAdDin? It should have been fixed by now.
Are you still experiencing this issue @SalahAdDin? It should have been fixed by now.
Is there any new release? I can't see it here.
@SalahAdDin With the latest release of next.js and million.js, it seems like this has not been fixed yet.
Same issue
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs within the next 7 days.
Are you still experiencing this issue @SalahAdDin? It should have been fixed by now.
Yeah, we are still experiencing the issue.
agreed with @IamSoPrada
I could only get it work this way with the latest version of nextjs "next": "14.2.3",
import bundleAnalyzer from "@next/bundle-analyzer";
import million from "million/compiler";
import MillionLint from "@million/lint";
const withBundleAnalyzer = bundleAnalyzer({
enabled: process.env.ANALYZE === "true",
});
const nextConfig = {
productionBrowserSourceMaps: true,
async headers() {
const headers = [];
headers.push({
source: "/:all*(svg|jpg|jpeg|png|gif|ico|webp)",
locale: false,
headers: [
{
key: "Cache-Control",
value: "public, max-age=31536000, stale-while-revalidate",
},
],
});
headers.push({
headers: [
{
key: "X-Robots-Tag",
value: "noindex",
},
],
source: "/:path*",
});
return headers;
},
webpack(config, { isServer }) {
config.module.rules.push({
test: /\.svg$/i,
issuer: /\.[jt]sx?$/,
use: ["@svgr/webpack"],
});
config.externals.push({
bufferutil: "bufferutil",
"utf-8-validate": "utf-8-validate",
});
if (isServer) {
if (Array.isArray(config.resolve.alias)) {
config.resolve.alias.push({ name: "msw/browser", alias: false });
} else {
config.resolve.alias["msw/browser"] = false;
}
} else {
if (Array.isArray(config.resolve.alias)) {
config.resolve.alias.push({ name: "msw/node", alias: false });
} else {
config.resolve.alias["msw/node"] = false;
}
}
return config;
},
images: {
deviceSizes: [320, 428, 744, 1024, 1440, 1920, 2048],
formats: ["image/avif", "image/webp"],
remotePatterns: [
{
protocol: "http",
hostname: "localhost",
},
],
},
};
export default million.next(withBundleAnalyzer(nextConfig), {
auto: { rsc: true },
rsc: true,
});
With out this I get this error
Module not found: Can't resolve '/myproject/src/app/dashboard/layout.tsx' Module not found: Can't resolve '/myproject/src/app/layout.tsx'
https://nextjs.org/docs/messages/module-not-found
same issue