Fix multi-layout head injection (#8449)

* Fix multi-layout head injection

* Tracing fix

* Improved walk

* Upgrade the compiler version

---------

Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com>
This commit is contained in:
Matthew Phillips 2023-09-08 22:00:07 +08:00 committed by GitHub
parent 50c0a803e3
commit 7eea37a075
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 53 additions and 17 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fix multi-layout head injection

View file

@ -119,7 +119,7 @@
"test:e2e:match": "playwright test -g" "test:e2e:match": "playwright test -g"
}, },
"dependencies": { "dependencies": {
"@astrojs/compiler": "^2.0.1", "@astrojs/compiler": "^2.1.0",
"@astrojs/internal-helpers": "workspace:*", "@astrojs/internal-helpers": "workspace:*",
"@astrojs/markdown-remark": "workspace:*", "@astrojs/markdown-remark": "workspace:*",
"@astrojs/telemetry": "workspace:*", "@astrojs/telemetry": "workspace:*",

View file

@ -154,7 +154,7 @@ export default function astro({ settings, logger }: AstroPluginOptions): vite.Pl
hydratedComponents: transformResult.hydratedComponents, hydratedComponents: transformResult.hydratedComponents,
scripts: transformResult.scripts, scripts: transformResult.scripts,
containsHead: transformResult.containsHead, containsHead: transformResult.containsHead,
propagation: 'none', propagation: transformResult.propagation ? 'self' : 'none',
pageOptions: {}, pageOptions: {},
}; };

View file

@ -58,6 +58,15 @@ export default function configHeadVitePlugin(): vite.Plugin {
propagateMetadata.call(this, id, 'containsHead', true); propagateMetadata.call(this, id, 'containsHead', true);
} }
if(info && getAstroMetadata(info)?.propagation === 'self') {
const mod = server.moduleGraph.getModuleById(id);
for (const parent of mod?.importers ?? []) {
if(parent.id) {
propagateMetadata.call(this, parent.id, 'propagation', 'in-tree');
}
}
}
if (injectExp.test(source)) { if (injectExp.test(source)) {
propagateMetadata.call(this, id, 'propagation', 'in-tree'); propagateMetadata.call(this, id, 'propagation', 'in-tree');
} }
@ -91,12 +100,23 @@ export function astroHeadBuildPlugin(internals: BuildInternals): AstroBuildPlugi
const modinfo = this.getModuleInfo(id); const modinfo = this.getModuleInfo(id);
// <head> tag in the tree // <head> tag in the tree
if (modinfo && getAstroMetadata(modinfo)?.containsHead) { if(modinfo) {
const meta = getAstroMetadata(modinfo);
if(meta?.containsHead) {
for (const [pageInfo] of getTopLevelPages(id, this)) { for (const [pageInfo] of getTopLevelPages(id, this)) {
let metadata = getOrCreateMetadata(pageInfo.id); let metadata = getOrCreateMetadata(pageInfo.id);
metadata.containsHead = true; metadata.containsHead = true;
} }
} }
if(meta?.propagation === 'self') {
for (const [info] of walkParentInfos(id, this)) {
let metadata = getOrCreateMetadata(info.id);
if(metadata.propagation !== 'self') {
metadata.propagation = 'in-tree';
}
}
}
}
// Head propagation (aka bubbling) // Head propagation (aka bubbling)
if (mod.code && injectExp.test(mod.code)) { if (mod.code && injectExp.test(mod.code)) {

View file

@ -123,27 +123,38 @@ describe('head injection', () => {
}); });
} }
`.trim(), `.trim(),
'/src/components/Layout.astro': ` '/src/components/Content.astro': `
--- ---
import { renderEntry } from '../common/head.js'; import { renderEntry } from '../common/head.js';
const ExtraHead = renderEntry(); const ExtraHead = renderEntry();
--- ---
<ExtraHead />
`,
'/src/components/Inner.astro': `
---
import Content from './Content.astro';
---
<Content />
`,
'/src/components/Layout.astro': `
<html> <html>
<head> <head>
<title>Normal head stuff</title> <title>Normal head stuff</title>
</head> </head>
<body> <body>
<slot name="title" /> <slot name="title" />
<ExtraHead /> <slot name="inner" />
</body> </body>
</html> </html>
`, `,
'/src/pages/index.astro': ` '/src/pages/index.astro': `
--- ---
import Layout from '../components/Layout.astro'; import Layout from '../components/Layout.astro';
import Inner from '../components/Inner.astro';
--- ---
<Layout> <Layout>
<h1 slot="title">Test page</h1> <h1 slot="title">Test page</h1>
<Inner slot="inner" />
</Layout> </Layout>
`, `,
}, },
@ -168,8 +179,8 @@ describe('head injection', () => {
const html = await text(); const html = await text();
const $ = cheerio.load(html); const $ = cheerio.load(html);
expect($('link[rel=stylesheet][href="/some/fake/styles.css"]')).to.have.a.lengthOf(1); expect($('link[rel=stylesheet][href="/some/fake/styles.css"]')).to.have.a.lengthOf(1, 'found inner link');
expect($('#other')).to.have.a.lengthOf(1); expect($('#other')).to.have.a.lengthOf(1, 'Found the #other div');
} }
); );
}); });

View file

@ -483,8 +483,8 @@ importers:
packages/astro: packages/astro:
dependencies: dependencies:
'@astrojs/compiler': '@astrojs/compiler':
specifier: ^2.0.1 specifier: ^2.1.0
version: 2.0.1 version: 2.1.0
'@astrojs/internal-helpers': '@astrojs/internal-helpers':
specifier: workspace:* specifier: workspace:*
version: link:../internal-helpers version: link:../internal-helpers
@ -5180,8 +5180,8 @@ packages:
resolution: {integrity: sha512-o/ObKgtMzl8SlpIdzaxFnt7SATKPxu4oIP/1NL+HDJRzxfJcAkOTAb/ZKMRyULbz4q+1t2/DAebs2Z1QairkZw==} resolution: {integrity: sha512-o/ObKgtMzl8SlpIdzaxFnt7SATKPxu4oIP/1NL+HDJRzxfJcAkOTAb/ZKMRyULbz4q+1t2/DAebs2Z1QairkZw==}
dev: true dev: true
/@astrojs/compiler@2.0.1: /@astrojs/compiler@2.1.0:
resolution: {integrity: sha512-DfBR7Cf+tOgQ4n7TIgTtU5x5SEA/08DNshpEPcT+91A0KbBlmUOYMBM/O6qAaHkmVo1KIoXQYhAmfdTT1zx9PQ==} resolution: {integrity: sha512-Mp+qrNhly+27bL/Zq8lGeUY+YrdoU0eDfIlAeGIPrzt0PnI/jGpvPUdCaugv4zbCrDkOUScFfcbeEiYumrdJnw==}
dev: false dev: false
/@astrojs/language-server@2.3.0(prettier-plugin-astro@0.12.0)(prettier@3.0.3)(typescript@5.1.6): /@astrojs/language-server@2.3.0(prettier-plugin-astro@0.12.0)(prettier@3.0.3)(typescript@5.1.6):