From 1c86c83c99b1bdbd1fe82303fa6044e9581a20a1 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 23 Apr 2022 08:47:52 -0400 Subject: [PATCH 01/27] remove built-in AMP support --- packages/kit/package.json | 5 +- packages/kit/rollup.config.js | 1 + packages/kit/src/amp.js | 29 ++ packages/kit/src/core/build/build_client.js | 9 +- packages/kit/src/core/build/build_server.js | 3 +- packages/kit/src/core/config/index.spec.js | 1 - packages/kit/src/core/config/options.js | 6 +- packages/kit/src/core/dev/amp_hook.js | 54 --- packages/kit/src/core/dev/index.js | 7 +- packages/kit/src/core/dev/plugin.js | 12 +- packages/kit/src/runtime/app/env.js | 4 - .../kit/src/runtime/server/page/render.js | 121 +++---- packages/kit/test/apps/amp/package.json | 1 + packages/kit/test/apps/amp/src/hooks.js | 26 ++ .../apps/amp/src/routes/styles/index.svelte | 6 +- .../apps/amp/src/routes/valid/index.svelte | 4 +- packages/kit/test/apps/amp/svelte.config.js | 12 +- packages/kit/test/apps/amp/test/test.js | 19 +- packages/kit/types/ambient.d.ts | 6 +- packages/kit/types/index.d.ts | 1 - packages/kit/types/internal.d.ts | 1 - pnpm-lock.yaml | 308 +++++++++++++++--- 22 files changed, 408 insertions(+), 228 deletions(-) create mode 100644 packages/kit/src/amp.js delete mode 100644 packages/kit/src/core/dev/amp_hook.js create mode 100644 packages/kit/test/apps/amp/src/hooks.js diff --git a/packages/kit/package.json b/packages/kit/package.json index 84871ac49bce..2ed72253b7a2 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -18,14 +18,12 @@ "devDependencies": { "@playwright/test": "^1.21.0", "@rollup/plugin-replace": "^4.0.0", - "@types/amphtml-validator": "^1.0.1", "@types/cookie": "^0.5.0", "@types/marked": "^4.0.1", "@types/mime": "^2.0.3", "@types/node": "^16.11.11", "@types/sade": "^1.7.3", "@types/set-cookie-parser": "^2.4.2", - "amphtml-validator": "^1.0.35", "cookie": "^0.5.0", "cross-env": "^7.0.3", "devalue": "^2.0.1", @@ -80,6 +78,9 @@ ".": { "types": "./types/index.d.ts" }, + "./amp": { + "import": "./dist/amp.js" + }, "./node": { "import": "./dist/node.js" }, diff --git a/packages/kit/rollup.config.js b/packages/kit/rollup.config.js index 6d4cf26498fb..2fa724b9a219 100644 --- a/packages/kit/rollup.config.js +++ b/packages/kit/rollup.config.js @@ -60,6 +60,7 @@ export default [ { input: { + amp: 'src/amp.js', cli: 'src/cli.js', node: 'src/node.js', hooks: 'src/hooks.js', diff --git a/packages/kit/src/amp.js b/packages/kit/src/amp.js new file mode 100644 index 000000000000..fcde0b2896f4 --- /dev/null +++ b/packages/kit/src/amp.js @@ -0,0 +1,29 @@ +// https://amp.dev/documentation/guides-and-tutorials/learn/spec/amp-boilerplate/ +const boilerplate = ` + + + `; + +/* +TODO not sure what to do about this +if (options.service_worker) { + head += + ''; + + body += ``; +} +*/ + +/** + * @param {string} html + */ +export function transform(html) { + // TODO + // * remove http-equiv + // * + // * probably lots of other stuff + return html + .replace(//, (match, $1) => ` - -

AMP validation failed

- - ${result.errors - .map( - (error) => ` -

${error.severity}

-

Line ${error.line}, column ${error.col}: ${error.message} (${ - error.code - })

-
${escape(lines[error.line - 1])}
- ` - ) - .join('\n\n')} - `; - } - - return new Response(rendered, { status: response.status, headers: response.headers }); -} diff --git a/packages/kit/src/core/dev/index.js b/packages/kit/src/core/dev/index.js index 14e35c234f26..a9df21306806 100644 --- a/packages/kit/src/core/dev/index.js +++ b/packages/kit/src/core/dev/index.js @@ -60,12 +60,7 @@ export async function dev({ cwd, port, host, https, config }) { plugins: [ svelte({ extensions: config.extensions, - // In AMP mode, we know that there are no conditional component imports. In that case, we - // don't need to include CSS for components that are imported but unused, so we can just - // include rendered CSS. - // This would also apply if hydrate and router are both false, but we don't know if one - // has been enabled at the page level, so we don't do anything there. - emitCss: !config.kit.amp, + emitCss: true, compilerOptions: { hydratable: !!config.kit.browser.hydrate } diff --git a/packages/kit/src/core/dev/plugin.js b/packages/kit/src/core/dev/plugin.js index d778fd28cf87..9a33dd1bfb4c 100644 --- a/packages/kit/src/core/dev/plugin.js +++ b/packages/kit/src/core/dev/plugin.js @@ -10,7 +10,6 @@ import { SVELTE_KIT_ASSETS } from '../constants.js'; import { get_mime_lookup, get_runtime_path, resolve_entry } from '../utils.js'; import { coalesce_to_error } from '../../utils/error.js'; import { load_template } from '../config/index.js'; -import { sequence } from '../../hooks.js'; import { posixify } from '../../utils/filesystem.js'; import { parse_route_id } from '../../utils/routing.js'; import { normalize_path } from '../../utils/url.js'; @@ -23,14 +22,6 @@ import { normalize_path } from '../../utils/url.js'; export async function create_plugin(config, cwd) { const runtime = get_runtime_path(config); - /** @type {import('types').Handle} */ - let amp; - - if (config.kit.amp) { - process.env.VITE_SVELTEKIT_AMP = 'true'; - amp = (await import('./amp_hook.js')).handle; - } - process.env.VITE_SVELTEKIT_APP_VERSION_POLL_INTERVAL = '0'; /** @type {import('types').Respond} */ @@ -222,7 +213,7 @@ export async function create_plugin(config, cwd) { /** @type {import('types').Hooks} */ const hooks = { getSession: user_hooks.getSession || (() => ({})), - handle: amp ? sequence(amp, handle) : handle, + handle, handleError: user_hooks.handleError || (({ /** @type {Error & { frame?: string }} */ error }) => { @@ -284,7 +275,6 @@ export async function create_plugin(config, cwd) { const rendered = await respond( request, { - amp: config.kit.amp, csp: config.kit.csp, dev: true, floc: config.kit.floc, diff --git a/packages/kit/src/runtime/app/env.js b/packages/kit/src/runtime/app/env.js index f422aa5091b3..0e868726bbc3 100644 --- a/packages/kit/src/runtime/app/env.js +++ b/packages/kit/src/runtime/app/env.js @@ -10,9 +10,5 @@ export const dev = !!import.meta.env.DEV; * @type {import('$app/env').mode} */ export const mode = import.meta.env.MODE; -/** - * @type {import('$app/env').amp} - */ -export const amp = !!import.meta.env.VITE_SVELTEKIT_AMP; export { prerendering } from '../env.js'; diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index b7ad8f862ca3..b21eccc723f3 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -186,95 +186,76 @@ export async function render_response({ } `; - if (options.amp) { - // inline_style contains CSS files (i.e. `import './styles.css'`) - // rendered.css contains the CSS from ` - - - - `; - - if (options.service_worker) { - head += - ''; - - body += ``; - } - } else { - if (inlined_style) { - const attributes = []; - if (options.dev) attributes.push(' data-sveltekit'); - if (csp.style_needs_nonce) attributes.push(` nonce="${csp.nonce}"`); + if (inlined_style) { + const attributes = []; + if (options.dev) attributes.push(' data-sveltekit'); + if (csp.style_needs_nonce) attributes.push(` nonce="${csp.nonce}"`); - csp.add_style(inlined_style); + csp.add_style(inlined_style); - head += `\n\t${inlined_style}`; - } + head += `\n\t${inlined_style}`; + } - // prettier-ignore - head += Array.from(stylesheets) - .map((dep) => { - const attributes = [ - 'rel="stylesheet"', - `href="${options.prefix + dep}"` - ]; + // prettier-ignore + head += Array.from(stylesheets) + .map((dep) => { + const attributes = [ + 'rel="stylesheet"', + `href="${options.prefix + dep}"` + ]; + + if (csp.style_needs_nonce) { + attributes.push(`nonce="${csp.nonce}"`); + } - if (csp.style_needs_nonce) { - attributes.push(`nonce="${csp.nonce}"`); - } + if (styles.has(dep)) { + // don't load stylesheets that are already inlined + // include them in disabled state so that Vite can detect them and doesn't try to add them + attributes.push('disabled', 'media="(max-width: 0)"'); + } - if (styles.has(dep)) { - // don't load stylesheets that are already inlined - // include them in disabled state so that Vite can detect them and doesn't try to add them - attributes.push('disabled', 'media="(max-width: 0)"'); - } + return `\n\t`; + }) + .join(''); - return `\n\t`; - }) + if (page_config.router || page_config.hydrate) { + head += Array.from(modulepreloads) + .map((dep) => `\n\t`) .join(''); - if (page_config.router || page_config.hydrate) { - head += Array.from(modulepreloads) - .map((dep) => `\n\t`) - .join(''); - - const attributes = ['type="module"', `data-hydrate="${target}"`]; + const attributes = ['type="module"', `data-hydrate="${target}"`]; - csp.add_script(init_app); + csp.add_script(init_app); - if (csp.script_needs_nonce) { - attributes.push(`nonce="${csp.nonce}"`); - } + if (csp.script_needs_nonce) { + attributes.push(`nonce="${csp.nonce}"`); + } - body += `\n\t\t`; + body += `\n\t\t`; - body += serialized_data - .map(({ url, body, response }) => - render_json_payload_script( - { type: 'data', url, body: typeof body === 'string' ? hash(body) : undefined }, - response - ) + body += serialized_data + .map(({ url, body, response }) => + render_json_payload_script( + { type: 'data', url, body: typeof body === 'string' ? hash(body) : undefined }, + response ) - .join('\n\t'); + ) + .join('\n\t'); - if (shadow_props) { - body += render_json_payload_script({ type: 'props' }, shadow_props); - } + if (shadow_props) { + body += render_json_payload_script({ type: 'props' }, shadow_props); } + } - if (options.service_worker) { - // always include service worker unless it's turned off explicitly - csp.add_script(init_service_worker); + if (options.service_worker) { + // always include service worker unless it's turned off explicitly + csp.add_script(init_service_worker); - head += ` - ${init_service_worker}`; - } + head += ` + ${init_service_worker}`; } - if (state.prerender && !options.amp) { + if (state.prerender) { const http_equiv = []; const csp_headers = csp.get_meta(); diff --git a/packages/kit/test/apps/amp/package.json b/packages/kit/test/apps/amp/package.json index 8cf523e3d410..35daa09815fc 100644 --- a/packages/kit/test/apps/amp/package.json +++ b/packages/kit/test/apps/amp/package.json @@ -14,6 +14,7 @@ "devDependencies": { "@sveltejs/kit": "workspace:*", "cross-env": "^7.0.3", + "purify-css": "^1.2.5", "svelte": "^3.43.0", "svelte-check": "^2.5.0", "typescript": "~4.6.2" diff --git a/packages/kit/test/apps/amp/src/hooks.js b/packages/kit/test/apps/amp/src/hooks.js new file mode 100644 index 000000000000..7307a31a03b7 --- /dev/null +++ b/packages/kit/test/apps/amp/src/hooks.js @@ -0,0 +1,26 @@ +import purify from 'purify-css'; +import * as amp from '../../../../src/amp.js'; + +/** @type {import('@sveltejs/kit').Handle} */ +export async function handle({ event, resolve }) { + const response = await resolve(event, { + transformPage: ({ html }) => { + html = amp.transform(html); + + // remove unused CSS + let css = ''; + const markup = html.replace( + /`; + } + ); + + css = purify(markup, css); + return markup.replace('', `${css}`); + } + }); + + return response; +} diff --git a/packages/kit/test/apps/amp/src/routes/styles/index.svelte b/packages/kit/test/apps/amp/src/routes/styles/index.svelte index 8d066cbe6ae5..08db544b1211 100644 --- a/packages/kit/test/apps/amp/src/routes/styles/index.svelte +++ b/packages/kit/test/apps/amp/src/routes/styles/index.svelte @@ -1,16 +1,14 @@ -{#if amp} +{#if Math.random() <= 1}

this text is rendered

{:else} - + {/if} - `) .replace(//g, '') + .replace(/]+>/g, (match) => { + if (/rel=('|")?stylesheet\1/.test(match)) { + if (/ disabled /.test(match)) return ''; + throw new Error( + 'An AMP document cannot contain — ensure that inlineStyleThreshold is set to Infinity, and remove links from your page template and elements' + ); + } + + return match; + }) .replace('', boilerplate + ''); + + return cleaned; } diff --git a/packages/kit/test/apps/amp/package.json b/packages/kit/test/apps/amp/package.json index 35daa09815fc..fc4d0808d1d6 100644 --- a/packages/kit/test/apps/amp/package.json +++ b/packages/kit/test/apps/amp/package.json @@ -19,5 +19,8 @@ "svelte-check": "^2.5.0", "typescript": "~4.6.2" }, - "type": "module" + "type": "module", + "dependencies": { + "amphtml-validator": "^1.0.35" + } } diff --git a/packages/kit/test/apps/amp/src/hooks.js b/packages/kit/test/apps/amp/src/hooks.js index 7307a31a03b7..3badcc62e08d 100644 --- a/packages/kit/test/apps/amp/src/hooks.js +++ b/packages/kit/test/apps/amp/src/hooks.js @@ -1,6 +1,9 @@ import purify from 'purify-css'; +import { getInstance } from 'amphtml-validator'; import * as amp from '../../../../src/amp.js'; +const validator = await getInstance(); + /** @type {import('@sveltejs/kit').Handle} */ export async function handle({ event, resolve }) { const response = await resolve(event, { @@ -18,7 +21,15 @@ export async function handle({ event, resolve }) { ); css = purify(markup, css); - return markup.replace('', `${css}`); + const purified = markup.replace('', `${css}`); + + const result = validator.validateString(purified); + + if (result.status === 'PASS') { + return purified; + } + + return JSON.stringify(result.errors); } }); diff --git a/packages/kit/test/apps/amp/svelte.config.js b/packages/kit/test/apps/amp/svelte.config.js index 1b57bf79677c..9c3a2801c70a 100644 --- a/packages/kit/test/apps/amp/svelte.config.js +++ b/packages/kit/test/apps/amp/svelte.config.js @@ -3,6 +3,11 @@ import path from 'path'; /** @type {import('@sveltejs/kit').Config} */ const config = { kit: { + browser: { + router: false, + hydrate: false + }, + inlineStyleThreshold: Infinity, vite: { diff --git a/packages/kit/test/apps/amp/test/test.js b/packages/kit/test/apps/amp/test/test.js index 647884b2fa38..5162912cdbe4 100644 --- a/packages/kit/test/apps/amp/test/test.js +++ b/packages/kit/test/apps/amp/test/test.js @@ -14,6 +14,14 @@ test('renders an AMP page', async ({ page, baseURL }) => { expect(await page.$('script[sveltekit\\:data-type="data"]')).toBeNull(); }); +test('prints validation errors', async ({ page, baseURL }) => { + await page.goto(`${baseURL}/invalid`); + + const body = await page.innerHTML('body'); + + expect(body).toContain("Invalid URL protocol 'javascript:' for attribute 'href' in tag 'a'"); +}); + test('styles are applied', async ({ page, baseURL }) => { await page.goto(`${baseURL}/valid`); @@ -56,6 +64,6 @@ test('throws error on encountering stylesheet links', async ({ page }) => { await page.goto('/invalid/has-stylesheet'); expect(await page.textContent('body')).toContain( - 'An AMP document cannot contain — make that inlineStyleThreshold is set to Infinity, and remove links from your page template and elements' + 'An AMP document cannot contain — ensure that inlineStyleThreshold is set to Infinity, and remove links from your page template and elements' ); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a65a8cfc6581..f2a5d5e949a8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -323,11 +323,14 @@ importers: packages/kit/test/apps/amp: specifiers: '@sveltejs/kit': workspace:* + amphtml-validator: ^1.0.35 cross-env: ^7.0.3 purify-css: ^1.2.5 svelte: ^3.43.0 svelte-check: ^2.5.0 typescript: ~4.6.2 + dependencies: + amphtml-validator: 1.0.35 devDependencies: '@sveltejs/kit': link:../../.. cross-env: 7.0.3 @@ -1873,6 +1876,15 @@ packages: uri-js: 4.4.1 dev: true + /amphtml-validator/1.0.35: + resolution: {integrity: sha512-C67JzC5EI6pE2C0sAo/zuCp8ARDl1Vtt6/s0nr+3NuXDNOdkjclZUkaNAd/ZnsEvvYodkXZ6T/uww890IQh9dQ==} + hasBin: true + dependencies: + colors: 1.4.0 + commander: 7.2.0 + promise: 8.1.0 + dev: false + /ansi-align/2.0.0: resolution: {integrity: sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=} dependencies: @@ -1980,6 +1992,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /asap/2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + dev: false + /atob/2.1.2: resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} engines: {node: '>= 4.5.0'} @@ -2273,13 +2289,17 @@ packages: /colors/1.4.0: resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} engines: {node: '>=0.1.90'} - dev: true /commander/4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} dev: true + /commander/7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + dev: false + /commander/8.3.0: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} @@ -4952,6 +4972,12 @@ packages: engines: {node: '>=0.4.0'} dev: true + /promise/8.1.0: + resolution: {integrity: sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==} + dependencies: + asap: 2.0.6 + dev: false + /prompts/2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} From 48dd2702ed90d705b0349d199effbf79fdfcbd21 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 18 May 2022 12:23:20 -0400 Subject: [PATCH 06/27] remove http-equiv tags --- packages/kit/src/amp.js | 7 ++++++- packages/kit/test/apps/amp/src/app.html | 2 +- .../amp/src/routes/http-equiv/cache-control.svelte | 14 ++++++++++++++ packages/kit/test/apps/amp/test/test.js | 9 +++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 packages/kit/test/apps/amp/src/routes/http-equiv/cache-control.svelte diff --git a/packages/kit/src/amp.js b/packages/kit/src/amp.js index 2617f06cc1d9..ec36103e730e 100644 --- a/packages/kit/src/amp.js +++ b/packages/kit/src/amp.js @@ -2,7 +2,8 @@ const boilerplate = ` - `; + +`; /* TODO not sure what to do about this @@ -35,6 +36,10 @@ export function transform(html) { return match; }) + .replace(/]+>/g, (match) => { + if (match.includes('http-equiv')) return ''; + return match; + }) .replace('', boilerplate + ''); return cleaned; diff --git a/packages/kit/test/apps/amp/src/app.html b/packages/kit/test/apps/amp/src/app.html index c462a30011e5..bfb96ec90242 100644 --- a/packages/kit/test/apps/amp/src/app.html +++ b/packages/kit/test/apps/amp/src/app.html @@ -3,7 +3,7 @@ - + %svelte.head% diff --git a/packages/kit/test/apps/amp/src/routes/http-equiv/cache-control.svelte b/packages/kit/test/apps/amp/src/routes/http-equiv/cache-control.svelte new file mode 100644 index 000000000000..6be73f14d259 --- /dev/null +++ b/packages/kit/test/apps/amp/src/routes/http-equiv/cache-control.svelte @@ -0,0 +1,14 @@ + + +

the cache-control headers should be removed from this page

diff --git a/packages/kit/test/apps/amp/test/test.js b/packages/kit/test/apps/amp/test/test.js index 5162912cdbe4..345bfa7f0992 100644 --- a/packages/kit/test/apps/amp/test/test.js +++ b/packages/kit/test/apps/amp/test/test.js @@ -67,3 +67,12 @@ test('throws error on encountering stylesheet links', async ({ page }) => { 'An AMP document cannot contain — ensure that inlineStyleThreshold is set to Infinity, and remove links from your page template and elements' ); }); + +test('http-equiv tags are removed', async ({ page }) => { + await page.goto('/http-equiv/cache-control'); + + expect(await page.textContent('h1')).toBe( + 'the cache-control headers should be removed from this page' + ); + expect(await page.innerHTML('head')).not.toContain('http-equiv="cache-control"'); +}); From e1c6edecfba70c9e1dbb3d5917c651d7339c0c5f Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 18 May 2022 12:34:05 -0400 Subject: [PATCH 07/27] docs --- documentation/docs/16-seo.md | 42 +++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/documentation/docs/16-seo.md b/documentation/docs/16-seo.md index c75e61864b79..0a850a25f415 100644 --- a/documentation/docs/16-seo.md +++ b/documentation/docs/16-seo.md @@ -22,7 +22,7 @@ SvelteKit redirects pathnames with trailing slashes to ones without (or vice ver ### Manual setup -#### <title> and <meta> +#### <title> and <meta> Every page should have well-written and unique `` and `<meta name="description">` elements inside a [`<svelte:head>`](https://svelte.dev/docs#template-syntax-svelte-head). Guidance on how to write descriptive titles and descriptions, along with other suggestions on making content understandable by search engines, can be found on Google's [Lighthouse SEO audits](https://web.dev/lighthouse-seo/) documentation. @@ -82,8 +82,40 @@ export async function get() { #### AMP -An unfortunate reality of modern web development is that it is sometimes necessary to create an [Accelerated Mobile Pages (AMP)](https://amp.dev/) version of your site. In SvelteKit this can be done by setting the [`amp`](/docs/configuration#amp) config option, which has the following effects: +An unfortunate reality of modern web development is that it is sometimes necessary to create an [Accelerated Mobile Pages (AMP)](https://amp.dev/) version of your site. In SvelteKit this can be done by enforcing the following [configuration](/docs/configuration) options... -- Client-side JavaScript, including the router, is disabled -- Styles are concatenated into `<style amp-custom>`, and the [AMP boilerplate](https://amp.dev/boilerplate/) is injected -- In development, requests are checked against the [AMP validator](https://validator.ampproject.org/) so you get early warning of any errors +```js +/// file: svelte.config.js +/** @type {import('@sveltejs/kit').Config} */ +const config = { + kit: { + // the combination of these options + // disables JavaScript + browser: { + hydrate: false, + router: false + }, + + // since <link rel="stylesheet"> isn't + // allowed, inline all styles + inlineStyleThreshold: Infinity + } +}; + +export default config; +``` + +...and transforming the HTML using `transformPage` along with `amp.transform` imported from `@sveltejs/kit/amp`: + +```js +import * as amp from '@sveltejs/kit/amp'; + +/** @type {import('@sveltejs/kit').Handle} */ +export async function handle({ event, resolve }) { + return resolve(event, { + transformPage: ({ html }) => amp.transform(html) + }); +} +``` + +> It's a good idea to use the `handle` hook to validate the transformed HTML using `amphtml-validator`, but only if you're prerendering pages since it's very slow. From 3612fe5d60323e130301c3fc67cba1c2f4aa9fb0 Mon Sep 17 00:00:00 2001 From: Rich Harris <hello@rich-harris.dev> Date: Wed, 18 May 2022 12:38:11 -0400 Subject: [PATCH 08/27] get docs to build --- packages/kit/types/ambient.d.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/kit/types/ambient.d.ts b/packages/kit/types/ambient.d.ts index 5d1e7da7ba10..8fc4d525709e 100644 --- a/packages/kit/types/ambient.d.ts +++ b/packages/kit/types/ambient.d.ts @@ -300,3 +300,10 @@ declare module '@sveltejs/kit/node' { ): Promise<Request>; export function setResponse(res: import('http').ServerResponse, response: Response): void; } + +/** + * Utilities for people who have to support AMP + */ +declare module '@sveltejs/kit/amp' { + export function transform(html: string): string; +} From 448e20ef1cb6a5ba21f78acbdc234745ee12c312 Mon Sep 17 00:00:00 2001 From: Rich Harris <hello@rich-harris.dev> Date: Wed, 18 May 2022 13:00:06 -0400 Subject: [PATCH 09/27] changeset --- .changeset/big-cups-exist.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/big-cups-exist.md diff --git a/.changeset/big-cups-exist.md b/.changeset/big-cups-exist.md new file mode 100644 index 000000000000..4859d353d2b9 --- /dev/null +++ b/.changeset/big-cups-exist.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +[breaking] remove amp config option in favour of amp.transform helper function From 5402ddd8aa3cfd972d227ed46605f642a7c8990b Mon Sep 17 00:00:00 2001 From: Rich Harris <hello@rich-harris.dev> Date: Thu, 19 May 2022 16:01:18 -0400 Subject: [PATCH 10/27] move amp stuff into separate package --- packages/{kit/src/amp.js => kit-amp/index.js} | 22 ++------------- packages/kit-amp/package.json | 27 +++++++++++++++++++ packages/kit/package.json | 3 --- packages/kit/rollup.config.js | 1 - packages/kit/test/apps/amp/package.json | 1 + packages/kit/test/apps/amp/src/hooks.js | 2 +- packages/kit/types/ambient.d.ts | 7 ----- pnpm-lock.yaml | 5 ++++ 8 files changed, 36 insertions(+), 32 deletions(-) rename packages/{kit/src/amp.js => kit-amp/index.js} (76%) create mode 100644 packages/kit-amp/package.json diff --git a/packages/kit/src/amp.js b/packages/kit-amp/index.js similarity index 76% rename from packages/kit/src/amp.js rename to packages/kit-amp/index.js index ec36103e730e..5b54cb8919db 100644 --- a/packages/kit/src/amp.js +++ b/packages/kit-amp/index.js @@ -5,25 +5,9 @@ const boilerplate = ` <script async src="https://cdn.ampproject.org/v0.js"></script> `; -/* -TODO not sure what to do about this -if (options.service_worker) { - head += - '<script async custom-element="amp-install-serviceworker" src="https://cdn.ampproject.org/v0/amp-install-serviceworker-0.1.js"></script>'; - - body += `<amp-install-serviceworker src="${options.service_worker}" layout="nodisplay"></amp-install-serviceworker>`; -} -*/ - -/** - * @param {string} html - */ +/** @param {string} html */ export function transform(html) { - // TODO - // * remove http-equiv - // * <amp-install-serviceworker> - // * probably lots of other stuff - const cleaned = html + return html .replace(/<style([^]+?)<\/style>/, (match, $1) => `<style amp-custom${$1}</style>`) .replace(/<script[^]+?<\/script>/g, '') .replace(/<link[^>]+>/g, (match) => { @@ -41,6 +25,4 @@ export function transform(html) { return match; }) .replace('</head>', boilerplate + '</head>'); - - return cleaned; } diff --git a/packages/kit-amp/package.json b/packages/kit-amp/package.json new file mode 100644 index 000000000000..d7bfdeedda4f --- /dev/null +++ b/packages/kit-amp/package.json @@ -0,0 +1,27 @@ +{ + "name": "@sveltejs/kit-amp", + "version": "1.0.0-next.0", + "repository": { + "type": "git", + "url": "https://github.com/sveltejs/kit", + "directory": "packages/adapter-auto" + }, + "license": "MIT", + "homepage": "https://kit.svelte.dev", + "type": "module", + "exports": { + ".": { + "import": "./index.js" + }, + "./package.json": "./package.json" + }, + "main": "index.js", + "files": [ + "index.js" + ], + "scripts": { + "lint": "eslint --ignore-path .gitignore \"**/*.{ts,js,svelte}\" && npm run check-format", + "format": "npm run check-format -- --write", + "check-format": "prettier --check . --config ../../.prettierrc --ignore-path .gitignore" + } +} diff --git a/packages/kit/package.json b/packages/kit/package.json index a1d66550c830..fe254de4a1df 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -80,9 +80,6 @@ ".": { "types": "./types/index.d.ts" }, - "./amp": { - "import": "./dist/amp.js" - }, "./node": { "import": "./dist/node.js" }, diff --git a/packages/kit/rollup.config.js b/packages/kit/rollup.config.js index 2fa724b9a219..6d4cf26498fb 100644 --- a/packages/kit/rollup.config.js +++ b/packages/kit/rollup.config.js @@ -60,7 +60,6 @@ export default [ { input: { - amp: 'src/amp.js', cli: 'src/cli.js', node: 'src/node.js', hooks: 'src/hooks.js', diff --git a/packages/kit/test/apps/amp/package.json b/packages/kit/test/apps/amp/package.json index fc4d0808d1d6..3d2fd00beb07 100644 --- a/packages/kit/test/apps/amp/package.json +++ b/packages/kit/test/apps/amp/package.json @@ -13,6 +13,7 @@ }, "devDependencies": { "@sveltejs/kit": "workspace:*", + "@sveltejs/kit-amp": "workspace:*", "cross-env": "^7.0.3", "purify-css": "^1.2.5", "svelte": "^3.43.0", diff --git a/packages/kit/test/apps/amp/src/hooks.js b/packages/kit/test/apps/amp/src/hooks.js index 3badcc62e08d..999661120e7c 100644 --- a/packages/kit/test/apps/amp/src/hooks.js +++ b/packages/kit/test/apps/amp/src/hooks.js @@ -1,6 +1,6 @@ import purify from 'purify-css'; import { getInstance } from 'amphtml-validator'; -import * as amp from '../../../../src/amp.js'; +import * as amp from '@sveltejs/kit-amp'; const validator = await getInstance(); diff --git a/packages/kit/types/ambient.d.ts b/packages/kit/types/ambient.d.ts index 8fc4d525709e..5d1e7da7ba10 100644 --- a/packages/kit/types/ambient.d.ts +++ b/packages/kit/types/ambient.d.ts @@ -300,10 +300,3 @@ declare module '@sveltejs/kit/node' { ): Promise<Request>; export function setResponse(res: import('http').ServerResponse, response: Response): void; } - -/** - * Utilities for people who have to support AMP - */ -declare module '@sveltejs/kit/amp' { - export function transform(html: string): string; -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 88cbcbf6b45c..402937ff3d9e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -322,9 +322,13 @@ importers: typescript: 4.6.4 uvu: 0.5.2 + packages/kit-amp: + specifiers: {} + packages/kit/test/apps/amp: specifiers: '@sveltejs/kit': workspace:* + '@sveltejs/kit-amp': workspace:* amphtml-validator: ^1.0.35 cross-env: ^7.0.3 purify-css: ^1.2.5 @@ -335,6 +339,7 @@ importers: amphtml-validator: 1.0.35 devDependencies: '@sveltejs/kit': link:../../.. + '@sveltejs/kit-amp': link:../../../../kit-amp cross-env: 7.0.3 purify-css: 1.2.5 svelte: 3.44.2 From 7a6a4819d094873bb52dfd5cfa0d2b4456ce9ec4 Mon Sep 17 00:00:00 2001 From: Rich Harris <richard.a.harris@gmail.com> Date: Thu, 19 May 2022 16:01:57 -0400 Subject: [PATCH 11/27] Update documentation/docs/16-seo.md Co-authored-by: Conduitry <git@chor.date> --- documentation/docs/16-seo.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/16-seo.md b/documentation/docs/16-seo.md index 0a850a25f415..e2f732c018e3 100644 --- a/documentation/docs/16-seo.md +++ b/documentation/docs/16-seo.md @@ -105,7 +105,7 @@ const config = { export default config; ``` -...and transforming the HTML using `transformPage` along with `amp.transform` imported from `@sveltejs/kit/amp`: +...and transforming the HTML using `transformPage` along with `transform` imported from `@sveltejs/kit/amp`: ```js import * as amp from '@sveltejs/kit/amp'; From 8b1a6060dae2eafe8be126d129e90f41e86b9d9e Mon Sep 17 00:00:00 2001 From: Rich Harris <hello@rich-harris.dev> Date: Thu, 19 May 2022 16:02:26 -0400 Subject: [PATCH 12/27] update docs --- documentation/docs/16-seo.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/docs/16-seo.md b/documentation/docs/16-seo.md index e2f732c018e3..73c73a9d5df5 100644 --- a/documentation/docs/16-seo.md +++ b/documentation/docs/16-seo.md @@ -105,10 +105,10 @@ const config = { export default config; ``` -...and transforming the HTML using `transformPage` along with `transform` imported from `@sveltejs/kit/amp`: +...and transforming the HTML using `transformPage` along with `transform` imported from `@sveltejs/kit-amp`: ```js -import * as amp from '@sveltejs/kit/amp'; +import * as amp from '@sveltejs/kit-amp'; /** @type {import('@sveltejs/kit').Handle} */ export async function handle({ event, resolve }) { From af281a43f72973dda533c9e3564b0d40c6688394 Mon Sep 17 00:00:00 2001 From: Rich Harris <hello@rich-harris.dev> Date: Thu, 19 May 2022 16:04:58 -0400 Subject: [PATCH 13/27] lint --- packages/adapter-vercel/index.js | 4 +++- packages/kit-amp/.gitignore | 0 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 packages/kit-amp/.gitignore diff --git a/packages/adapter-vercel/index.js b/packages/adapter-vercel/index.js index 6c89940d8952..fe9e3a55a7c1 100644 --- a/packages/adapter-vercel/index.js +++ b/packages/adapter-vercel/index.js @@ -405,7 +405,9 @@ function get_node_version() { const major = parseInt(full.split('.')[0]); // '16.5.0' --> 16 if (major < 16) { - throw new Error(`SvelteKit only supports Node.js version 16 or greater (currently using v${full}). Consult the documentation: https://vercel.com/docs/runtimes#official-runtimes/node-js/node-js-version`) + throw new Error( + `SvelteKit only supports Node.js version 16 or greater (currently using v${full}). Consult the documentation: https://vercel.com/docs/runtimes#official-runtimes/node-js/node-js-version` + ); } return { major, full }; diff --git a/packages/kit-amp/.gitignore b/packages/kit-amp/.gitignore new file mode 100644 index 000000000000..e69de29bb2d1 From 285fa25f94ed2dc413161928970e70924dfd2482 Mon Sep 17 00:00:00 2001 From: Rich Harris <hello@rich-harris.dev> Date: Thu, 19 May 2022 16:11:56 -0400 Subject: [PATCH 14/27] get site to build --- packages/kit-amp/index.d.ts | 1 + packages/kit-amp/package.json | 1 + pnpm-lock.yaml | 2 ++ sites/kit.svelte.dev/package.json | 1 + 4 files changed, 5 insertions(+) create mode 100644 packages/kit-amp/index.d.ts diff --git a/packages/kit-amp/index.d.ts b/packages/kit-amp/index.d.ts new file mode 100644 index 000000000000..475cec2b75c3 --- /dev/null +++ b/packages/kit-amp/index.d.ts @@ -0,0 +1 @@ +export function transform(html: string): string; diff --git a/packages/kit-amp/package.json b/packages/kit-amp/package.json index d7bfdeedda4f..efd6e41cfdb4 100644 --- a/packages/kit-amp/package.json +++ b/packages/kit-amp/package.json @@ -16,6 +16,7 @@ "./package.json": "./package.json" }, "main": "index.js", + "types": "index.d.ts", "files": [ "index.js" ], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 402937ff3d9e..c1ddfcdcf9ba 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -465,6 +465,7 @@ importers: '@sveltejs/adapter-auto': workspace:* '@sveltejs/adapter-static': workspace:* '@sveltejs/kit': workspace:* + '@sveltejs/kit-amp': workspace:* '@sveltejs/site-kit': ^2.1.0 '@types/node': ^16.11.11 flexsearch: ^0.7.21 @@ -480,6 +481,7 @@ importers: '@sveltejs/adapter-auto': link:../../packages/adapter-auto '@sveltejs/adapter-static': link:../../packages/adapter-static '@sveltejs/kit': link:../../packages/kit + '@sveltejs/kit-amp': link:../../packages/kit-amp '@sveltejs/site-kit': 2.1.0 '@types/node': 16.11.11 flexsearch: 0.7.21 diff --git a/sites/kit.svelte.dev/package.json b/sites/kit.svelte.dev/package.json index 8f75148b2f05..109ae77b92fd 100644 --- a/sites/kit.svelte.dev/package.json +++ b/sites/kit.svelte.dev/package.json @@ -11,6 +11,7 @@ "@sveltejs/adapter-auto": "workspace:*", "@sveltejs/adapter-static": "workspace:*", "@sveltejs/kit": "workspace:*", + "@sveltejs/kit-amp": "workspace:*", "@sveltejs/site-kit": "^2.1.0", "@types/node": "^16.11.11", "flexsearch": "^0.7.21", From 19fbfb7a15d59a78bb9ee6a2a6c9ae28b8be99e6 Mon Sep 17 00:00:00 2001 From: Rich Harris <hello@rich-harris.dev> Date: Thu, 19 May 2022 16:38:54 -0400 Subject: [PATCH 15/27] disable side-effects-cache --- .npmrc | 1 + 1 file changed, 1 insertion(+) diff --git a/.npmrc b/.npmrc index d7445a115f87..fdc5b9933a7a 100644 --- a/.npmrc +++ b/.npmrc @@ -1,2 +1,3 @@ link-workspace-packages = true engine-strict = true +side-effects-cache = false \ No newline at end of file From d0ffad5209fbfa951ee67d8d16e2dec8048c2195 Mon Sep 17 00:00:00 2001 From: Rich Harris <hello@rich-harris.dev> Date: Thu, 19 May 2022 17:04:50 -0400 Subject: [PATCH 16/27] good riddance to amphtml-validator --- packages/kit/test/apps/amp/package.json | 5 +--- packages/kit/test/apps/amp/src/hooks.js | 13 +-------- packages/kit/test/apps/amp/test/test.js | 35 ++++++++++++++----------- 3 files changed, 21 insertions(+), 32 deletions(-) diff --git a/packages/kit/test/apps/amp/package.json b/packages/kit/test/apps/amp/package.json index 3d2fd00beb07..9dd5f7c6af2e 100644 --- a/packages/kit/test/apps/amp/package.json +++ b/packages/kit/test/apps/amp/package.json @@ -20,8 +20,5 @@ "svelte-check": "^2.5.0", "typescript": "~4.6.2" }, - "type": "module", - "dependencies": { - "amphtml-validator": "^1.0.35" - } + "type": "module" } diff --git a/packages/kit/test/apps/amp/src/hooks.js b/packages/kit/test/apps/amp/src/hooks.js index 999661120e7c..98a2e9bdaaff 100644 --- a/packages/kit/test/apps/amp/src/hooks.js +++ b/packages/kit/test/apps/amp/src/hooks.js @@ -1,9 +1,6 @@ import purify from 'purify-css'; -import { getInstance } from 'amphtml-validator'; import * as amp from '@sveltejs/kit-amp'; -const validator = await getInstance(); - /** @type {import('@sveltejs/kit').Handle} */ export async function handle({ event, resolve }) { const response = await resolve(event, { @@ -21,15 +18,7 @@ export async function handle({ event, resolve }) { ); css = purify(markup, css); - const purified = markup.replace('</style>', `${css}</style>`); - - const result = validator.validateString(purified); - - if (result.status === 'PASS') { - return purified; - } - - return JSON.stringify(result.errors); + return markup.replace('</style>', `${css}</style>`); } }); diff --git a/packages/kit/test/apps/amp/test/test.js b/packages/kit/test/apps/amp/test/test.js index 345bfa7f0992..2497cee43b86 100644 --- a/packages/kit/test/apps/amp/test/test.js +++ b/packages/kit/test/apps/amp/test/test.js @@ -14,14 +14,6 @@ test('renders an AMP page', async ({ page, baseURL }) => { expect(await page.$('script[sveltekit\\:data-type="data"]')).toBeNull(); }); -test('prints validation errors', async ({ page, baseURL }) => { - await page.goto(`${baseURL}/invalid`); - - const body = await page.innerHTML('body'); - - expect(body).toContain("Invalid URL protocol 'javascript:' for attribute 'href' in tag 'a'"); -}); - test('styles are applied', async ({ page, baseURL }) => { await page.goto(`${baseURL}/valid`); @@ -60,14 +52,6 @@ test('only includes CSS for rendered components', async ({ page, baseURL }) => { expect(style).not.toContain('#40b3ff'); // unrendered styles }); -test('throws error on encountering stylesheet links', async ({ page }) => { - await page.goto('/invalid/has-stylesheet'); - - expect(await page.textContent('body')).toContain( - 'An AMP document cannot contain <link rel="stylesheet"> — ensure that inlineStyleThreshold is set to Infinity, and remove links from your page template and <svelte:head> elements' - ); -}); - test('http-equiv tags are removed', async ({ page }) => { await page.goto('/http-equiv/cache-control'); @@ -76,3 +60,22 @@ test('http-equiv tags are removed', async ({ page }) => { ); expect(await page.innerHTML('head')).not.toContain('http-equiv="cache-control"'); }); + +// validation tests are skipped because amphtml-validator doesn't +// play nicely with CI, and is also abominably slow, because +// everything AMP-related is awful +test.skip('prints validation errors', async ({ page, baseURL }) => { + await page.goto(`${baseURL}/invalid`); + + const body = await page.innerHTML('body'); + + expect(body).toContain("Invalid URL protocol 'javascript:' for attribute 'href' in tag 'a'"); +}); + +test.skip('throws error on encountering stylesheet links', async ({ page }) => { + await page.goto('/invalid/has-stylesheet'); + + expect(await page.textContent('body')).toContain( + 'An AMP document cannot contain <link rel="stylesheet"> — ensure that inlineStyleThreshold is set to Infinity, and remove links from your page template and <svelte:head> elements' + ); +}); From e392f2e98bb5497dec42e0a60660bf9a2888e100 Mon Sep 17 00:00:00 2001 From: Rich Harris <hello@rich-harris.dev> Date: Thu, 19 May 2022 17:08:18 -0400 Subject: [PATCH 17/27] goddammit --- pnpm-lock.yaml | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c1ddfcdcf9ba..55d3ef589dfd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -329,14 +329,11 @@ importers: specifiers: '@sveltejs/kit': workspace:* '@sveltejs/kit-amp': workspace:* - amphtml-validator: ^1.0.35 cross-env: ^7.0.3 purify-css: ^1.2.5 svelte: ^3.43.0 svelte-check: ^2.5.0 typescript: ~4.6.2 - dependencies: - amphtml-validator: 1.0.35 devDependencies: '@sveltejs/kit': link:../../.. '@sveltejs/kit-amp': link:../../../../kit-amp @@ -1894,15 +1891,6 @@ packages: uri-js: 4.4.1 dev: true - /amphtml-validator/1.0.35: - resolution: {integrity: sha512-C67JzC5EI6pE2C0sAo/zuCp8ARDl1Vtt6/s0nr+3NuXDNOdkjclZUkaNAd/ZnsEvvYodkXZ6T/uww890IQh9dQ==} - hasBin: true - dependencies: - colors: 1.4.0 - commander: 7.2.0 - promise: 8.1.0 - dev: false - /ansi-align/2.0.0: resolution: {integrity: sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=} dependencies: @@ -2010,10 +1998,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /asap/2.0.6: - resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} - dev: false - /atob/2.1.2: resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} engines: {node: '>= 4.5.0'} @@ -2307,17 +2291,13 @@ packages: /colors/1.4.0: resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} engines: {node: '>=0.1.90'} + dev: true /commander/4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} dev: true - /commander/7.2.0: - resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} - engines: {node: '>= 10'} - dev: false - /commander/8.3.0: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} @@ -4998,12 +4978,6 @@ packages: engines: {node: '>=0.4.0'} dev: true - /promise/8.1.0: - resolution: {integrity: sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==} - dependencies: - asap: 2.0.6 - dev: false - /prompts/2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} From baa0fe8c07f9b86000ec246b345108ccd8a6efa9 Mon Sep 17 00:00:00 2001 From: Rich Harris <hello@rich-harris.dev> Date: Thu, 19 May 2022 17:12:51 -0400 Subject: [PATCH 18/27] goodbye, thanks for nothing --- .npmrc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.npmrc b/.npmrc index fdc5b9933a7a..f349fc7c9bf1 100644 --- a/.npmrc +++ b/.npmrc @@ -1,3 +1,2 @@ link-workspace-packages = true -engine-strict = true -side-effects-cache = false \ No newline at end of file +engine-strict = true \ No newline at end of file From 27ccc8190eafdbf1b3fede6ee39a9be6453c13ae Mon Sep 17 00:00:00 2001 From: Rich Harris <hello@rich-harris.dev> Date: Thu, 19 May 2022 17:20:47 -0400 Subject: [PATCH 19/27] bypass turbo for a second --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index de108360f650..8ad86da0d011 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "private": true, "scripts": { "build": "turbo run build", - "test": "turbo run test", + "test": "pnpm -r test", "check": "turbo run check", "lint": "turbo run lint", "format": "turbo run format", From ad66d264db203361c5daf7731b183844c7613542 Mon Sep 17 00:00:00 2001 From: Rich Harris <hello@rich-harris.dev> Date: Thu, 19 May 2022 17:27:04 -0400 Subject: [PATCH 20/27] remove rimraf for a second --- package.json | 2 +- packages/kit/src/core/sync/write_types.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 8ad86da0d011..de108360f650 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "private": true, "scripts": { "build": "turbo run build", - "test": "pnpm -r test", + "test": "turbo run test", "check": "turbo run check", "lint": "turbo run lint", "format": "turbo run format", diff --git a/packages/kit/src/core/sync/write_types.js b/packages/kit/src/core/sync/write_types.js index 01f129aa8e37..de331b20f154 100644 --- a/packages/kit/src/core/sync/write_types.js +++ b/packages/kit/src/core/sync/write_types.js @@ -23,7 +23,7 @@ export type Load< * @param {import('types').ManifestData} manifest_data */ export function write_types(config, manifest_data) { - rimraf(`${config.kit.outDir}/types`); + // rimraf(`${config.kit.outDir}/types`); /** @type {Map<string, { params: string[], type: 'page' | 'endpoint' | 'both' }>} */ const shadow_types = new Map(); From d7ee9ab119812664943d855cac576aed9efaae4c Mon Sep 17 00:00:00 2001 From: Rich Harris <hello@rich-harris.dev> Date: Thu, 19 May 2022 17:35:16 -0400 Subject: [PATCH 21/27] maybe this will please the windows gods --- packages/kit/src/utils/filesystem.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/kit/src/utils/filesystem.js b/packages/kit/src/utils/filesystem.js index fbc201f401bc..ac3811ef4c93 100644 --- a/packages/kit/src/utils/filesystem.js +++ b/packages/kit/src/utils/filesystem.js @@ -13,6 +13,7 @@ export function mkdirp(dir) { /** @param {string} path */ export function rimraf(path) { + if (!fs.existsSync(path)) return; (fs.rmSync || fs.rmdirSync)(path, { recursive: true, force: true }); } From 9093045c642011e7ef22b028157c6bbb13d88126 Mon Sep 17 00:00:00 2001 From: Rich Harris <hello@rich-harris.dev> Date: Thu, 19 May 2022 17:46:43 -0400 Subject: [PATCH 22/27] once more with feeling --- packages/kit/src/core/sync/write_types.js | 2 +- packages/kit/src/utils/filesystem.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/kit/src/core/sync/write_types.js b/packages/kit/src/core/sync/write_types.js index de331b20f154..01f129aa8e37 100644 --- a/packages/kit/src/core/sync/write_types.js +++ b/packages/kit/src/core/sync/write_types.js @@ -23,7 +23,7 @@ export type Load< * @param {import('types').ManifestData} manifest_data */ export function write_types(config, manifest_data) { - // rimraf(`${config.kit.outDir}/types`); + rimraf(`${config.kit.outDir}/types`); /** @type {Map<string, { params: string[], type: 'page' | 'endpoint' | 'both' }>} */ const shadow_types = new Map(); diff --git a/packages/kit/src/utils/filesystem.js b/packages/kit/src/utils/filesystem.js index ac3811ef4c93..b0c6a5d3beb9 100644 --- a/packages/kit/src/utils/filesystem.js +++ b/packages/kit/src/utils/filesystem.js @@ -14,7 +14,7 @@ export function mkdirp(dir) { /** @param {string} path */ export function rimraf(path) { if (!fs.existsSync(path)) return; - (fs.rmSync || fs.rmdirSync)(path, { recursive: true, force: true }); + fs.rmSync(path, { recursive: true, force: true }); } /** From 0e743997abd5a96349a854a556107fd322318409 Mon Sep 17 00:00:00 2001 From: Rich Harris <hello@rich-harris.dev> Date: Thu, 19 May 2022 17:57:04 -0400 Subject: [PATCH 23/27] fuck you, windows --- packages/kit/src/utils/filesystem.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/kit/src/utils/filesystem.js b/packages/kit/src/utils/filesystem.js index b0c6a5d3beb9..796a28c41577 100644 --- a/packages/kit/src/utils/filesystem.js +++ b/packages/kit/src/utils/filesystem.js @@ -14,7 +14,14 @@ export function mkdirp(dir) { /** @param {string} path */ export function rimraf(path) { if (!fs.existsSync(path)) return; - fs.rmSync(path, { recursive: true, force: true }); + + if (fs.statSync(path).isDirectory()) { + for (const child of fs.readdirSync(path)) { + rimraf(child); + } + } else { + fs.unlinkSync(path); + } } /** From 95e0bff551b81dbf807e9e4baaa26639842b3a28 Mon Sep 17 00:00:00 2001 From: Rich Harris <hello@rich-harris.dev> Date: Fri, 20 May 2022 12:41:25 -0400 Subject: [PATCH 24/27] revert rimraf changes --- packages/kit/src/utils/filesystem.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/packages/kit/src/utils/filesystem.js b/packages/kit/src/utils/filesystem.js index 796a28c41577..dc63b0ed8570 100644 --- a/packages/kit/src/utils/filesystem.js +++ b/packages/kit/src/utils/filesystem.js @@ -13,15 +13,7 @@ export function mkdirp(dir) { /** @param {string} path */ export function rimraf(path) { - if (!fs.existsSync(path)) return; - - if (fs.statSync(path).isDirectory()) { - for (const child of fs.readdirSync(path)) { - rimraf(child); - } - } else { - fs.unlinkSync(path); - } + fs.rmSync(path, { force: true, recursive: true }); } /** From b26abe85966d419b036b853564011a8dacf8926b Mon Sep 17 00:00:00 2001 From: Rich Harris <hello@rich-harris.dev> Date: Fri, 20 May 2022 12:52:17 -0400 Subject: [PATCH 25/27] rename kit-amp to amp --- documentation/docs/16-seo.md | 4 ++-- packages/kit-amp/package.json | 2 +- packages/kit/test/apps/amp/package.json | 2 +- packages/kit/test/apps/amp/src/hooks.js | 2 +- pnpm-lock.yaml | 8 ++++---- sites/kit.svelte.dev/package.json | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/documentation/docs/16-seo.md b/documentation/docs/16-seo.md index 73c73a9d5df5..0e61d988e93c 100644 --- a/documentation/docs/16-seo.md +++ b/documentation/docs/16-seo.md @@ -105,10 +105,10 @@ const config = { export default config; ``` -...and transforming the HTML using `transformPage` along with `transform` imported from `@sveltejs/kit-amp`: +...and transforming the HTML using `transformPage` along with `transform` imported from `@sveltejs/amp`: ```js -import * as amp from '@sveltejs/kit-amp'; +import * as amp from '@sveltejs/amp'; /** @type {import('@sveltejs/kit').Handle} */ export async function handle({ event, resolve }) { diff --git a/packages/kit-amp/package.json b/packages/kit-amp/package.json index efd6e41cfdb4..fcc2b308613f 100644 --- a/packages/kit-amp/package.json +++ b/packages/kit-amp/package.json @@ -1,5 +1,5 @@ { - "name": "@sveltejs/kit-amp", + "name": "@sveltejs/amp", "version": "1.0.0-next.0", "repository": { "type": "git", diff --git a/packages/kit/test/apps/amp/package.json b/packages/kit/test/apps/amp/package.json index 9dd5f7c6af2e..a66b74094572 100644 --- a/packages/kit/test/apps/amp/package.json +++ b/packages/kit/test/apps/amp/package.json @@ -12,8 +12,8 @@ "test:build": "playwright test" }, "devDependencies": { + "@sveltejs/amp": "workspace:*", "@sveltejs/kit": "workspace:*", - "@sveltejs/kit-amp": "workspace:*", "cross-env": "^7.0.3", "purify-css": "^1.2.5", "svelte": "^3.43.0", diff --git a/packages/kit/test/apps/amp/src/hooks.js b/packages/kit/test/apps/amp/src/hooks.js index 98a2e9bdaaff..c75f6f29116a 100644 --- a/packages/kit/test/apps/amp/src/hooks.js +++ b/packages/kit/test/apps/amp/src/hooks.js @@ -1,5 +1,5 @@ import purify from 'purify-css'; -import * as amp from '@sveltejs/kit-amp'; +import * as amp from '@sveltejs/amp'; /** @type {import('@sveltejs/kit').Handle} */ export async function handle({ event, resolve }) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7bce8151b2f4..897ed705d651 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -327,16 +327,16 @@ importers: packages/kit/test/apps/amp: specifiers: + '@sveltejs/amp': workspace:* '@sveltejs/kit': workspace:* - '@sveltejs/kit-amp': workspace:* cross-env: ^7.0.3 purify-css: ^1.2.5 svelte: ^3.43.0 svelte-check: ^2.5.0 typescript: ~4.6.2 devDependencies: + '@sveltejs/amp': link:../../../../kit-amp '@sveltejs/kit': link:../../.. - '@sveltejs/kit-amp': link:../../../../kit-amp cross-env: 7.0.3 purify-css: 1.2.5 svelte: 3.44.2 @@ -461,8 +461,8 @@ importers: specifiers: '@sveltejs/adapter-auto': workspace:* '@sveltejs/adapter-static': workspace:* + '@sveltejs/amp': workspace:* '@sveltejs/kit': workspace:* - '@sveltejs/kit-amp': workspace:* '@sveltejs/site-kit': ^2.1.0 '@types/node': ^16.11.11 flexsearch: ^0.7.21 @@ -477,8 +477,8 @@ importers: devDependencies: '@sveltejs/adapter-auto': link:../../packages/adapter-auto '@sveltejs/adapter-static': link:../../packages/adapter-static + '@sveltejs/amp': link:../../packages/kit-amp '@sveltejs/kit': link:../../packages/kit - '@sveltejs/kit-amp': link:../../packages/kit-amp '@sveltejs/site-kit': 2.1.0 '@types/node': 16.11.11 flexsearch: 0.7.21 diff --git a/sites/kit.svelte.dev/package.json b/sites/kit.svelte.dev/package.json index 109ae77b92fd..f148d830eac6 100644 --- a/sites/kit.svelte.dev/package.json +++ b/sites/kit.svelte.dev/package.json @@ -10,8 +10,8 @@ "devDependencies": { "@sveltejs/adapter-auto": "workspace:*", "@sveltejs/adapter-static": "workspace:*", + "@sveltejs/amp": "workspace:*", "@sveltejs/kit": "workspace:*", - "@sveltejs/kit-amp": "workspace:*", "@sveltejs/site-kit": "^2.1.0", "@types/node": "^16.11.11", "flexsearch": "^0.7.21", From e08a8745ef67827def16fe2d2b0faf9d7ebcaf2a Mon Sep 17 00:00:00 2001 From: Rich Harris <richard.a.harris@gmail.com> Date: Fri, 20 May 2022 13:12:56 -0400 Subject: [PATCH 26/27] Update .npmrc Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> --- .npmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.npmrc b/.npmrc index f349fc7c9bf1..d7445a115f87 100644 --- a/.npmrc +++ b/.npmrc @@ -1,2 +1,2 @@ link-workspace-packages = true -engine-strict = true \ No newline at end of file +engine-strict = true From 4c96bff9b7c10c4c39bf9c99bdfd72c92d540c0a Mon Sep 17 00:00:00 2001 From: Rich Harris <hello@rich-harris.dev> Date: Fri, 20 May 2022 13:33:30 -0400 Subject: [PATCH 27/27] move kit-amp to amp --- packages/{kit-amp => amp}/.gitignore | 0 packages/{kit-amp => amp}/index.d.ts | 0 packages/{kit-amp => amp}/index.js | 0 packages/{kit-amp => amp}/package.json | 0 pnpm-lock.yaml | 10 +++++----- 5 files changed, 5 insertions(+), 5 deletions(-) rename packages/{kit-amp => amp}/.gitignore (100%) rename packages/{kit-amp => amp}/index.d.ts (100%) rename packages/{kit-amp => amp}/index.js (100%) rename packages/{kit-amp => amp}/package.json (100%) diff --git a/packages/kit-amp/.gitignore b/packages/amp/.gitignore similarity index 100% rename from packages/kit-amp/.gitignore rename to packages/amp/.gitignore diff --git a/packages/kit-amp/index.d.ts b/packages/amp/index.d.ts similarity index 100% rename from packages/kit-amp/index.d.ts rename to packages/amp/index.d.ts diff --git a/packages/kit-amp/index.js b/packages/amp/index.js similarity index 100% rename from packages/kit-amp/index.js rename to packages/amp/index.js diff --git a/packages/kit-amp/package.json b/packages/amp/package.json similarity index 100% rename from packages/kit-amp/package.json rename to packages/amp/package.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 897ed705d651..414fbd1d1c13 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -195,6 +195,9 @@ importers: '@types/node': 14.18.17 typescript: 4.6.2 + packages/amp: + specifiers: {} + packages/create-svelte: specifiers: '@playwright/test': ^1.21.0 @@ -322,9 +325,6 @@ importers: typescript: 4.6.4 uvu: 0.5.2 - packages/kit-amp: - specifiers: {} - packages/kit/test/apps/amp: specifiers: '@sveltejs/amp': workspace:* @@ -335,7 +335,7 @@ importers: svelte-check: ^2.5.0 typescript: ~4.6.2 devDependencies: - '@sveltejs/amp': link:../../../../kit-amp + '@sveltejs/amp': link:../../../../amp '@sveltejs/kit': link:../../.. cross-env: 7.0.3 purify-css: 1.2.5 @@ -477,7 +477,7 @@ importers: devDependencies: '@sveltejs/adapter-auto': link:../../packages/adapter-auto '@sveltejs/adapter-static': link:../../packages/adapter-static - '@sveltejs/amp': link:../../packages/kit-amp + '@sveltejs/amp': link:../../packages/amp '@sveltejs/kit': link:../../packages/kit '@sveltejs/site-kit': 2.1.0 '@types/node': 16.11.11