vanilla-extract-css / vanilla-extract

Zero-runtime Stylesheets-in-TypeScript
https://vanilla-extract.style
MIT License
9.64k stars 295 forks source link

Cannot consume exported theme vars from a library that is built with rollup-plugin #991

Open mihkeleidast opened 1 year ago

mihkeleidast commented 1 year ago

Describe the bug

Exported vars from a UI library that is build with @vanilla-extract/rollup-plugin cannot be consumed in consumer application without the application build breaking.

This affects vite, next, and webpack (and likely other app bundlers/plugins as well).

We are trying to pre-build our UI library with the rollup plugin, but this is not possible if we want to continue to consume the exported vars as well. I think some sort of double compilation is necessary, i.e. the vanilla-extract vite and webpack plugins should be able to consume libraries that are also build with some vanilla-extract plugin.

The workaround in https://github.com/vanilla-extract-css/vanilla-extract/discussions/774 works for the vite app, but I'm not sure that ignoring those nested imports is actually the best solution. Also, the same cannot be used for webpack/next examples.

Reproduction

https://github.com/graup/vanilla-extract-rollup-example/pull/3

System Info

See the repro, the versions don't matter, happens on latest versions as well as older ones.

Used Package Manager

yarn

Logs

// vite start
error during build:
Error: Build failed with 20 errors:
../../packages/ui/dist/foundation/Typography/styles.css.vanilla.js:1:7: ERROR: Cannot import "../../packages/ui/dist/foundation/Typography/styles.css.ts.vanilla.css" into a JavaScript file without an output path configured
../../packages/ui/dist/inputs/Button/Button.js:5:7: ERROR: Cannot import "../../packages/ui/dist/theme/theme.css.ts.vanilla.css" into a JavaScript file without an output path configured
../../packages/ui/dist/inputs/Button/styles.css.vanilla.js:1:7: ERROR: Cannot import "../../packages/ui/dist/theme/theme.css.ts.vanilla.css" into a JavaScript file without an output path configured
../../packages/ui/dist/inputs/Button/styles.css.vanilla.js:2:7: ERROR: Cannot import "../../packages/ui/dist/theme/sprinkles.css.ts.vanilla.css" into a JavaScript file without an output path configured
../../packages/ui/dist/inputs/Button/styles.css.vanilla.js:3:7: ERROR: Cannot import "../../packages/ui/dist/inputs/Button/styles.css.ts.vanilla.css" into a JavaScript file without an output path configured
...
    at failureErrorWithLog (/home/mihkel/dev/mihkeleidast/vanilla-extract-rollup-example/node_modules/@vanilla-extract/vite-plugin/node_modules/esbuild/lib/main.js:1604:15)
    at /home/mihkel/dev/mihkeleidast/vanilla-extract-rollup-example/node_modules/@vanilla-extract/vite-plugin/node_modules/esbuild/lib/main.js:1056:28
    at runOnEndCallbacks (/home/mihkel/dev/mihkeleidast/vanilla-extract-rollup-example/node_modules/@vanilla-extract/vite-plugin/node_modules/esbuild/lib/main.js:1476:61)
    at buildResponseToResult (/home/mihkel/dev/mihkeleidast/vanilla-extract-rollup-example/node_modules/@vanilla-extract/vite-plugin/node_modules/esbuild/lib/main.js:1054:7)
    at /home/mihkel/dev/mihkeleidast/vanilla-extract-rollup-example/node_modules/@vanilla-extract/vite-plugin/node_modules/esbuild/lib/main.js:1166:14
    at responseCallbacks.<computed> (/home/mihkel/dev/mihkeleidast/vanilla-extract-rollup-example/node_modules/@vanilla-extract/vite-plugin/node_modules/esbuild/lib/main.js:701:9)
    at handleIncomingPacket (/home/mihkel/dev/mihkeleidast/vanilla-extract-rollup-example/node_modules/@vanilla-extract/vite-plugin/node_modules/esbuild/lib/main.js:756:9)
    at Socket.readFromStdout (/home/mihkel/dev/mihkeleidast/vanilla-extract-rollup-example/node_modules/@vanilla-extract/vite-plugin/node_modules/esbuild/lib/main.js:677:7)
    at Socket.emit (node:events:513:28)
    at addChunk (node:internal/streams/readable:315:12)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
// vite end

// next start, webpack fails similarly
info  - Creating an optimized production build ..<w> [webpack.cache.PackFileCacheStrategy] Skipped not serializable cache item 'Compilation/modules|/home/mihkel/dev/mihkeleidast/vanilla-extract-rollup-example/node_modules/@vanilla-extract/webpack-plugin/loader/dist/vanilla-extract-webpack-plugin-loader.cjs.js??ruleSet[1].rules[0].use[0]!/home/mihkel/dev/mihkeleidast/vanilla-extract-rollup-example/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[3].oneOf[3].use!/home/mihkel/dev/mihkeleidast/vanilla-extract-rollup-example/apps/example-nextjs/components/billing.css.ts': No serializer registered for CodeGenerationError
<w> while serializing webpack/lib/cache/PackFileCacheStrategy.PackContentItems -> webpack/lib/NormalModule -> webpack/lib/ModuleBuildError -> CodeGenerationError
info  - Creating an optimized production build  
Failed to compile.

./components/billing.css.ts
CodeGenerationError: No template for dependency: CssDependency
    at /home/mihkel/dev/mihkeleidast/vanilla-extract-rollup-example/node_modules/next/dist/compiled/webpack/bundle5.js:25629:18
    at /home/mihkel/dev/mihkeleidast/vanilla-extract-rollup-example/node_modules/next/dist/compiled/webpack/bundle5.js:17657:6
    at /home/mihkel/dev/mihkeleidast/vanilla-extract-rollup-example/node_modules/next/dist/compiled/webpack/bundle5.js:17611:11
    at /home/mihkel/dev/mihkeleidast/vanilla-extract-rollup-example/node_modules/next/dist/compiled/webpack/bundle5.js:60793:9
    at /home/mihkel/dev/mihkeleidast/vanilla-extract-rollup-example/node_modules/next/dist/compiled/webpack/bundle5.js:17660:6
    at eval (eval at create (/home/mihkel/dev/mihkeleidast/vanilla-extract-rollup-example/node_modules/next/dist/compiled/webpack/bundle5.js:140346:10), <anonymous>:30:1)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
// next end

Validations

otaviomad commented 1 year ago

I can confirm that this problem also occurs on the esbuild plugin. The built files get prepended with a bunch of imports referencing non-existent vanilla css files.

greenskybluephish commented 1 year ago

I came across this same issue today, with very similar usage to OP. Tracking the error led me to this post. When esbuild is passed a 'css.ts' file that is importing 'vars' from the library, it automatically tries to use it's css loader to write a matching CSS file, but since it's only writing the JS file to memory and there's no outdir set, it causes the error to be thrown.

Originally thought there were further changes needed to address, but turned out once I updated the vite and plugin versions, the esbuild options allowed the necessary config to be set.

vanillaExtractPlugin({ esbuildOptions: { loader: { '.css': 'empty' } } })

https://github.com/mihkeleidast/vanilla-extract-rollup-example/pull/1

przemyslaw-wlodek commented 11 months ago

I also faced this issue. We used ladle with vite for one of the packages in monorepo and the fix provided by @greenskybluephish worked fine. Now I'm migrating this package to Storybook with webpack and there are no clear answers.

packages/ui-lib -> UI components styled with vanilla-extract, built with rollup apps/my-app -> Application having packages/ui-lib as a dependency

You may need to modify this to your needs, depending on context but I will give my example where apps/my-app has its own Storybook playground.

  1. Remove any loaders targeting css files (or make sure they exclude vanilla-extract css: example)
  2. Add a loader targeting your local app styles (like in vanilla-extract docs)
  3. Add a loader targeting your ui package from monorepo (packages/ui-lib)

I ended up with this:

// step 1
config.module.rules = config.module.rules.filter((rule) => !rule?.test?.test('test.css'));

// step 2
config.module.rules.push({
  test: /\.vanilla.css$/i,
  exclude: /node_modules/,
  use: [
    MiniCssExtractPlugin.loader,
    {
      loader: require.resolve('css-loader'),
      options: { url: false },
    },
  ],
});

// step 3
// target pre-built files e.g. `component.vanilla-13hs15.css` instead of `component.vanilla.css`
config.module.rules.push({
  test: /\.vanilla-.*.css$/i,
  include: path.resolve(__dirname, '../../ui-lib'),
  use: [
    MiniCssExtractPlugin.loader,
    {
      loader: require.resolve('css-loader'),
      options: { url: false },
    },
  ],
});