Merge branch 'main' into feat/squoosh-lib

This commit is contained in:
Tony Sullivan 2022-09-13 09:46:35 -05:00
commit 717785baa5
58 changed files with 628 additions and 299 deletions

View file

@ -0,0 +1,5 @@
---
'@astrojs/netlify': patch
---
Fix route validation failures on Netlify Edge

View file

@ -1,5 +0,0 @@
---
'@astrojs/vue': patch
---
Fix Vue `script setup` with other renderers applied

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Use import order to sort CSS in the build

View file

@ -1,4 +1,4 @@
name: CI name: Release
on: on:
push: push:

89
.github/workflows/snapshot-release.yml vendored Normal file
View file

@ -0,0 +1,89 @@
name: Create a Snapshot Release
on:
issue_comment:
types: [created]
defaults:
run:
shell: bash
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
FORCE_COLOR: true
jobs:
snapshot-release:
name: Create a snapshot release of a pull request
if: ${{ github.repository_owner == 'withastro' && github.event.issue.pull_request && startsWith(github.event.comment.body, '!preview') }}
runs-on: ubuntu-latest
steps:
- name: "Check if user has admin access (only admins can publish snapshot releases)."
uses: "lannonbr/repo-permission-check-action@2.0.0"
with:
permission: "admin"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Extract the snapshot name from comment body
id: getSnapshotName
uses: actions/github-script@v6
with:
script: |
const splitComment = context.payload.comment.body.split(' ');
splitComment.length !== 2 && (github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: 'Invalid comment format. Expected: "!preview <one-word-snapshot-name>"',
}) || core.setFailed('Invalid comment format. Expected: "!preview <one-word-snapshot-name>"'));
return splitComment[1].trim();
result-encoding: string
- uses: actions/checkout@v3
with:
ref: ${{ github.event.inputs.ref }}
- name: Setup PNPM
uses: pnpm/action-setup@v2.2.1
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 16
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Build Packages
run: pnpm run build
- name: Bump Package Versions
id: changesets
run: echo "::set-output name=result::$(npx changeset version --snapshot ${{ steps.getSnapshotName.outputs.result }})"
env:
# Needs access to run the script
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# - name: Publish Release
# id: publish
# run: echo "::set-output name=result::$(pnpm run release --tag next--${{ steps.getSnapshotName.outputs.result }})"
# env:
# # Needs access to publish to npm
# NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Pull Request Notification
uses: actions/github-script@v6
env:
MESSAGE: ${{ steps.changesets.outputs.result }}
with:
script: |
console.log(process.env.MESSAGE);
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '```\n' + process.env.MESSAGE + '\n```',
})

View file

@ -10,6 +10,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1" "astro": "^1.2.2"
} }
} }

View file

@ -10,9 +10,9 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1", "astro": "^1.2.2",
"@astrojs/mdx": "^0.11.1", "@astrojs/mdx": "^0.11.1",
"@astrojs/rss": "^1.0.0", "@astrojs/rss": "^1.0.1",
"@astrojs/sitemap": "^1.0.0" "@astrojs/sitemap": "^1.0.0"
} }
} }

View file

@ -15,9 +15,9 @@
], ],
"scripts": {}, "scripts": {},
"devDependencies": { "devDependencies": {
"astro": "^1.2.1" "astro": "^1.2.2"
}, },
"peerDependencies": { "peerDependencies": {
"astro": "^1.2.1" "astro": "^1.2.2"
} }
} }

View file

@ -11,7 +11,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1", "astro": "^1.2.2",
"preact": "^10.7.3", "preact": "^10.7.3",
"react": "^18.1.0", "react": "^18.1.0",
"react-dom": "^18.1.0", "react-dom": "^18.1.0",

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1", "astro": "^1.2.2",
"alpinejs": "^3.10.2", "alpinejs": "^3.10.2",
"@astrojs/alpinejs": "^0.1.2", "@astrojs/alpinejs": "^0.1.2",
"@types/alpinejs": "^3.7.0" "@types/alpinejs": "^3.7.0"

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1", "astro": "^1.2.2",
"lit": "^2.2.5", "lit": "^2.2.5",
"@astrojs/lit": "^1.0.0", "@astrojs/lit": "^1.0.0",
"@webcomponents/template-shadowroot": "^0.1.0" "@webcomponents/template-shadowroot": "^0.1.0"

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1", "astro": "^1.2.2",
"preact": "^10.7.3", "preact": "^10.7.3",
"react": "^18.1.0", "react": "^18.1.0",
"react-dom": "^18.1.0", "react-dom": "^18.1.0",
@ -21,6 +21,6 @@
"@astrojs/react": "^1.1.2", "@astrojs/react": "^1.1.2",
"@astrojs/solid-js": "^1.1.0", "@astrojs/solid-js": "^1.1.0",
"@astrojs/svelte": "^1.0.0", "@astrojs/svelte": "^1.0.0",
"@astrojs/vue": "^1.0.1" "@astrojs/vue": "^1.0.2"
} }
} }

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1", "astro": "^1.2.2",
"preact": "^10.7.3", "preact": "^10.7.3",
"@astrojs/preact": "^1.1.0" "@astrojs/preact": "^1.1.0"
} }

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1", "astro": "^1.2.2",
"react": "^18.1.0", "react": "^18.1.0",
"react-dom": "^18.1.0", "react-dom": "^18.1.0",
"@astrojs/react": "^1.1.2", "@astrojs/react": "^1.1.2",

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1", "astro": "^1.2.2",
"solid-js": "^1.4.3", "solid-js": "^1.4.3",
"@astrojs/solid-js": "^1.1.0" "@astrojs/solid-js": "^1.1.0"
} }

View file

@ -12,6 +12,6 @@
"dependencies": { "dependencies": {
"svelte": "^3.48.0", "svelte": "^3.48.0",
"@astrojs/svelte": "^1.0.0", "@astrojs/svelte": "^1.0.0",
"astro": "^1.2.1" "astro": "^1.2.2"
} }
} }

View file

@ -10,8 +10,8 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1", "astro": "^1.2.2",
"vue": "^3.2.37", "vue": "^3.2.37",
"@astrojs/vue": "^1.0.1" "@astrojs/vue": "^1.0.2"
} }
} }

View file

@ -10,6 +10,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1" "astro": "^1.2.2"
} }
} }

View file

@ -10,6 +10,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1" "astro": "^1.2.2"
} }
} }

View file

@ -10,6 +10,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1" "astro": "^1.2.2"
} }
} }

View file

@ -12,7 +12,7 @@
}, },
"devDependencies": {}, "devDependencies": {},
"dependencies": { "dependencies": {
"astro": "^1.2.1", "astro": "^1.2.2",
"svelte": "^3.48.0", "svelte": "^3.48.0",
"@astrojs/svelte": "^1.0.0", "@astrojs/svelte": "^1.0.0",
"@astrojs/node": "^1.0.1", "@astrojs/node": "^1.0.1",

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1", "astro": "^1.2.2",
"@astrojs/markdown-remark": "^1.1.0", "@astrojs/markdown-remark": "^1.1.0",
"hast-util-select": "5.0.1", "hast-util-select": "5.0.1",
"rehype-autolink-headings": "^6.1.1", "rehype-autolink-headings": "^6.1.1",

View file

@ -10,6 +10,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1" "astro": "^1.2.2"
} }
} }

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1", "astro": "^1.2.2",
"preact": "^10.6.5", "preact": "^10.6.5",
"@astrojs/preact": "^1.1.0", "@astrojs/preact": "^1.1.0",
"@astrojs/mdx": "^0.11.1" "@astrojs/mdx": "^0.11.1"

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1", "astro": "^1.2.2",
"preact": "^10.7.3", "preact": "^10.7.3",
"@astrojs/preact": "^1.1.0", "@astrojs/preact": "^1.1.0",
"nanostores": "^0.5.12", "nanostores": "^0.5.12",

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1", "astro": "^1.2.2",
"@astrojs/tailwind": "^1.0.0", "@astrojs/tailwind": "^1.0.0",
"autoprefixer": "^10.4.7", "autoprefixer": "^10.4.7",
"canvas-confetti": "^1.5.1", "canvas-confetti": "^1.5.1",

View file

@ -10,7 +10,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1", "astro": "^1.2.2",
"vite-plugin-pwa": "0.11.11", "vite-plugin-pwa": "0.11.11",
"workbox-window": "^6.5.3" "workbox-window": "^6.5.3"
} }

View file

@ -12,7 +12,7 @@
"test": "vitest" "test": "vitest"
}, },
"dependencies": { "dependencies": {
"astro": "^1.2.1", "astro": "^1.2.2",
"vitest": "^0.20.3" "vitest": "^0.20.3"
} }
} }

View file

@ -1,5 +1,11 @@
# @astrojs/rss # @astrojs/rss
## 1.0.1
### Patch Changes
- [#4701](https://github.com/withastro/astro/pull/4701) [`6e1d62fe2`](https://github.com/withastro/astro/commit/6e1d62fe222e45b763b2b60b377b07e431950d54) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Fix globs for homepage route
## 1.0.0 ## 1.0.0
### Major Changes ### Major Changes

View file

@ -1,7 +1,7 @@
{ {
"name": "@astrojs/rss", "name": "@astrojs/rss",
"description": "Add RSS feeds to your Astro projects", "description": "Add RSS feeds to your Astro projects",
"version": "1.0.0", "version": "1.0.1",
"type": "module", "type": "module",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
"author": "withastro", "author": "withastro",

View file

@ -56,7 +56,7 @@ function mapGlobResult(items: GlobResult): Promise<RSSFeedItem[]> {
return Promise.all( return Promise.all(
Object.values(items).map(async (getInfo) => { Object.values(items).map(async (getInfo) => {
const { url, frontmatter } = await getInfo(); const { url, frontmatter } = await getInfo();
if (!Boolean(url)) { if (url === undefined || url === null) {
throw new Error( throw new Error(
`[RSS] When passing an import.meta.glob result directly, you can only glob ".md" files within /pages! Consider mapping the result to an array of RSSFeedItems. See the RSS docs for usage examples: https://docs.astro.build/en/guides/rss/#2-list-of-rss-feed-objects` `[RSS] When passing an import.meta.glob result directly, you can only glob ".md" files within /pages! Consider mapping the result to an array of RSSFeedItems. See the RSS docs for usage examples: https://docs.astro.build/en/guides/rss/#2-list-of-rss-feed-objects`
); );

View file

@ -17,7 +17,8 @@ const phpFeedItem = {
}; };
const web1FeedItem = { const web1FeedItem = {
link: '/web1', // Should support empty string as a URL (possible for homepage route)
link: '',
title: 'Web 1.0', title: 'Web 1.0',
pubDate: '1997-05-03', pubDate: '1997-05-03',
description: description:
@ -26,7 +27,7 @@ const web1FeedItem = {
// note: I spent 30 minutes looking for a nice node-based snapshot tool // note: I spent 30 minutes looking for a nice node-based snapshot tool
// ...and I gave up. Enjoy big strings! // ...and I gave up. Enjoy big strings!
const validXmlResult = `<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title><![CDATA[My RSS feed]]></title><description><![CDATA[This sure is a nice RSS feed]]></description><link>https://example.com/</link><item><title><![CDATA[Remember PHP?]]></title><link>https://example.com/php/</link><guid>https://example.com/php/</guid><description><![CDATA[PHP is a general-purpose scripting language geared toward web development. It was originally created by Danish-Canadian programmer Rasmus Lerdorf in 1994.]]></description><pubDate>Tue, 03 May 1994 00:00:00 GMT</pubDate></item><item><title><![CDATA[Web 1.0]]></title><link>https://example.com/web1/</link><guid>https://example.com/web1/</guid><description><![CDATA[Web 1.0 is the term used for the earliest version of the Internet as it emerged from its origins with Defense Advanced Research Projects Agency (DARPA) and became, for the first time, a global network representing the future of digital communications.]]></description><pubDate>Sat, 03 May 1997 00:00:00 GMT</pubDate></item></channel></rss>`; const validXmlResult = `<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title><![CDATA[My RSS feed]]></title><description><![CDATA[This sure is a nice RSS feed]]></description><link>https://example.com/</link><item><title><![CDATA[Remember PHP?]]></title><link>https://example.com/php/</link><guid>https://example.com/php/</guid><description><![CDATA[PHP is a general-purpose scripting language geared toward web development. It was originally created by Danish-Canadian programmer Rasmus Lerdorf in 1994.]]></description><pubDate>Tue, 03 May 1994 00:00:00 GMT</pubDate></item><item><title><![CDATA[Web 1.0]]></title><link>https://example.com/</link><guid>https://example.com/</guid><description><![CDATA[Web 1.0 is the term used for the earliest version of the Internet as it emerged from its origins with Defense Advanced Research Projects Agency (DARPA) and became, for the first time, a global network representing the future of digital communications.]]></description><pubDate>Sat, 03 May 1997 00:00:00 GMT</pubDate></item></channel></rss>`;
describe('rss', () => { describe('rss', () => {
it('should generate on valid RSSFeedItem array', async () => { it('should generate on valid RSSFeedItem array', async () => {
@ -160,5 +161,45 @@ describe('rss', () => {
chai.expect(err.message).to.contain('Required field [link] is missing'); chai.expect(err.message).to.contain('Required field [link] is missing');
} }
}); });
it('should provide a good error message when passing glob result form outside pages/', async () => {
const globResult = {
'./posts/php.md': () =>
new Promise((resolve) =>
resolve({
// "undefined" when outside pages/
url: undefined,
frontmatter: {
title: phpFeedItem.title,
pubDate: phpFeedItem.pubDate,
description: phpFeedItem.description,
},
})
),
'./posts/nested/web1.md': () =>
new Promise((resolve) =>
resolve({
url: undefined,
frontmatter: {
title: web1FeedItem.title,
pubDate: web1FeedItem.pubDate,
description: web1FeedItem.description,
},
})
),
};
try {
await rss({
title: 'Your Website Title',
description: 'Your Website Description',
site: 'https://astro-demo',
items: globResult,
});
chai.expect(false).to.equal(true, 'Should have errored');
} catch (err) {
chai.expect(err.message).to.contain('you can only glob ".md" files within /pages');
}
});
}); });
}); });

View file

@ -1,5 +1,13 @@
# astro # astro
## 1.2.2
### Patch Changes
- [#4705](https://github.com/withastro/astro/pull/4705) [`5b6173fd0`](https://github.com/withastro/astro/commit/5b6173fd031b7e85974cbadd39de7fa199075e44) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Properly show an error message when a renderer is not properly configured
- [#4723](https://github.com/withastro/astro/pull/4723) [`0dba3b6f3`](https://github.com/withastro/astro/commit/0dba3b6f3fbd013f922fd11b9d6d977d165a512a) Thanks [@matthewp](https://github.com/matthewp)! - Makes the dev server more resilient to crashes
## 1.2.1 ## 1.2.1
### Patch Changes ### Patch Changes

View file

@ -1,6 +1,6 @@
{ {
"name": "astro", "name": "astro",
"version": "1.2.1", "version": "1.2.2",
"description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.", "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
"type": "module", "type": "module",
"author": "withastro", "author": "withastro",

View file

@ -7,19 +7,21 @@ export function* walkParentInfos(
id: string, id: string,
ctx: { getModuleInfo: GetModuleInfo }, ctx: { getModuleInfo: GetModuleInfo },
depth = 0, depth = 0,
seen = new Set<string>() seen = new Set<string>(),
): Generator<[ModuleInfo, number], void, unknown> { childId = ''
): Generator<[ModuleInfo, number, number], void, unknown> {
seen.add(id); seen.add(id);
const info = ctx.getModuleInfo(id); const info = ctx.getModuleInfo(id);
if (info) { if (info) {
yield [info, depth]; let order = childId ? info.importedIds.indexOf(childId) : 0;
yield [info, depth, order];
} }
const importers = (info?.importers || []).concat(info?.dynamicImporters || []); const importers = (info?.importers || []).concat(info?.dynamicImporters || []);
for (const imp of importers) { for (const imp of importers) {
if (seen.has(imp)) { if (seen.has(imp)) {
continue; continue;
} }
yield* walkParentInfos(imp, ctx, ++depth, seen); yield* walkParentInfos(imp, ctx, ++depth, seen, id);
} }
} }
@ -34,7 +36,7 @@ export function moduleIsTopLevelPage(info: ModuleInfo): boolean {
export function* getTopLevelPages( export function* getTopLevelPages(
id: string, id: string,
ctx: { getModuleInfo: GetModuleInfo } ctx: { getModuleInfo: GetModuleInfo }
): Generator<[ModuleInfo, number], void, unknown> { ): Generator<[ModuleInfo, number, number], void, unknown> {
for (const res of walkParentInfos(id, ctx)) { for (const res of walkParentInfos(id, ctx)) {
if (moduleIsTopLevelPage(res[0])) { if (moduleIsTopLevelPage(res[0])) {
yield res; yield res;

View file

@ -191,14 +191,26 @@ export function sortedCSS(pageData: PageBuildData) {
return Array.from(pageData.css) return Array.from(pageData.css)
.sort((a, b) => { .sort((a, b) => {
let depthA = a[1].depth, let depthA = a[1].depth,
depthB = b[1].depth; depthB = b[1].depth,
orderA = a[1].order,
orderB = b[1].order;
if (depthA === -1) { if (orderA === -1 && orderB >= 0) {
return -1;
} else if (depthB === -1) {
return 1; return 1;
} else if (orderB === -1 && orderA >= 0) {
return -1;
} else if (orderA > orderB) {
return 1;
} else if (orderA < orderB) {
return -1;
} else { } else {
return depthA > depthB ? -1 : 1; if (depthA === -1) {
return -1;
} else if (depthB === -1) {
return 1;
} else {
return depthA > depthB ? -1 : 1;
}
} }
}) })
.map(([id]) => id); .map(([id]) => id);

View file

@ -18,7 +18,7 @@ export interface PageBuildData {
component: ComponentPath; component: ComponentPath;
route: RouteData; route: RouteData;
moduleSpecifier: string; moduleSpecifier: string;
css: Map<string, { depth: number }>; css: Map<string, { depth: number; order: number }>;
hoistedScript: { type: 'inline' | 'external'; value: string } | undefined; hoistedScript: { type: 'inline' | 'external'; value: string } | undefined;
} }
export type AllPagesData = Record<ComponentPath, PageBuildData>; export type AllPagesData = Record<ComponentPath, PageBuildData>;

View file

@ -110,7 +110,12 @@ export function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[]
importedCss: Set<string>; importedCss: Set<string>;
}; };
const appendCSSToPage = (pageData: PageBuildData, meta: ViteMetadata, depth: number) => { const appendCSSToPage = (
pageData: PageBuildData,
meta: ViteMetadata,
depth: number,
order: number
) => {
for (const importedCssImport of meta.importedCss) { for (const importedCssImport of meta.importedCss) {
// CSS is prioritized based on depth. Shared CSS has a higher depth due to being imported by multiple pages. // CSS is prioritized based on depth. Shared CSS has a higher depth due to being imported by multiple pages.
// Depth info is used when sorting the links on the page. // Depth info is used when sorting the links on the page.
@ -120,8 +125,15 @@ export function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[]
if (depth < cssInfo.depth) { if (depth < cssInfo.depth) {
cssInfo.depth = depth; cssInfo.depth = depth;
} }
// Update the order, preferring the lowest order we have.
if (cssInfo.order === -1) {
cssInfo.order = order;
} else if (order < cssInfo.order && order > -1) {
cssInfo.order = order;
}
} else { } else {
pageData?.css.set(importedCssImport, { depth }); pageData?.css.set(importedCssImport, { depth, order });
} }
} }
}; };
@ -161,7 +173,7 @@ export function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[]
for (const id of Object.keys(c.modules)) { for (const id of Object.keys(c.modules)) {
for (const pageData of getParentClientOnlys(id, this)) { for (const pageData of getParentClientOnlys(id, this)) {
for (const importedCssImport of meta.importedCss) { for (const importedCssImport of meta.importedCss) {
pageData.css.set(importedCssImport, { depth: -1 }); pageData.css.set(importedCssImport, { depth: -1, order: -1 });
} }
} }
} }
@ -169,12 +181,12 @@ export function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[]
// For this CSS chunk, walk parents until you find a page. Add the CSS to that page. // For this CSS chunk, walk parents until you find a page. Add the CSS to that page.
for (const id of Object.keys(c.modules)) { for (const id of Object.keys(c.modules)) {
for (const [pageInfo, depth] of walkParentInfos(id, this)) { for (const [pageInfo, depth, order] of walkParentInfos(id, this)) {
if (moduleIsTopLevelPage(pageInfo)) { if (moduleIsTopLevelPage(pageInfo)) {
const pageViteID = pageInfo.id; const pageViteID = pageInfo.id;
const pageData = getPageDataByViteID(internals, pageViteID); const pageData = getPageDataByViteID(internals, pageViteID);
if (pageData) { if (pageData) {
appendCSSToPage(pageData, meta, depth); appendCSSToPage(pageData, meta, depth, order);
} }
} else if ( } else if (
options.target === 'client' && options.target === 'client' &&
@ -184,7 +196,7 @@ export function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[]
internals, internals,
pageInfo.id pageInfo.id
)) { )) {
appendCSSToPage(pageData, meta, -1); appendCSSToPage(pageData, meta, -1, order);
} }
} }
} }
@ -211,7 +223,7 @@ export function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[]
); );
if (cssChunk) { if (cssChunk) {
for (const pageData of eachPageData(internals)) { for (const pageData of eachPageData(internals)) {
pageData.css.set(cssChunk.fileName, { depth: -1 }); pageData.css.set(cssChunk.fileName, { depth: -1, order: -1 });
} }
} }
} }

View file

@ -48,7 +48,10 @@ export function cleanErrorStack(stack: string) {
export function fixViteErrorMessage(_err: unknown, server?: ViteDevServer, filePath?: URL) { export function fixViteErrorMessage(_err: unknown, server?: ViteDevServer, filePath?: URL) {
const err = createSafeError(_err); const err = createSafeError(_err);
// Vite will give you better stacktraces, using sourcemaps. // Vite will give you better stacktraces, using sourcemaps.
server?.ssrFixStacktrace(err); try {
server?.ssrFixStacktrace(err);
} catch {}
// Fix: Astro.glob() compiles to import.meta.glob() by the time Vite sees it, // Fix: Astro.glob() compiles to import.meta.glob() by the time Vite sees it,
// so we need to update this error message in case it originally came from Astro.glob(). // so we need to update this error message in case it originally came from Astro.glob().
if (err.message === 'import.meta.glob() can only accept string literals.') { if (err.message === 'import.meta.glob() can only accept string literals.') {
@ -57,14 +60,16 @@ export function fixViteErrorMessage(_err: unknown, server?: ViteDevServer, fileP
if (filePath && /failed to load module for ssr:/.test(err.message)) { if (filePath && /failed to load module for ssr:/.test(err.message)) {
const importName = err.message.split('for ssr:').at(1)?.trim(); const importName = err.message.split('for ssr:').at(1)?.trim();
if (importName) { if (importName) {
const content = fs.readFileSync(fileURLToPath(filePath)).toString(); try {
const lns = content.split('\n'); const content = fs.readFileSync(fileURLToPath(filePath)).toString();
const line = lns.findIndex((ln) => ln.includes(importName)); const lns = content.split('\n');
if (line == -1) return err; const line = lns.findIndex((ln) => ln.includes(importName));
const column = lns[line]?.indexOf(importName); if (line == -1) return err;
if (!(err as any).id) { const column = lns[line]?.indexOf(importName);
(err as any).id = `${fileURLToPath(filePath)}:${line + 1}:${column + 1}`; if (!(err as any).id) {
} (err as any).id = `${fileURLToPath(filePath)}:${line + 1}:${column + 1}`;
}
} catch {}
} }
} }
return err; return err;

View file

@ -66,6 +66,14 @@ export async function runHookConfigSetup({
config: updatedConfig, config: updatedConfig,
command, command,
addRenderer(renderer: AstroRenderer) { addRenderer(renderer: AstroRenderer) {
if (!renderer.name) {
throw new Error(`Integration ${bold(integration.name)} has an unnamed renderer.`);
}
if (!renderer.serverEntrypoint) {
throw new Error(`Renderer ${bold(renderer.name)} does not provide a serverEntrypoint.`);
}
updatedConfig._ctx.renderers.push(renderer); updatedConfig._ctx.renderers.push(renderer);
}, },
injectScript: (stage, content) => { injectScript: (stage, content) => {

View file

@ -20,7 +20,7 @@ import { preload, ssr } from '../core/render/dev/index.js';
import { RouteCache } from '../core/render/route-cache.js'; import { RouteCache } from '../core/render/route-cache.js';
import { createRequest } from '../core/request.js'; import { createRequest } from '../core/request.js';
import { createRouteManifest, matchAllRoutes } from '../core/routing/index.js'; import { createRouteManifest, matchAllRoutes } from '../core/routing/index.js';
import { createSafeError, resolvePages } from '../core/util.js'; import { resolvePages } from '../core/util.js';
import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js'; import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js';
interface AstroPluginOptions { interface AstroPluginOptions {
@ -348,7 +348,7 @@ async function handleRequest(
return await writeSSRResult(result, res); return await writeSSRResult(result, res);
} }
} catch (_err) { } catch (_err) {
const err = fixViteErrorMessage(createSafeError(_err), viteServer, filePath); const err = fixViteErrorMessage(_err, viteServer, filePath);
const errorWithMetadata = collectErrorMetadata(err); const errorWithMetadata = collectErrorMetadata(err);
error(logging, null, msg.formatErrorMessage(errorWithMetadata)); error(logging, null, msg.formatErrorMessage(errorWithMetadata));
handle500Response(viteServer, origin, req, res, errorWithMetadata); handle500Response(viteServer, origin, req, res, errorWithMetadata);

View file

@ -86,10 +86,25 @@ describe('CSS production ordering', () => {
getLinks(html).map((href) => getLinkContent(fixture, href)) getLinks(html).map((href) => getLinkContent(fixture, href))
); );
expect(content).to.have.a.lengthOf(2, 'there are 2 stylesheets'); expect(content).to.have.a.lengthOf(3, 'there are 3 stylesheets');
const [, last] = content; const [, found] = content;
expect(last.css).to.match(/#00f/); expect(found.css).to.match(/#00f/);
});
it('CSS injected by injectScript comes first because of import order', async () => {
let oneHtml = await fixture.readFile('/one/index.html');
let twoHtml = await fixture.readFile('/two/index.html');
let threeHtml = await fixture.readFile('/three/index.html');
for (const html of [oneHtml, twoHtml, threeHtml]) {
const content = await Promise.all(
getLinks(html).map((href) => getLinkContent(fixture, href))
);
const [first] = content;
expect(first.css).to.include('green', 'Came from the injected script');
}
}); });
}); });
}); });

View file

@ -0,0 +1,34 @@
import { expect } from 'chai';
import * as cheerio from 'cheerio';
import { loadFixture } from './test-utils.js';
describe('Errors in JavaScript', () => {
/** @type {import('./test-utils').Fixture} */
let fixture;
/** @type {import('./test-utils').DevServer} */
let devServer;
before(async () => {
fixture = await loadFixture({
root: './fixtures/error-bad-js',
});
devServer = await fixture.startDevServer();
});
after(async () => {
await devServer.stop();
});
it('Does not crash the dev server', async () => {
let res = await fixture.fetch('/');
let html = await res.text();
expect(html).to.include('ReferenceError');
res = await fixture.fetch('/');
await res.text();
expect(html).to.include('ReferenceError');
});
});

View file

@ -0,0 +1,14 @@
import { defineConfig } from 'astro/config';
export default defineConfig({
integrations: [
{
name: 'test-integration',
hooks: {
'astro:config:setup'({ injectScript }) {
injectScript('page-ssr', `import '/src/styles/base.css';`);
}
}
}
]
});

View file

@ -0,0 +1,14 @@
<html>
<head>
<title>Testing</title>
<style>
body {
margin: 2px;
color: blueviolet;
}
</style>
</head>
<body>
<h1>Testing</h1>
</body>
</html>

View file

@ -0,0 +1,3 @@
body {
background: green;
}

View file

@ -0,0 +1,3 @@
import { defineConfig } from 'astro/config';
export default defineConfig({});

View file

@ -0,0 +1,15 @@
{
"name": "@test/error-bad-js",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"astro": "workspace:*"
}
}

View file

@ -0,0 +1 @@
/// <reference types="astro/client" />

View file

@ -0,0 +1,16 @@
---
import something from '../something.js';
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Astro</h1>
</body>
</html>

View file

@ -0,0 +1 @@
export var foo = bar;

View file

@ -53,7 +53,10 @@ async function createEdgeManifest(routes: RouteData[], entryFile: string, dir: U
} else { } else {
functions.push({ functions.push({
function: entryFile, function: entryFile,
pattern: route.pattern.toString(), // Make route pattern serializable to match expected
// Netlify Edge validation format. Mirrors Netlify's own edge bundler:
// https://github.com/netlify/edge-bundler/blob/main/src/manifest.ts#L34
pattern: route.pattern.source.replace(/\\\//g, '/').toString(),
}); });
} }
} }

View file

@ -1,5 +1,11 @@
# @astrojs/vercel # @astrojs/vercel
## 2.0.0
### Major Changes
- [#4713](https://github.com/withastro/astro/pull/4713) [`16113c3ae`](https://github.com/withastro/astro/commit/16113c3ae2ebff96136ebd31958fc5eb4369ee0d) Thanks [@JuanM04](https://github.com/JuanM04)! - Use Edge Functions instead of Edge Middlewares
## 1.0.2 ## 1.0.2
### Patch Changes ### Patch Changes

View file

@ -1,7 +1,7 @@
{ {
"name": "@astrojs/vercel", "name": "@astrojs/vercel",
"description": "Deploy your site to Vercel", "description": "Deploy your site to Vercel",
"version": "1.0.2", "version": "2.0.0",
"type": "module", "type": "module",
"author": "withastro", "author": "withastro",
"license": "MIT", "license": "MIT",

View file

@ -68,7 +68,7 @@ export default function vercelEdge(): AstroIntegration {
routes: [ routes: [
...getRedirects(routes, _config), ...getRedirects(routes, _config),
{ handle: 'filesystem' }, { handle: 'filesystem' },
{ src: '/.*', middlewarePath: 'render' }, { src: '/.*', dest: 'render' },
], ],
}); });
}, },

View file

@ -1,5 +1,11 @@
# @astrojs/vue # @astrojs/vue
## 1.0.2
### Patch Changes
- [#4706](https://github.com/withastro/astro/pull/4706) [`b0ee81d0a`](https://github.com/withastro/astro/commit/b0ee81d0a70d8301530c321b670ab784c9bc00a2) Thanks [@bholmesdev](https://github.com/bholmesdev)! - Fix Vue `script setup` with other renderers applied
## 1.0.1 ## 1.0.1
### Patch Changes ### Patch Changes

View file

@ -1,6 +1,6 @@
{ {
"name": "@astrojs/vue", "name": "@astrojs/vue",
"version": "1.0.1", "version": "1.0.2",
"description": "Use Vue components within Astro", "description": "Use Vue components within Astro",
"type": "module", "type": "module",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",

File diff suppressed because it is too large Load diff