Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(remix-dev/vite): attach CSS from shared chunks to routes #7952

Merged
merged 7 commits into from
Nov 9, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
refactor
markdalgleish committed Nov 9, 2023
commit 134a248688e42522f6eb74aa5bfe3a7b18ed82ef
50 changes: 28 additions & 22 deletions packages/remix-dev/vite/plugin.ts
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ import {
type Connect,
type Plugin as VitePlugin,
type Manifest as ViteManifest,
type ManifestChunk,
type ResolvedConfig as ResolvedViteConfig,
type ViteDevServer,
type UserConfig as ViteUserConfig,
@@ -120,61 +121,66 @@ const getHash = (source: BinaryLike, maxLength?: number): string => {

const resolveBuildAssetPaths = (
pluginConfig: ResolvedRemixVitePluginConfig,
manifest: ViteManifest,
viteManifest: ViteManifest,
absoluteFilePath: string
): Manifest["entry"] & { css: string[] } => {
let rootRelativeFilePath = path.relative(
pluginConfig.rootDirectory,
absoluteFilePath
);
let manifestKey = normalizePath(rootRelativeFilePath);
let manifestEntry = manifest[manifestKey];
let entryChunk = viteManifest[manifestKey];

if (!manifestEntry) {
let knownManifestKeys = Object.keys(manifest)
if (!entryChunk) {
let knownManifestKeys = Object.keys(viteManifest)
.map((key) => '"' + key + '"')
.join(", ");
throw new Error(
`No manifest entry found for "${manifestKey}". Known manifest keys: ${knownManifestKeys}`
);
}

let keys = resolveViteManifestDepChunks(manifest, manifestKey);
let entries = [...keys].map((key) => manifest[key]);
let chunks = resolveDependantChunks(viteManifest, entryChunk);

return {
module: `${pluginConfig.publicPath}${manifestEntry.file}`,
module: `${pluginConfig.publicPath}${entryChunk.file}`,
imports:
dedupe(entries.flatMap((e) => e.imports ?? [])).map((imported) => {
return `${pluginConfig.publicPath}${manifest[imported].file}`;
dedupe(chunks.flatMap((e) => e.imports ?? [])).map((imported) => {
return `${pluginConfig.publicPath}${viteManifest[imported].file}`;
}) ?? [],
css:
dedupe(entries.flatMap((e) => e.css ?? [])).map((href) => {
dedupe(chunks.flatMap((e) => e.css ?? [])).map((href) => {
return `${pluginConfig.publicPath}${href}`;
}) ?? [],
};
};

function resolveViteManifestDepChunks(manifest: ViteManifest, base: string) {
let keys = new Set<string>();
function resolveDependantChunks(
viteManifest: ViteManifest,
entryChunk: ManifestChunk
): ManifestChunk[] {
let chunks = new Set<ManifestChunk>();

function dfs(key: string) {
if (keys.has(key)) {
function walk(chunk: ManifestChunk) {
if (chunks.has(chunk)) {
return;
}
keys.add(key);
let chunk = manifest[key];
for (let next of chunk.imports ?? []) {
dfs(next);

if (chunk.imports) {
for (let importKey of chunk.imports) {
walk(viteManifest[importKey]);
}
}

chunks.add(chunk);
}
dfs(base);

return keys;
walk(entryChunk);

return Array.from(chunks);
}

// common utils?
function dedupe(array: any[]) {
function dedupe<T>(array: T[]): T[] {
return [...new Set(array)];
}