million icon indicating copy to clipboard operation
million copied to clipboard

`million/compiler` failed to check nextjs `app` dir inside `src` dir

Open 0x221A opened this issue 2 years ago • 31 comments

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.

0x221A avatar Feb 09 '24 22:02 0x221A

Thanks for opening this issue! A maintainer will review it soon.

github-actions[bot] avatar Feb 09 '24 22:02 github-actions[bot]

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 avatar Feb 12 '24 13:02 SalahAdDin

@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.

0x221A avatar Feb 12 '24 18:02 0x221A

@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.

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 avatar Feb 13 '24 00:02 SalahAdDin

@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.

0x221A avatar Feb 13 '24 01:02 0x221A

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 avatar Feb 13 '24 02:02 SalahAdDin

@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.

0x221A avatar Feb 13 '24 12:02 0x221A

@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.

Well, it is working well after removing the provider.

In your opinion this workaround should not be required, right?

Thank you!

SalahAdDin avatar Feb 13 '24 13:02 SalahAdDin

@SalahAdDin The workaround is required if you're using app directory inside src directory as I said at first.

0x221A avatar Feb 13 '24 13:02 0x221A

@SalahAdDin The workaround is required if you're using app directory inside src directory as I said at first.

But it should be working without the workaround, right?

SalahAdDin avatar Feb 13 '24 19:02 SalahAdDin

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.

github-actions[bot] avatar Feb 29 '24 00:02 github-actions[bot]

@aidenybai any news on this issue?

SalahAdDin avatar Feb 29 '24 01:02 SalahAdDin

bump here, same issue -- anyone got around this?

nikshepsvn avatar Mar 16 '24 06:03 nikshepsvn

bump

IamSoPrada avatar Mar 17 '24 20:03 IamSoPrada

Workaround doesn't work for me on Nextjs 14 with app dir inside src.

lvanoverberghe avatar Mar 18 '24 07:03 lvanoverberghe

Workaround doesn't work for me on Nextjs 14 with app dir inside src.

Can I see the config?

0x221A avatar Mar 18 '24 08:03 0x221A

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)

lvanoverberghe avatar Mar 18 '24 08:03 lvanoverberghe

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,
});

IamSoPrada avatar Mar 18 '24 19:03 IamSoPrada

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.

github-actions[bot] avatar Apr 03 '24 00:04 github-actions[bot]

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.

github-actions[bot] avatar Apr 20 '24 00:04 github-actions[bot]

Up!

SalahAdDin avatar Apr 20 '24 00:04 SalahAdDin

Are you still experiencing this issue @SalahAdDin? It should have been fixed by now.

tobySolutions avatar Apr 25 '24 00:04 tobySolutions

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 avatar Apr 25 '24 03:04 SalahAdDin

@SalahAdDin With the latest release of next.js and million.js, it seems like this has not been fixed yet.

0x221A avatar Apr 25 '24 12:04 0x221A

Same issue

advanceddev avatar Apr 26 '24 15:04 advanceddev

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.

github-actions[bot] avatar May 12 '24 00:05 github-actions[bot]

Are you still experiencing this issue @SalahAdDin? It should have been fixed by now.

Yeah, we are still experiencing the issue.

SalahAdDin avatar May 13 '24 19:05 SalahAdDin

agreed with @IamSoPrada

I could only get it work this way with the latest version of nextjs "next": "14.2.3",

image
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

x86developers avatar May 23 '24 01:05 x86developers

same issue Screenshot 2024-05-31 at 15 36 52

ugursepetci avatar May 31 '24 12:05 ugursepetci