diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 5aefffee0298..cd5d8b6c8932 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,29 +1,32 @@ ------- +--- + Before filing an issue we'd appreciate it if you could take a moment to ensure there isn't already an open issue or pull-request. ------ + +--- If there's an existing issue, please add a :+1: reaction to the description of the issue. One way we prioritize issues is by the number of :+1: reactions on their descriptions. Please DO NOT add `+1` or :+1: comments. ### Feature requests and proposals + We're excited to hear how we can make SvelteKit better. Please add as much detail as you can on your use case. To propose an implementation of a large feature or change, please create an [RFC](https://github.com/sveltejs/rfcs). ### Bugs + If you're filing an issue about a bug please include as much information as you can, including the following. -- The output of `npx envinfo --system --npmPackages svelte,@sveltejs/kit,@sveltejs/snowpack-config --binaries --browsers` +- The output of `npx envinfo --system --npmPackages svelte,@sveltejs/kit --binaries --browsers` - Your browser - Your adapter (e.g. Node, static, Vercel, Begin, etc...) -- *Repeatable steps to reproduce the issue* +- _Repeatable steps to reproduce the issue_ * We recommend creating a small repo that illustrates the problem. * Reproductions should be small, self-contained, correct examples – http://sscce.org. -Thanks for being part of SvelteKit! -------- +## Thanks for being part of SvelteKit! diff --git a/documentation/docs/01-structure.md b/documentation/docs/01-structure.md index 69ce27c1a3fe..55b019bfabba 100644 --- a/documentation/docs/01-structure.md +++ b/documentation/docs/01-structure.md @@ -15,8 +15,8 @@ If you take a look inside a new SvelteKit project, you'll see some files that Sv │ └ app.html ├ static │ ├ # your files here -├ snowpack.config.cjs -└ svelte.config.cjs +├ svelte.config.cjs +└ vite.config.js ``` ### package.json @@ -73,10 +73,10 @@ Sapper doesn't serve these files — you'd typically use [sirv](https://github.c > Note that the default behaviour of the service worker is to cache all assets from the static directory, so if you have more than 50mb of files here, you will start to exceed the cache limit for service-workers in some browsers, which can cause the service worker to stop loading. In this instance, it is advisable to customise what files are cached by editing the service-worker yourself. -### snowpack.config.cjs - -This is the [Snowpack configuration file](https://www.snowpack.dev/reference/configuration) for your project. - ### svelte.config.cjs This file contains SvelteKit options as well as options for `svelte-preprocess`. + +### vite.config.js + +This is the [Vite configuration file](https://vitejs.dev/config/) for your project. diff --git a/examples/hn.svelte.dev/package.json b/examples/hn.svelte.dev/package.json index d52feee92f5d..20ff997b4ee7 100644 --- a/examples/hn.svelte.dev/package.json +++ b/examples/hn.svelte.dev/package.json @@ -11,7 +11,6 @@ "devDependencies": { "@sveltejs/adapter-netlify": "workspace:*", "@sveltejs/kit": "workspace:*", - "@sveltejs/snowpack-config": "workspace:*", "svelte": "^3.32.1" } } diff --git a/examples/hn.svelte.dev/snowpack.config.cjs b/examples/hn.svelte.dev/snowpack.config.cjs deleted file mode 100644 index 46d9a675aa50..000000000000 --- a/examples/hn.svelte.dev/snowpack.config.cjs +++ /dev/null @@ -1,10 +0,0 @@ -// Consult https://www.snowpack.dev to learn about these options -module.exports = { - extends: '@sveltejs/snowpack-config', - mount: { - 'src/components': '/_components' - }, - alias: { - '$components': './src/components' - } -}; \ No newline at end of file diff --git a/examples/hn.svelte.dev/src/components/Nav.svelte b/examples/hn.svelte.dev/src/components/Nav.svelte index 9f8cb40dde3c..7cc7feccf386 100644 --- a/examples/hn.svelte.dev/src/components/Nav.svelte +++ b/examples/hn.svelte.dev/src/components/Nav.svelte @@ -6,13 +6,13 @@ Svelte Hacker News logo diff --git a/examples/hn.svelte.dev/src/routes/$error.svelte b/examples/hn.svelte.dev/src/routes/$error.svelte index 6d8f982a8202..8a624d35056f 100644 --- a/examples/hn.svelte.dev/src/routes/$error.svelte +++ b/examples/hn.svelte.dev/src/routes/$error.svelte @@ -1,8 +1,9 @@ diff --git a/examples/realworld.svelte.dev/vite.config.js b/examples/realworld.svelte.dev/vite.config.js new file mode 100644 index 000000000000..ad6f3c58cda6 --- /dev/null +++ b/examples/realworld.svelte.dev/vite.config.js @@ -0,0 +1,10 @@ +import { resolve } from 'path'; + +export default { + resolve: { + alias: { + $common: resolve('src/common'), + $components: resolve('src/components') + } + } +}; diff --git a/examples/sandbox/package.json b/examples/sandbox/package.json index a6925ab77544..c637ae9d481d 100644 --- a/examples/sandbox/package.json +++ b/examples/sandbox/package.json @@ -11,7 +11,6 @@ "devDependencies": { "@sveltejs/adapter-node": "workspace:*", "@sveltejs/kit": "workspace:*", - "@sveltejs/snowpack-config": "workspace:*", "svelte": "^3.32.1" } } diff --git a/examples/sandbox/snowpack.config.cjs b/examples/sandbox/snowpack.config.cjs deleted file mode 100644 index adb7e99ea205..000000000000 --- a/examples/sandbox/snowpack.config.cjs +++ /dev/null @@ -1,10 +0,0 @@ -// Consult https://www.snowpack.dev to learn about these options -module.exports = { - extends: '@sveltejs/snowpack-config', - mount: { - 'src/components': '/_components' - }, - alias: { - $components: './src/components' - } -}; diff --git a/examples/sandbox/vite.config.js b/examples/sandbox/vite.config.js new file mode 100644 index 000000000000..4c52b8079c75 --- /dev/null +++ b/examples/sandbox/vite.config.js @@ -0,0 +1,9 @@ +import { resolve } from 'path'; + +export default { + resolve: { + alias: { + $components: resolve('src/components') + } + } +}; diff --git a/examples/svelte-kit-demo/package.json b/examples/svelte-kit-demo/package.json index 9c820dbe36b4..c7a5ea3335e4 100644 --- a/examples/svelte-kit-demo/package.json +++ b/examples/svelte-kit-demo/package.json @@ -12,7 +12,6 @@ "@sveltejs/adapter-node": "workspace:*", "@sveltejs/adapter-static": "workspace:*", "@sveltejs/kit": "workspace:*", - "@sveltejs/snowpack-config": "workspace:*", "svelte": "^3.32.1" } } diff --git a/examples/svelte-kit-demo/snowpack.config.cjs b/examples/svelte-kit-demo/snowpack.config.cjs deleted file mode 100644 index 46d9a675aa50..000000000000 --- a/examples/svelte-kit-demo/snowpack.config.cjs +++ /dev/null @@ -1,10 +0,0 @@ -// Consult https://www.snowpack.dev to learn about these options -module.exports = { - extends: '@sveltejs/snowpack-config', - mount: { - 'src/components': '/_components' - }, - alias: { - '$components': './src/components' - } -}; \ No newline at end of file diff --git a/examples/svelte-kit-demo/src/components/Nav.svelte b/examples/svelte-kit-demo/src/components/Nav.svelte index bad0c1007890..5085704f6e3d 100644 --- a/examples/svelte-kit-demo/src/components/Nav.svelte +++ b/examples/svelte-kit-demo/src/components/Nav.svelte @@ -3,9 +3,9 @@ - -

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 rendered.replace( - '', - ` - - - - `.replace(/^\t{6}/gm, '') - ); + const rendered = await render( + { + headers: req.headers, + method: req.method, + path: parsed.pathname, + query: new URLSearchParams(parsed.query), + body }, - manifest: this.manifest, - target: this.config.target, - entry: 'assets/runtime/internal/start.js', - dev: true, - amp: this.config.amp, - root, - setup, - only_prerender: false, - start_global: this.config.startGlobal, - app_dir: this.config.appDir, - host: this.config.host, - host_header: this.config.hostHeader, - get_stack: (error) => - sourcemap_stacktrace(error.stack, async (address) => { - if (existsSync(address)) { - // it's a filepath - return readFileSync(address, 'utf-8'); + { + paths: this.config.paths, + template: ({ head, body }) => { + let rendered = template + .replace('%svelte.head%', () => head) + .replace('%svelte.body%', () => body); + + if (this.config.amp) { + const result = validator.validateString(rendered); + + if (result.status !== 'PASS') { + const lines = rendered.split('\n'); + + const escape = (str) => + str.replace(/&/g, '&').replace(//g, '>'); + + rendered = ` + + + + + +

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')} + `; + } } - try { - const { contents } = await this.snowpack.loadUrl(address, { - isSSR: true, - encoding: 'utf8' - }); - return contents; - } catch { - // fail gracefully - } - }), - get_static_file: (file) => readFileSync(join(this.config.files.assets, file)), - get_amp_css: (url) => - this.snowpack.loadUrl(url, { encoding: 'utf-8' }).then(({ contents }) => contents) + return rendered; + }, + manifest: this.manifest, + target: this.config.target, + entry: `/${dev_dir}/runtime/internal/start.js`, + dev: true, + amp: this.config.amp, + root, + setup, + only_prerender: false, + start_global: this.config.startGlobal, + host: this.config.host, + host_header: this.config.hostHeader, + get_stack: (error) => { + this.viteDevServer.ssrFixStacktrace(error); + return error.stack; + }, + get_static_file: (file) => readFileSync(join(this.config.files.assets, file)), + get_amp_css: (url) => '' // TODO: implement this + } + ); + + if (rendered) { + res.writeHead(rendered.status, rendered.headers); + res.end(rendered.body); + } else { + res.statusCode = 404; + res.end('Not found'); } - ); - - if (rendered) { - res.writeHead(rendered.status, rendered.headers); - res.end(rendered.body); - } else { - res.statusCode = 404; - res.end('Not found'); + } catch (e) { + this.viteDevServer.ssrFixStacktrace(e); + res.end(e.stack); } }); }); @@ -285,51 +232,90 @@ class Watcher extends EventEmitter { } update() { - const manifest_data = create_manifest_data(this.config); + const manifest_data = create_manifest_data({ + config: this.config, + output: dev_dir + }); create_app({ manifest_data, - output: '.svelte/assets' + output: dev_dir }); const common_css_deps = new Set(); + const load = async (url) => { + const mod = await this.viteDevServer.ssrLoadModule(url); + const node = await this.viteDevServer.moduleGraph.getModuleByUrl(url); + + const deps = new Set(); + find_deps(node, deps); + + const css = new Set(); + for (const dep of deps) { + // TODO what about .scss files, etc? + if (dep.file.endsWith('.css')) { + const mod = await this.viteDevServer.ssrLoadModule(dep.url); + css.add(mod.default); + } + } + + return { mod, css }; + }; + + const find_deps = (node, deps) => { + for (const dep of node.importedModules) { + if (!deps.has(dep)) { + deps.add(dep); + find_deps(dep, deps); + } + } + }; + this.manifest = { assets: manifest_data.assets, layout: async () => { - const { exports, css } = await this.load(manifest_data.layout.url); - css.forEach((dep) => common_css_deps.add(dep)); - return exports; + const { mod, css } = await load(manifest_data.layout); + css.forEach((mod) => { + common_css_deps.add(mod); + }); + return mod; }, error: async () => { - const { exports, css } = await this.load(manifest_data.error.url); - css.forEach((dep) => common_css_deps.add(dep)); - return exports; + const { mod, css } = await load(manifest_data.error); + css.forEach((mod) => { + common_css_deps.add(mod); + }); + return mod; }, pages: manifest_data.pages.map((data) => { - // This is a bit of a hack, but it means we can inject the correct - // elements without needing to do any analysis before loading + // This is a bit of a hack, but it means we can inject the correct ` + ? `` : [ ...js_deps.map((dep) => ``), ...css_deps.map((dep) => ``) @@ -274,7 +275,7 @@ async function get_response({ request, options, $session, route, status = 200, e ` : ` `; - const head = [rendered.head, links, init].join('\n\n'); + const head = [ + rendered.head, + options.amp ? '' : ``, + links, + init + ].join('\n\n'); const body = options.amp ? rendered.html diff --git a/packages/kit/src/runtime/internal/renderer/index.js b/packages/kit/src/runtime/internal/renderer/index.js index ad0163579acb..d4348e1dbf31 100644 --- a/packages/kit/src/runtime/internal/renderer/index.js +++ b/packages/kit/src/runtime/internal/renderer/index.js @@ -119,6 +119,15 @@ export class Renderer { this.current = hydrated.state; } + // remove dev-mode SSR