Fix importing CSS packages in frontmatter (#3537)
* Fix importing CSS packages in frontmatter * Formatting * Only update if the source code contains the import * Consolidate the two plugins * we do need a pre and a post * Adds a changeset
This commit is contained in:
parent
88974f8b40
commit
51c60de76c
7 changed files with 121 additions and 64 deletions
5
.changeset/green-ducks-reply.md
Normal file
5
.changeset/green-ducks-reply.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fixes imported CSS packages in frontmatter
|
|
@ -130,7 +130,7 @@
|
|||
"strip-ansi": "^7.0.1",
|
||||
"supports-esm": "^1.0.0",
|
||||
"tsconfig-resolver": "^3.0.1",
|
||||
"vite": "^2.9.9",
|
||||
"vite": "^2.9.10",
|
||||
"yargs-parser": "^21.0.1",
|
||||
"zod": "^3.17.3"
|
||||
},
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { GetModuleInfo, ModuleInfo } from 'rollup';
|
||||
import type { GetModuleInfo, ModuleInfo, OutputChunk } from 'rollup';
|
||||
import { BuildInternals } from '../core/build/internal';
|
||||
import type { PageBuildData } from '../core/build/types';
|
||||
|
||||
|
@ -76,25 +76,6 @@ export function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[]
|
|||
{
|
||||
name: CSS_PLUGIN_NAME,
|
||||
|
||||
configResolved(resolvedConfig) {
|
||||
// Our plugin needs to run before `vite:css-post` because we have to modify
|
||||
// The bundles before vite:css-post sees them. We can remove this code
|
||||
// after this bug is fixed: https://github.com/vitejs/vite/issues/8330
|
||||
const plugins = resolvedConfig.plugins as VitePlugin[];
|
||||
const viteCSSPostIndex = resolvedConfig.plugins.findIndex(
|
||||
(p) => p.name === 'vite:css-post'
|
||||
);
|
||||
if (viteCSSPostIndex !== -1) {
|
||||
// Move our plugin to be right before this one.
|
||||
const ourIndex = plugins.findIndex((p) => p.name === CSS_PLUGIN_NAME);
|
||||
const ourPlugin = plugins[ourIndex];
|
||||
|
||||
// Remove us from where we are now and place us right before the viteCSSPost plugin
|
||||
plugins.splice(ourIndex, 1);
|
||||
plugins.splice(viteCSSPostIndex - 1, 0, ourPlugin);
|
||||
}
|
||||
},
|
||||
|
||||
outputOptions(outputOptions) {
|
||||
const manualChunks = outputOptions.manualChunks || Function.prototype;
|
||||
outputOptions.manualChunks = function (id, ...args) {
|
||||
|
@ -157,21 +138,8 @@ export function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[]
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (chunk.type === 'chunk') {
|
||||
// This simply replaces single quotes with double quotes because the vite:css-post
|
||||
// plugin only works with single for some reason. This code can be removed
|
||||
// When the Vite bug is fixed: https://github.com/vitejs/vite/issues/8330
|
||||
const exp = new RegExp(
|
||||
`(\\bimport\\s*)[']([^']*(?:[a-z]+\.[0-9a-z]+\.m?js))['](;\n?)`,
|
||||
'g'
|
||||
);
|
||||
chunk.code = chunk.code.replace(exp, (_match, begin, chunkPath, end) => {
|
||||
return begin + '"' + chunkPath + '"' + end;
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
name: CSS_MINIFY_PLUGIN_NAME,
|
||||
|
@ -190,10 +158,40 @@ export function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[]
|
|||
});
|
||||
output.source = minifiedCSS;
|
||||
}
|
||||
} else if (output.type === 'chunk') {
|
||||
// vite:css-post removes "pure CSS" JavaScript chunks, that is chunks that only contain a comment
|
||||
// about it being a CSS module. We need to keep these chunks around because Astro
|
||||
// re-imports all modules as their namespace `import * as module1 from 'some/path';
|
||||
// in order to determine if one of them is a side-effectual web component.
|
||||
// If we ever get rid of that feature, the code below can be removed.
|
||||
for(const [imp, bindings] of Object.entries(output.importedBindings)) {
|
||||
if(imp.startsWith('chunks/') && !bundle[imp] && output.code.includes(imp)) {
|
||||
// This just creates an empty chunk module so that the main entry module
|
||||
// that is importing it doesn't break.
|
||||
const depChunk: OutputChunk = {
|
||||
type: 'chunk',
|
||||
fileName: imp,
|
||||
name: imp,
|
||||
facadeModuleId: imp,
|
||||
code: `/* Pure CSS chunk ${imp} */ ${bindings.map(b => `export const ${b} = {};`)}`,
|
||||
dynamicImports: [],
|
||||
implicitlyLoadedBefore: [],
|
||||
importedBindings: {},
|
||||
imports: [],
|
||||
referencedFiles: [],
|
||||
exports: Array.from(bindings),
|
||||
isDynamicEntry: false,
|
||||
isEntry: false,
|
||||
isImplicitEntry: false,
|
||||
modules: {},
|
||||
};
|
||||
bundle[imp] = depChunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
|
9
packages/astro/test/fixtures/fontsource-package/package.json
vendored
Normal file
9
packages/astro/test/fixtures/fontsource-package/package.json
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@test/astro-fontsource-package",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fontsource/montserrat": "4.5.11",
|
||||
"astro": "workspace:*"
|
||||
}
|
||||
}
|
13
packages/astro/test/fixtures/fontsource-package/src/pages/index.astro
vendored
Normal file
13
packages/astro/test/fixtures/fontsource-package/src/pages/index.astro
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
import "@fontsource/montserrat";
|
||||
---
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Astro</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Astro</h1>
|
||||
</body>
|
||||
</html>
|
20
packages/astro/test/fontsource.test.js
Normal file
20
packages/astro/test/fontsource.test.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { expect } from 'chai';
|
||||
import * as cheerio from 'cheerio';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
|
||||
describe('@fontsource/* packages', () => {
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({ root: './fixtures/fontsource-package/' });
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('can be imported in frontmatter', async () => {
|
||||
const html = await fixture.readFile('/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
const assetPath = $('link').attr('href');
|
||||
const css = await fixture.readFile(assetPath);
|
||||
expect(css).to.contain('Montserrat');
|
||||
});
|
||||
});
|
|
@ -542,7 +542,7 @@ importers:
|
|||
strip-ansi: ^7.0.1
|
||||
supports-esm: ^1.0.0
|
||||
tsconfig-resolver: ^3.0.1
|
||||
vite: ^2.9.9
|
||||
vite: ^2.9.10
|
||||
yargs-parser: ^21.0.1
|
||||
zod: ^3.17.3
|
||||
dependencies:
|
||||
|
@ -599,7 +599,7 @@ importers:
|
|||
strip-ansi: 7.0.1
|
||||
supports-esm: 1.0.0
|
||||
tsconfig-resolver: 3.0.1
|
||||
vite: 2.9.9_sass@1.52.2
|
||||
vite: 2.9.10_sass@1.52.2
|
||||
yargs-parser: 21.0.1
|
||||
zod: 3.17.3
|
||||
devDependencies:
|
||||
|
@ -1367,6 +1367,14 @@ importers:
|
|||
'@astrojs/vue': link:../../../../integrations/vue
|
||||
astro: link:../../..
|
||||
|
||||
packages/astro/test/fixtures/fontsource-package:
|
||||
specifiers:
|
||||
'@fontsource/montserrat': 4.5.11
|
||||
astro: workspace:*
|
||||
dependencies:
|
||||
'@fontsource/montserrat': 4.5.11
|
||||
astro: link:../../..
|
||||
|
||||
packages/astro/test/fixtures/legacy-build:
|
||||
specifiers:
|
||||
'@astrojs/vue': workspace:*
|
||||
|
@ -3895,6 +3903,10 @@ packages:
|
|||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@fontsource/montserrat/4.5.11:
|
||||
resolution: {integrity: sha512-XAYZmprnZDVSLIeEiB3evVG2JD+yoR9aT+I6LCOcwZFQ6ro9UPpopDncqoqwv+j5M0/UjyAP6ov70+L/fmP8Gg==}
|
||||
dev: false
|
||||
|
||||
/@formatjs/ecma402-abstract/1.11.4:
|
||||
resolution: {integrity: sha512-EBikYFp2JCdIfGEb5G9dyCkTGDmC57KSHhRQOC3aYxoPWVZvfWCDjZwkGYHN7Lis/fmuWl906bnNTJifDQ3sXw==}
|
||||
dependencies:
|
||||
|
@ -13592,6 +13604,31 @@ packages:
|
|||
- supports-color
|
||||
dev: true
|
||||
|
||||
/vite/2.9.10_sass@1.52.2:
|
||||
resolution: {integrity: sha512-TwZRuSMYjpTurLqXspct+HZE7ONiW9d+wSWgvADGxhDPPyoIcNywY+RX4ng+QpK30DCa1l/oZgi2PLZDibhzbQ==}
|
||||
engines: {node: '>=12.2.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
less: '*'
|
||||
sass: '*'
|
||||
stylus: '*'
|
||||
peerDependenciesMeta:
|
||||
less:
|
||||
optional: true
|
||||
sass:
|
||||
optional: true
|
||||
stylus:
|
||||
optional: true
|
||||
dependencies:
|
||||
esbuild: 0.14.42
|
||||
postcss: 8.4.14
|
||||
resolve: 1.22.0
|
||||
rollup: 2.75.5
|
||||
sass: 1.52.2
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
dev: false
|
||||
|
||||
/vite/2.9.9:
|
||||
resolution: {integrity: sha512-ffaam+NgHfbEmfw/Vuh6BHKKlI/XIAhxE5QSS7gFLIngxg171mg1P3a4LSRME0z2ZU1ScxoKzphkipcYwSD5Ew==}
|
||||
engines: {node: '>=12.2.0'}
|
||||
|
@ -13616,31 +13653,6 @@ packages:
|
|||
fsevents: 2.3.2
|
||||
dev: false
|
||||
|
||||
/vite/2.9.9_sass@1.52.2:
|
||||
resolution: {integrity: sha512-ffaam+NgHfbEmfw/Vuh6BHKKlI/XIAhxE5QSS7gFLIngxg171mg1P3a4LSRME0z2ZU1ScxoKzphkipcYwSD5Ew==}
|
||||
engines: {node: '>=12.2.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
less: '*'
|
||||
sass: '*'
|
||||
stylus: '*'
|
||||
peerDependenciesMeta:
|
||||
less:
|
||||
optional: true
|
||||
sass:
|
||||
optional: true
|
||||
stylus:
|
||||
optional: true
|
||||
dependencies:
|
||||
esbuild: 0.14.42
|
||||
postcss: 8.4.14
|
||||
resolve: 1.22.0
|
||||
rollup: 2.75.5
|
||||
sass: 1.52.2
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
dev: false
|
||||
|
||||
/vm2/3.9.9:
|
||||
resolution: {integrity: sha512-xwTm7NLh/uOjARRBs8/95H0e8fT3Ukw5D/JJWhxMbhKzNh1Nu981jQKvkep9iKYNxzlVrdzD0mlBGkDKZWprlw==}
|
||||
engines: {node: '>=6.0'}
|
||||
|
|
Loading…
Reference in a new issue