nextui-org / tailwind-variants

🦄 Tailwindcss first-class variant API
https://tailwind-variants.org
MIT License
2.27k stars 64 forks source link

In monorepo, `writeFileSync()` is called on the client side #90

Closed dino3616 closed 10 months ago

dino3616 commented 1 year ago

Describe the bug

In monorepo using Turborepo, when withTV() was called in a child package to hide settings related to tailwind, writeFileSync() was called on the client side and compilation failed.

To Reproduce

Steps to reproduce the behavior:

  1. Clone a minimally configured repository to reproduce this problem: https://github.com/dino3616/tv-bug (alternative: you can use Codespaces)
  2. Install dependencies with the pnpm install command
  3. Start the development server with the pnpm website dev command
  4. Check the errors output to the browser and terminal

Expected behavior

Can compile even if withTV() is called in a child package.

Screenshots

Below is a screenshot of the error output to the browser:

image

and terminal:

pnpm website dev

> tv-bug@0.1.0 website /Users/shio/Projects/shio3616/tv-bug
> pnpm --filter @tv-bug/website "dev"

> @tv-bug/website@0.1.0 dev /Users/shio/Projects/shio3616/tv-bug/apps/website
> next dev

- ready started server on 0.0.0.0:3000, url: http://localhost:3000
- event compiled client and server successfully in 318 ms (20 modules)
- wait compiling...
- event compiled client and server successfully in 100 ms (20 modules)
- wait compiling /page (client and server)...
- error ../../node_modules/.pnpm/tailwind-variants@0.1.13_tailwindcss@3.3.3/node_modules/tailwind-variants/dist/chunk-FUBUDMV2.js:1:0
Module not found: Can't resolve 'fs'

https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
../../node_modules/.pnpm/tailwind-variants@0.1.13_tailwindcss@3.3.3/node_modules/tailwind-variants/dist/transformer.js
../../packages/tailwind/src/config.ts
../../packages/tailwind/src/index.ts
./src/component/client-button.tsx
- wait compiling /_error (client and server)...
- error ../../node_modules/.pnpm/tailwind-variants@0.1.13_tailwindcss@3.3.3/node_modules/tailwind-variants/dist/chunk-FUBUDMV2.js:1:0
Module not found: Can't resolve 'fs'

https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
../../node_modules/.pnpm/tailwind-variants@0.1.13_tailwindcss@3.3.3/node_modules/tailwind-variants/dist/transformer.js
../../packages/tailwind/src/config.ts
../../packages/tailwind/src/index.ts
./src/component/client-button.tsx
<w> [webpack.cache.PackFileCacheStrategy] Caching failed for pack: Error: ENOENT: no such file or directory, rename '/Users/shio/Projects/shio3616/tv-bug/apps/website/.next/cache/webpack/client-development-fallback/1.pack.gz_' -> '/Users/shio/Projects/shio3616/tv-bug/apps/website/.next/cache/webpack/client-development-fallback/1.pack.gz

Desktop (please complete the following information):

Additional context

This problem is only specific to monorepo and does not occur with polyrepo. In fact, a modification like this PR completely eliminates the problem.

tianenpang commented 1 year ago

Hi @dino3616 thank you for your feedback and for providing a reproduction case.

Based on the reproduction, it seems that this issue is not related to the tailwind-variants. Instead, it might be due to the importing from @tv-bug/tailwind/src/index.ts which led to bundling the @tv-bug/tailwind/src/config.ts file into the client side and we should try to avoid this whenever possible.

Consider not exporting and importing directly from barrel files.

packages/tailwind/src/index.ts

- export * from './config';
  export * from './util';

apps/website/tailwind.config.ts

- import { createConfig } from '@tv-bug/tailwind';
+ import { createConfig } from '@tv-bug/tailwind/src/config';

Try out the modularize imports.

Rename config.ts and util.ts in the packages/tailwind/src directory to create-config.ts and cn.ts, and then fix the exports in the barrel file whitch is index.ts.

// add modularizeImports config in next.config.mjs
const config = {
  ...rest,
  modularizeImports:{
    '@tv-bug/tailwind': {
      transform: '@tv-bug/tailwind/src/{{ kebabCase member }}',
      preventFullImport: true,
      skipDefaultConversion: true,
    },
  }
};

// imports will be the same as in the repro, no changes needed
import { createConfig } from '@tv-bug/tailwind';
import { cn } from '@tv-bug/tailwind';

// and you are good to go 🚀
mskelton commented 10 months ago

Closing as stale, @tianenpang's suggestion should resolve the issue, but if it does not, we can re-open this issue.