You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is it possible for a Vite plugin to take a JS file (e.g. ui-component.module.css.js) and transform it to a "virtual" CSS file that's still processed by other Vite CSS plugins (i.e. treated as if it were originally import './ui-component.module.css')?
Background
I'm trying to implement a UI library which uses ClojureScript (CLJS) for the core app logic and style generation. It uses Emmy, a Clojure computer algebra system (CAS), for color space math to generate color scales.
The CLJS part of the library defines color scale functions and constants with concrete instances of these functions (e.g. 5-step blue gradient).
The constants can be exported as static CSS files, with the functions being imported as needed for UIs with runtime color dynamism (e.g. data visualizations with runtime-swappable datasets using D3 that need to generate color palettes on the fly).
(nsui-library.color-scale.css
(:require
[emmy.generic :as g]
[emmy.matrix :as m]
[emmy.numbers]
[ui-library.utils.css :refer [color-gradient->css]]))
(defngenerate-gradient"Create an n-stop gradient between 2 colors in the desired colorspace (e.g. CIELAB, CAM16-UCS)."
[start-color end-color stops color-space]
...)
(def ^:export blue-gradient"CSS stylesheet fragment string for CSS variables encoding a blue gradient."
(color-gradient->css (generate-gradient ...)))
(def ^:export purple-gradient"CSS stylesheet fragment string for CSS variables encoding a purple gradient."
(color-gradient->css (generate-gradient ...)))
ClojureScript compiler toolchains can be configured to output a directory with an ESM file per Clojure namespace. For example:
ui-library
│ # CLJS source.
├── cljs
│ └── ui_library
│ └── color_scale
│ └── css.cljs
│
│ # Compiled CLJS. Can only output JS files.
│ #
│ # Can create a Vite alias like `$generated` for import statements.
├── generated
│ ├── cljs_env.js
│ ├── cljs.core.js
│ ├── emmy.generic.js
│ ├── emmy.matrix.js
│ └── ui-library.color-scale.css.js
│
│ # UI components.
│ #
│ # Many UI libraries have their own template formats (e.g. JSX, Vue, Svelte).
│ # This bridges CLJS with those formats.
└── {framework}
└── src
└── Component.{jsx|vue|svelte|...}
ui-library.color-scale.css.js would look something like this:
import{$APP,shadow$provide,$jscomp}from"./cljs_env.js";import"./cljs.core.js";import"./emmy.generic.js";import"./emmy.matrix.js";// The CLJS strings are turned into JS strings.exportconstblue_gradient= ...;exportconstpurple_gradient= ...;
The main idea is to have a Vite plugin that handles import '$generated/ui-library.color-scale.css.js' statements by:
Ideally this "virtual" CSS file is processed by other Vite CSS plugins to take advantage of Vite's built-in CSS handling (e.g. CSS modules for component-scoped styling).
The main reason for passing these CSS style strings through JS is to let us take advantage of watch modes (e.g. shadow-cljs watch, vite dev) for incremental re-compilation and hot module replacement (HMR) on file changes in both the CLJS and Vite halves of the build pipeline.
The current setup I have instead has to manually do the CLJS compile + CLJS-to-CSS extraction in one go since the CLJS-to-CSS part is all-at-once instead of incremental (too expensive to run in watch mode since it re-extracts everything instead of only what's changed).
Documentation
Vite's Plugin API documentation has a small example for transforming custom file types, but I'm not sure if the return result will be processed by other plugins.
From the build graph in the Rollup plugin documentation which Vite's Plugin API docs page points to, it looks like each import can only be transformed once (by a single plugin or by all plugins?).
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Question
Is it possible for a Vite plugin to take a JS file (e.g.
ui-component.module.css.js
) and transform it to a "virtual" CSS file that's still processed by other Vite CSS plugins (i.e. treated as if it were originallyimport './ui-component.module.css'
)?Background
I'm trying to implement a UI library which uses ClojureScript (CLJS) for the core app logic and style generation. It uses Emmy, a Clojure computer algebra system (CAS), for color space math to generate color scales.
The CLJS part of the library defines color scale functions and constants with concrete instances of these functions (e.g. 5-step blue gradient).
The constants can be exported as static CSS files, with the functions being imported as needed for UIs with runtime color dynamism (e.g. data visualizations with runtime-swappable datasets using D3 that need to generate color palettes on the fly).
ClojureScript compiler toolchains can be configured to output a directory with an ESM file per Clojure namespace. For example:
ui-library.color-scale.css.js
would look something like this:The main idea is to have a Vite plugin that handles
import '$generated/ui-library.color-scale.css.js'
statements by:./generated/ui-library.color-scale.css.js
.blue_gradient
,purple_gradient
).Ideally this "virtual" CSS file is processed by other Vite CSS plugins to take advantage of Vite's built-in CSS handling (e.g. CSS modules for component-scoped styling).
The main reason for passing these CSS style strings through JS is to let us take advantage of watch modes (e.g.
shadow-cljs watch
,vite dev
) for incremental re-compilation and hot module replacement (HMR) on file changes in both the CLJS and Vite halves of the build pipeline.The current setup I have instead has to manually do the CLJS compile + CLJS-to-CSS extraction in one go since the CLJS-to-CSS part is all-at-once instead of incremental (too expensive to run in watch mode since it re-extracts everything instead of only what's changed).
Documentation
Vite's Plugin API documentation has a small example for transforming custom file types, but I'm not sure if the return result will be processed by other plugins.
From the build graph in the Rollup plugin documentation which Vite's Plugin API docs page points to, it looks like each import can only be transformed once (by a single plugin or by all plugins?).
Beta Was this translation helpful? Give feedback.
All reactions