diff --git a/.changeset/green-ducks-reply.md b/.changeset/green-ducks-reply.md new file mode 100644 index 000000000..20b00ddca --- /dev/null +++ b/.changeset/green-ducks-reply.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes imported CSS packages in frontmatter diff --git a/packages/astro/package.json b/packages/astro/package.json index 24fb9ac06..4a611ac0e 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -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" }, diff --git a/packages/astro/src/vite-plugin-build-css/index.ts b/packages/astro/src/vite-plugin-build-css/index.ts index a38ffc731..6656d350e 100644 --- a/packages/astro/src/vite-plugin-build-css/index.ts +++ b/packages/astro/src/vite-plugin-build-css/index.ts @@ -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; + } + } } } } - }, - }, + } + } ]; } diff --git a/packages/astro/test/fixtures/fontsource-package/package.json b/packages/astro/test/fixtures/fontsource-package/package.json new file mode 100644 index 000000000..2056d8447 --- /dev/null +++ b/packages/astro/test/fixtures/fontsource-package/package.json @@ -0,0 +1,9 @@ +{ + "name": "@test/astro-fontsource-package", + "version": "0.0.0", + "private": true, + "dependencies": { + "@fontsource/montserrat": "4.5.11", + "astro": "workspace:*" + } +} diff --git a/packages/astro/test/fixtures/fontsource-package/src/pages/index.astro b/packages/astro/test/fixtures/fontsource-package/src/pages/index.astro new file mode 100644 index 000000000..9c57bf10d --- /dev/null +++ b/packages/astro/test/fixtures/fontsource-package/src/pages/index.astro @@ -0,0 +1,13 @@ +--- +import "@fontsource/montserrat"; +--- + + + + + Astro + + +

Astro

+ + diff --git a/packages/astro/test/fontsource.test.js b/packages/astro/test/fontsource.test.js new file mode 100644 index 000000000..1c75d0125 --- /dev/null +++ b/packages/astro/test/fontsource.test.js @@ -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'); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e847f793f..e3ed897d2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -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'}