Skip to content

Commit

Permalink
feat: support css modules
Browse files Browse the repository at this point in the history
Signed-off-by: Marc MacLeod <847542+marbemac@users.noreply.github.com>
  • Loading branch information
marbemac committed Jan 22, 2024
1 parent dc4b723 commit db81922
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/perfect-goats-warn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ssrx/vite': minor
---

Support CSS modules.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.button {
background-color: blue;
}
13 changes: 13 additions & 0 deletions examples/solid-router-simple/src/components/Counter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { createSignal } from 'solid-js';

import styles from './Counter.module.css';

export function Counter() {
const [count, setCount] = createSignal(0);

return (
<button class={styles['button']} onClick={() => setCount(count => count + 1)}>
Counter: {count()}
</button>
);
}
3 changes: 3 additions & 0 deletions examples/solid-router-simple/src/pages/_index.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.data {
color: red;
}
11 changes: 10 additions & 1 deletion examples/solid-router-simple/src/pages/_index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { createResource } from 'solid-js';

import { Counter } from '~/components/Counter.tsx';
import { rand, sleep } from '~/utils.ts';

import styles from './_index.module.css';

export async function loader() {
await sleep();

Expand All @@ -17,7 +20,13 @@ export default function Component() {

<p>This home route simply loads some data (with a simulated delay) and displays it.</p>

<p>Loader Data: {data()?.data}</p>
<p>
Loader Data: <span class={styles['data']}>{data()?.data}</span>
</p>

<div>
<Counter />
</div>
</div>
);
}
21 changes: 16 additions & 5 deletions packages/vite/src/helpers/vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,17 @@ import type { ModuleNode, ViteDevServer } from 'vite';

import { type Asset, AssetType, getAssetWeight } from './routes.ts';

export async function findStylesInModuleGraph(vite: ViteDevServer, match: string[], ssr: boolean) {
export async function findStylesInModuleGraph({
vite,
match,
ssr,
cssModules,
}: {
vite: ViteDevServer;
match: string[];
ssr: boolean;
cssModules: Record<string, string>;
}) {
const assets: { [id: string]: Asset } = {};

const dependencies = await findDependencies(vite, match, ssr);
Expand All @@ -22,9 +32,7 @@ export async function findStylesInModuleGraph(vite: ViteDevServer, match: string

if (file && ASSET_REGEXES.styles.test(file)) {
try {
const mod = await vite.ssrLoadModule(url);

const code = mod['default'];
const code = isCssModulesFile(file) ? cssModules[file] : (await vite.ssrLoadModule(url))['default'];

assets[file] = {
type: AssetType.style,
Expand Down Expand Up @@ -167,7 +175,8 @@ async function findDependencies(vite: ViteDevServer, match: string[], ssr: boole
}

const ASSET_REGEXES = {
styles: /\.(css|less|sass|scss|styl|stylus|pcss|postcss)$/,
styles: /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/,
cssModules: /\.module\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/,
external: /\/(node_modules|inc)\/.*/,
static: /\.(txt|ico|svg|webp|png|jpg|jpeg|gif|mp3)$/,
runtime: /\.(js|ts|tsx|jsx)$/,
Expand All @@ -178,6 +187,8 @@ const ASSET_REGEXES = {
vite: /^\/@.+|^\0vite\/.+/,
};

export const isCssModulesFile = (assetPath: string) => ASSET_REGEXES.cssModules.test(assetPath);

export const isInternalRuntimeAsset = (assetPath: string) => {
return (
(ASSET_REGEXES.runtime.test(assetPath) || ASSET_REGEXES.styles.test(assetPath)) &&
Expand Down
8 changes: 7 additions & 1 deletion packages/vite/src/plugins/dev-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { Connect, Plugin, ViteDevServer } from 'vite';

import type { Config } from '../config.ts';
import { PLUGIN_NAMESPACE } from '../consts.ts';
import { isAssetHandledByVite } from '../helpers/vite.ts';
import { isAssetHandledByVite, isCssModulesFile } from '../helpers/vite.ts';
import type { Router } from '../router.ts';
import type { Manifest } from '../ssr-manifest.ts';

Expand All @@ -30,6 +30,12 @@ export const devServerPlugin = ({ config, manifest }: DevServerPluginOpts): Plug

server.middlewares.use(await createMiddleware(server, { config }));
},

transform(code, id) {
if (isCssModulesFile(id)) {
manifest.cssModules[id] = code;
}
},
};
};

Expand Down
10 changes: 9 additions & 1 deletion packages/vite/src/ssr-manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ export class Manifest<ExternalRoutes> {
#ssrManifest?: SSRManifest;
readonly ssrManifestName = 'ssr-manifest.json';

// id (asset path) => strified css module
readonly cssModules: Record<string, string> = {};

constructor(opts: ManifestOpts<ExternalRoutes>) {
this.router = opts.router;
this.config = opts.config;
Expand Down Expand Up @@ -194,7 +197,12 @@ export class Manifest<ExternalRoutes> {
});

// styles
const styleAssets = await findStylesInModuleGraph(devServer, [this.config.clientFile], false);
const styleAssets = await findStylesInModuleGraph({
vite: devServer,
match: [this.config.clientFile],
ssr: false,
cssModules: this.cssModules,
});
assets.push(...Object.values(styleAssets));

return assets;
Expand Down

0 comments on commit db81922

Please sign in to comment.