Open Dessader opened 1 year ago
Small update.
When importing a component from a package that uses VE and including variables in its own styles, they work correctly in the consumed application.
However, there is still a problem where using variables directly from the package in the styles of the application itself causes an error.
The reproducible example given in the issue is also updated to demonstrate this.
Component definition:
// Box.tsx
import React from "react";
import { root } from "./Box.css";
export const Box = () => <div className={root}>External box</div>;
// Box.css.ts
import { style } from "@vanilla-extract/css";
import { cssVars } from "../vars";
export const root = style({
padding: cssVars.spacing["spacing-2x"],
background: "lightcoral",
});
Consumption of component:
import { homePageRoot } from "@/styles/app.css";
import { Box } from "@example-monorepo/design-system";
const HomePage = () => {
return (
<div className={homePageRoot}>
Next App
<Box />
</div>
);
};
export default HomePage;
I had the same error when attempting to integrate Storybook into my vanilla-based monorepo. I was able to resolve it by adding the entryFileNames
and assetFileNames
entries to my rollup.config.js as in this example.
I had the same error when attempting to integrate Storybook into my vanilla-based monorepo. I was able to resolve it by adding the
entryFileNames
andassetFileNames
entries to my rollup.config.js as in this example.
Could you please provide a reproducible example?
I had a similar error, so basically when trying to import any css file into *.css.ts files throw errors in the new app directory. This css file is imported into your cssVars file when bundled. This is what I did on my project link Defining different entry points and adding this in the exports field on package.json solved my issue. I mostly followed what is done here I had to set treeshake on the entry point that handles globals selectors, then the css file can be imported directly into your layout page for example and the variable can be used in any css.ts file
I had a similar error, so basically when trying to import any css file into *.css.ts files throw errors in the new app directory. This css file is imported into your cssVars file when bundled. This is what I did on my project link Defining different entry points and adding this in the exports field on package.json solved my issue. I mostly followed what is done here I had to set treeshake on the entry point that handles globals selectors, then the css file can be imported directly into your layout page for example and the variable can be used in any css.ts file
Thank you for taking the time to address this issue. I'm focused on another project right now, as soon as I have time to review your changes to my repository I'll look into it in more detail.
This seems to be the exact issue we're still struggling with.
We've got a design system being compiled with rollup. It outputs three main things as separated exports: all code (react & vanilla), vanilla only (contracts, tokens, and CSS util functions), and styles bundled into a single CSS file.
The design system package JSON specifies these in an exports map and everything resolves correctly in the app
The rollup config follows the prescribed configuration to rename output files so the app doesn't try to recompile anything in the design system dist. And the app does not transpile the design system
The React component files in the app consume the react exports and the static CSS. *.css.ts files in the app exclusively use the vanilla only exports to guarantee they do not incur any additional imported deps or code
The app is a NextJS app of version 14.2 (also started out on 14.0). We've tried both pages and app dirs, both with the same result, the OP error
We started out with our full Next config, but have been stripping things back to bare bones to try and isolate the error. We've yet to identify the root cause. At this point we've got a completely empty app with a single route, an empty Next config with only the VE plugin, and what feels like a correctly optimized design system build output, and yet...
@CinArb2 your example link doesn't seem to work anymore. There's no diff to view. Do you have time to recreate it here in this post?
@askoufis Any update on this issue? I'll post more specifics about our setup in a little bit. But I'm curious if there's any outstanding blocking issues or undocumented restrictions/specifics we should be aware of
The design system's rollup.config.js
:
import path from 'path';
import json from '@rollup/plugin-json';
import { vanillaExtractPlugin } from '@vanilla-extract/rollup-plugin';
import { dts } from 'rollup-plugin-dts';
import esbuild from 'rollup-plugin-esbuild';
import { default as depsExternal } from 'rollup-plugin-node-externals';
import ts from 'typescript';
const CSS_IMPORT_REGEX = /^import '.+\.css';$/gm;
function loadCompilerOptions(tsconfig) {
if (!tsconfig) return {};
const configFile = ts.readConfigFile(tsconfig, ts.sys.readFile);
const { options } = ts.parseJsonConfigFileContent(
configFile.config,
ts.sys,
'./'
);
return options;
}
const emittedCSSFiles = new Set();
function removeCssImports() {
return {
name: 'remove-css-imports',
renderChunk(code, chunkInfo) {
const output = code.replaceAll(CSS_IMPORT_REGEX, '');
return {
code: output,
map: chunkInfo.map ?? null,
};
},
};
}
// Bundle all of the .css files into a single "styles.css" file
function bundleCss() {
return {
name: 'bundle-css-emits',
buildStart: () => {
emittedCSSFiles.clear();
},
// Ran against every file
renderChunk(code, chunkInfo) {
const allImports = [
...code.matchAll(/import (?:.* from )?['"]([^;'"]*)['"];?/g),
];
const dirname = path.dirname(chunkInfo.fileName);
const output = allImports.reduce(
(resultingCode, [importLine, moduleId]) => {
if (emittedCSSFiles.has(path.posix.join(dirname, moduleId))) {
return resultingCode.replace(importLine, '');
}
return resultingCode;
},
code
);
return {
code: output,
map: chunkInfo.map ?? null,
};
},
generateBundle(_, bundle) {
const bundleCode = Array.from(emittedCSSFiles.values())
.map((file) => {
const { name, fileName, source } = bundle[file];
return `/* ${name} -> ${fileName} */\n` + source;
})
.join('\n\n');
this.emitFile({
type: 'asset',
name: 'styles.css',
source: bundleCode,
});
},
};
}
// Bundle all of the .vanilla files into a single "vanilla" file
function bundleVanilla() {
return {
name: 'bundle-vanilla-emits',
generateBundle(_, bundle) {
const ext = bundle['index.d.ts'] ? 'd.ts' : 'js';
this.emitFile({
type: 'asset',
fileName: `vanilla.${ext}`,
source: bundle[`index.${ext}`].code
.replace(/\/\/# sourceMappingURL.+/gi, '')
.split('\n')
.filter(
(line) =>
line.endsWith(`.vanilla.js';`) ||
line.endsWith(`/types.js';`) ||
line.endsWith(`'./utils/css.js';`) ||
line.includes(`from './types/`)
)
.join('\n'),
});
},
};
}
const compilerOptions = loadCompilerOptions('tsconfig.dist.json');
const commonPlugins = [
vanillaExtractPlugin(),
depsExternal(),
esbuild(),
json(),
];
export default [
// Main processing and bundling
{
input: 'src/index.ts',
plugins: [
...commonPlugins,
removeCssImports(),
bundleCss(),
bundleVanilla(),
],
output: [
{
dir: 'dist',
exports: 'named',
format: 'esm',
preserveModules: true,
sourcemap: true,
// Change .css.js files to .vanilla.js so that they don't get re-processed by consumer's setup
entryFileNames({ name }) {
return `${name.replace(/\.css$/, '.vanilla')}.js`;
},
// Build out the assets folder with all of the css files.
assetFileNames({ name }) {
name = name
.replace(/^src\//, 'assets/')
.replace('.css.ts.vanilla', '');
if (name.match(/\.css$/)) {
emittedCSSFiles.add(name);
}
return name;
},
},
],
},
// Go through and create type definition files
{
input: 'src/index.ts',
plugins: [
...commonPlugins,
dts({
compilerOptions: {
...compilerOptions,
baseUrl: path.resolve(compilerOptions.baseUrl || '.'),
declaration: true,
emitDeclarationOnly: true,
noEmit: false,
noEmitOnError: true,
target: ts.ScriptTarget.ESNext,
},
}),
bundleVanilla(),
],
output: [
{
dir: 'dist',
format: 'esm',
preserveModules: true,
preserveModulesRoot: 'src',
// Change .css.js files to vanilla.js so that they don't get re-processed by consumer's setup
entryFileNames({ name }) {
return `${name.replace(/\.css$/, '.vanilla')}.d.ts`;
},
},
],
},
];
Produces a dist folder of this output:
assets
is static CSS files onlyindex.js
exports everything from all folders except assets
vanilla.js
exports only *.vanilla.js
files (the non-CSS output of *.css.ts
files) and utils/css.js
which only exports methods that have no dependency on the DOM/client. The only imports in that file are import { assignInlineVars } from '@vanilla-extract/dynamic'; import kebabCase from 'lodash/kebabCase';
Package.json exports:
The app's next.config.js
:
import { createVanillaExtractPlugin } from '@vanilla-extract/next-plugin';
const withVanillaExtract = createVanillaExtractPlugin();
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
};
export default withVanillaExtract(nextConfig);
In the app:
*.tsx
files import from the design system root*.css.ts
files only import from /vanilla
/styles
is imported once as static CSS in the app root / themeFigured out that having a CSS import inside of a *.css.ts
file was what triggering this particular error
This was a brutal time tracking this down
Describe the bug
An application and package has been created in the monorepository that contains the definition of base tokens that are implemented using vanilla extract. Rollup and the corresponding plugin - @vanilla-extract/rollup-plugin, are used to build this package.
This package should be used in applications and other local libraries that will implement UI components.
After building the package and trying to import the created variables into the consumer application, I get an error:
I've looked at other issues in the repository with similar cases, but the proposed solutions are mostly based on the fact that you have to create a separate entry point for exporting style-related entities to get something like this:
However, in this case, it's probably not relevant, since nothing other than that is exported from the package.
I may be wrong somewhere.
Reproduction
https://github.com/Dessader/vanilla-extract-style-issue
System Info
Used Package Manager
yarn
Logs
No response
Validations