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"
},
"dependencies": {
"@astrojs/compiler": "^2.0.1",
"@astrojs/compiler": "^2.1.0",
"@astrojs/internal-helpers": "workspace:*",
"@astrojs/markdown-remark": "workspace:*",
"@astrojs/telemetry": "workspace:*",

View file

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

View file

@ -58,6 +58,15 @@ export default function configHeadVitePlugin(): vite.Plugin {
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)) {
propagateMetadata.call(this, id, 'propagation', 'in-tree');
}
@ -91,12 +100,23 @@ export function astroHeadBuildPlugin(internals: BuildInternals): AstroBuildPlugi
const modinfo = this.getModuleInfo(id);
// <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)) {
let metadata = getOrCreateMetadata(pageInfo.id);
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)
if (mod.code && injectExp.test(mod.code)) {

View file

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

View file

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