Skip to content

Commit

Permalink
Fix HMR in MDX deps in Content Collections (#9956)
Browse files Browse the repository at this point in the history
Co-authored-by: Florian Lefebvre <[email protected]>
Co-authored-by: bluwy <[email protected]>
  • Loading branch information
3 people authored Feb 6, 2024
1 parent 6e30bef commit 81acac2
Show file tree
Hide file tree
Showing 13 changed files with 124 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/soft-bags-flash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"astro": patch
---

Fixes HMR for MDX dependencies in Content Collections
32 changes: 32 additions & 0 deletions packages/astro/e2e/content-collections.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { expect } from '@playwright/test';
import { testFactory } from './test-utils.js';

const test = testFactory({ root: './fixtures/content-collections/' });

let devServer;

test.beforeAll(async ({ astro }) => {
devServer = await astro.startDevServer();
});

test.afterAll(async ({ astro }) => {
await devServer.stop();
astro.resetAllFiles();
});

test.describe('Content Collections', () => {
test('HMR', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/'));

await astro.editFile('./src/components/MyComponent.astro', (original) =>
original.replace('red', 'green')
);

const h1 = page.locator('#my-heading');

await expect(h1, 'should have green color').toHaveCSS(
'color',
'rgb(0, 128, 0)'
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';

// https://astro.build/config
export default defineConfig({
integrations: [
mdx(),
],
});
9 changes: 9 additions & 0 deletions packages/astro/e2e/fixtures/content-collections/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "@e2e/content-collections",
"version": "0.0.0",
"private": true,
"dependencies": {
"@astrojs/mdx": "workspace:*",
"astro": "workspace:*"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<h1 id="my-heading">
Some text here
</h1>


<style>
h1 {
color: red;
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
---

import MyComponent from '../../components/MyComponent.astro';

<MyComponent />
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
import { getEntryBySlug } from 'astro:content'
const post = await getEntryBySlug('posts', 'post-1')
const { Content } = await post.render();
---

<Content/>
28 changes: 22 additions & 6 deletions packages/astro/src/content/vite-plugin-content-assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,29 @@ export function astroContentAssetPropagationPlugin({
if (!devModuleLoader.getModuleById(basePath)?.ssrModule) {
await devModuleLoader.import(basePath);
}
const { styles, urls } = await getStylesForURL(pathToFileURL(basePath), devModuleLoader);
const {
styles,
urls,
crawledFiles: styleCrawledFiles,
} = await getStylesForURL(pathToFileURL(basePath), devModuleLoader);

const hoistedScripts = await getScriptsForURL(
pathToFileURL(basePath),
settings.config.root,
devModuleLoader
);
const { scripts: hoistedScripts, crawledFiles: scriptCrawledFiles } =
await getScriptsForURL(pathToFileURL(basePath), settings.config.root, devModuleLoader);

// Register files we crawled to be able to retrieve the rendered styles and scripts,
// as when they get updated, we need to re-transform ourselves.
// We also only watch files within the user source code, as changes in node_modules
// are usually also ignored by Vite.
for (const file of styleCrawledFiles) {
if (!file.includes('node_modules')) {
this.addWatchFile(file);
}
}
for (const file of scriptCrawledFiles) {
if (!file.includes('node_modules')) {
this.addWatchFile(file);
}
}

stringifiedLinks = JSON.stringify([...urls]);
stringifiedStyles = JSON.stringify(styles.map((s) => s.content));
Expand Down
1 change: 1 addition & 0 deletions packages/astro/src/core/module-loader/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export interface ModuleLoader {
export interface ModuleNode {
id: string | null;
url: string;
file: string | null;
ssrModule: Record<string, any> | null;
ssrTransformResult: {
deps?: string[];
Expand Down
7 changes: 6 additions & 1 deletion packages/astro/src/vite-plugin-astro-server/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@ interface ImportedStyle {
export async function getStylesForURL(
filePath: URL,
loader: ModuleLoader
): Promise<{ urls: Set<string>; styles: ImportedStyle[] }> {
): Promise<{ urls: Set<string>; styles: ImportedStyle[]; crawledFiles: Set<string> }> {
const importedCssUrls = new Set<string>();
// Map of url to injected style object. Use a `url` key to deduplicate styles
const importedStylesMap = new Map<string, ImportedStyle>();
const crawledFiles = new Set<string>();

for await (const importedModule of crawlGraph(loader, viteID(filePath), true)) {
if (importedModule.file) {
crawledFiles.add(importedModule.file);
}
if (isBuildableCSSRequest(importedModule.url)) {
// In dev, we inline all styles if possible
let css = '';
Expand Down Expand Up @@ -60,5 +64,6 @@ export async function getStylesForURL(
return {
urls: importedCssUrls,
styles: [...importedStylesMap.values()],
crawledFiles,
};
}
2 changes: 1 addition & 1 deletion packages/astro/src/vite-plugin-astro-server/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ async function getScriptsAndStyles({ pipeline, filePath }: GetScriptsAndStylesPa
const settings = pipeline.getSettings();
const mode = pipeline.getEnvironment().mode;
// Add hoisted script tags
const scripts = await getScriptsForURL(filePath, settings.config.root, moduleLoader);
const { scripts } = await getScriptsForURL(filePath, settings.config.root, moduleLoader);

// Inject HMR scripts
if (isPage(filePath, settings) && mode === 'development') {
Expand Down
8 changes: 6 additions & 2 deletions packages/astro/src/vite-plugin-astro-server/scripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,24 @@ export async function getScriptsForURL(
filePath: URL,
root: URL,
loader: ModuleLoader
): Promise<Set<SSRElement>> {
): Promise<{ scripts: Set<SSRElement>; crawledFiles: Set<string> }> {
const elements = new Set<SSRElement>();
const crawledFiles = new Set<string>();
const rootID = viteID(filePath);
const modInfo = loader.getModuleInfo(rootID);
addHoistedScripts(elements, modInfo, root);
for await (const moduleNode of crawlGraph(loader, rootID, true)) {
if (moduleNode.file) {
crawledFiles.add(moduleNode.file);
}
const id = moduleNode.id;
if (id) {
const info = loader.getModuleInfo(id);
addHoistedScripts(elements, info, root);
}
}

return elements;
return { scripts: elements, crawledFiles };
}

function addHoistedScripts(set: Set<SSRElement>, info: ModuleInfo | null, root: URL) {
Expand Down
9 changes: 9 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 81acac2

Please sign in to comment.