diff --git a/.changeset/few-points-taste.md b/.changeset/few-points-taste.md new file mode 100644 index 000000000000..ca3c24089848 --- /dev/null +++ b/.changeset/few-points-taste.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +Force Vite to bundle Svelte component libraries in SSR diff --git a/.changeset/nervous-steaks-add.md b/.changeset/nervous-steaks-add.md new file mode 100644 index 000000000000..7dcdc58aac66 --- /dev/null +++ b/.changeset/nervous-steaks-add.md @@ -0,0 +1,5 @@ +--- +'create-svelte': patch +--- + +Remove obsolete vite.ssr config from template diff --git a/documentation/faq/70-packages.md b/documentation/faq/70-packages.md index 0af993abd0d1..9ab2e5f43233 100644 --- a/documentation/faq/70-packages.md +++ b/documentation/faq/70-packages.md @@ -2,13 +2,14 @@ question: How do I fix the error I'm getting trying to include a package? --- -Most of these issues come from Vite trying to deal with non-ESM libraries. You may find it helpful to search for your error message in [the Vite issue tracker](https://github.com/vitejs/vite/issues). +Most of these issues come from Vite trying to deal with non-ESM libraries. You may find it helpful to search for your error message in [the Vite issue tracker](https://github.com/vitejs/vite/issues). There are a number of known Vite issues, which cause errors in the following circumstances: -- [packages which use `exports` instead of `module.exports`](https://github.com/vitejs/vite/issues/2579). + +- [CommonJS packages](https://github.com/vitejs/vite/issues/2579). - [ESM library that imports a CJS library](https://github.com/vitejs/vite/issues/3024) - [some UMD libraries](https://github.com/vitejs/vite/issues/2679) Vite 2 is a relatively new library and over time we expect it to become easier to use non-ESM libraries with Vite. However, you might also consider asking the library author to distribute an ESM version of their package or even converting the source for the package entirely to ESM. ESM is now the standard way to write JavaScript libraries and while there are a lot of legacy packages out there the ecosystem will become much easier to work with as more libraries convert to ESM. -The most common workarounds would be to try moving the package between `dependencies` and `devDependencies` or trying to `include` or `exclude` it in `optimizeDeps`. SvelteKit currently asks Vite to bundle all your `dependencies` for easier deployment to serverless environment. This means that by moving a dependency to `devDependencies` Vite is no longer asked to bundle it. This may sidestep issues Vite encounters in trying to bundle certain libraries. Avoiding Vite bundling especially works for `adapter-node` and `adapter-static` where the bundling isn't necessary since you're not running in a serverless environment. We are considering [better alternatives](https://github.com/sveltejs/kit/issues/1016) to make this setup easier. You should also add any Svelte components to `ssr.noExternal`. [We hope to do this automatically in the future](https://github.com/sveltejs/kit/issues/904). +The most common workarounds would be to `include` or `exclude` the offending package in [`optimizeDeps`](https://vitejs.dev/config/#dep-optimization-options), or to add it to [`ssr.external` or `ssr.noExternal`](https://vitejs.dev/config/#ssr-options). diff --git a/packages/create-svelte/shared/+typescript/svelte.config.cjs b/packages/create-svelte/shared/+typescript/svelte.config.cjs index 0780759e3be2..46d50cea5f57 100644 --- a/packages/create-svelte/shared/+typescript/svelte.config.cjs +++ b/packages/create-svelte/shared/+typescript/svelte.config.cjs @@ -15,12 +15,6 @@ module.exports = { adapter: node(), // hydrate the
element in src/app.html - target: '#svelte', - - vite: { - ssr: { - noExternal: Object.keys(pkg.dependencies || {}) - } - } + target: '#svelte' } }; diff --git a/packages/create-svelte/shared/-typescript/svelte.config.cjs b/packages/create-svelte/shared/-typescript/svelte.config.cjs index 621098e71839..e04420ed3c28 100644 --- a/packages/create-svelte/shared/-typescript/svelte.config.cjs +++ b/packages/create-svelte/shared/-typescript/svelte.config.cjs @@ -10,12 +10,6 @@ module.exports = { adapter: node(), // hydrate the
element in src/app.html - target: '#svelte', - - vite: { - ssr: { - noExternal: Object.keys(pkg.dependencies || {}) - } - } + target: '#svelte' } }; diff --git a/packages/kit/src/core/build/index.js b/packages/kit/src/core/build/index.js index f0bbb6afeb77..e48e89594d28 100644 --- a/packages/kit/src/core/build/index.js +++ b/packages/kit/src/core/build/index.js @@ -2,7 +2,7 @@ import fs from 'fs'; import path from 'path'; import { rimraf } from '../filesystem/index.js'; import create_manifest_data from '../../core/create_manifest_data/index.js'; -import { copy_assets, posixify, resolve_entry } from '../utils.js'; +import { copy_assets, get_no_external, posixify, resolve_entry } from '../utils.js'; import { create_app } from '../../core/create_app/index.js'; import vite from 'vite'; import svelte from '@sveltejs/vite-plugin-svelte'; @@ -438,11 +438,9 @@ async function build_server( // @ts-ignore ssr: { ...user_config.ssr, - noExternal: [ - 'svelte', - '@sveltejs/kit', - ...((user_config.ssr && user_config.ssr.noExternal) || []) - ] + // note to self: this _might_ need to be ['svelte', '@sveltejs/kit', ...get_no_external()] + // but I'm honestly not sure. roll with this for now and see if it's ok + noExternal: get_no_external(cwd, user_config.ssr && user_config.ssr.noExternal) }, optimizeDeps: { entries: [] diff --git a/packages/kit/src/core/dev/index.js b/packages/kit/src/core/dev/index.js index e9d69b71352c..60b616f778fd 100644 --- a/packages/kit/src/core/dev/index.js +++ b/packages/kit/src/core/dev/index.js @@ -11,7 +11,7 @@ import { create_app } from '../../core/create_app/index.js'; import { rimraf } from '../filesystem/index.js'; import { ssr } from '../../runtime/server/index.js'; import { getRawBody } from '../http/index.js'; -import { copy_assets } from '../utils.js'; +import { copy_assets, get_no_external } from '../utils.js'; import svelte from '@sveltejs/vite-plugin-svelte'; import { get_server } from '../server/index.js'; import '../../install-fetch.js'; @@ -107,6 +107,10 @@ class Watcher extends EventEmitter { optimizeDeps: { ...user_config.optimizeDeps, entries: [] + }, + ssr: { + ...user_config.ssr, + noExternal: get_no_external(this.cwd, user_config.ssr && user_config.ssr.noExternal) } }); diff --git a/packages/kit/src/core/utils.js b/packages/kit/src/core/utils.js index a9348beeeb5e..d80f38e89f9f 100644 --- a/packages/kit/src/core/utils.js +++ b/packages/kit/src/core/utils.js @@ -74,3 +74,35 @@ export function resolve_entry(entry) { export function posixify(str) { return str.replace(/\\/g, '/'); } + +/** + * Get a list of packages that use pkg.svelte, so they can be added + * to ssr.noExternal. This is done on a best-effort basis to reduce + * the frequency of 'Must use import to load ES Module' and similar + * @param {string} cwd + * @returns {string[]} + */ +function find_svelte_packages(cwd) { + const pkg_file = path.join(cwd, 'package.json'); + if (!fs.existsSync(pkg_file)) return []; + + const pkg = JSON.parse(fs.readFileSync(pkg_file, 'utf8')); + + const deps = [...Object.keys(pkg.dependencies || {}), ...Object.keys(pkg.devDependencies || {})]; + + return deps.filter((dep) => { + const dep_pkg_file = path.join(cwd, 'node_modules', dep, 'package.json'); + if (!fs.existsSync(dep_pkg_file)) return false; + + const dep_pkg = JSON.parse(fs.readFileSync(dep_pkg_file, 'utf-8')); + return !!dep_pkg.svelte; + }); +} + +/** + * @param {string} cwd + * @param {string[]} [user_specified_deps] + */ +export function get_no_external(cwd, user_specified_deps = []) { + return [...user_specified_deps, ...find_svelte_packages(cwd)]; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ac5760d03016..6c947ca9e824 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -196,7 +196,7 @@ importers: '@sveltejs/adapter-cloudflare-workers': link:../../../adapter-cloudflare-workers '@sveltejs/adapter-netlify': link:../../../adapter-netlify '@sveltejs/adapter-vercel': link:../../../adapter-vercel - '@sveltejs/kit': 1.0.0-next.84_svelte@3.37.0+vite@2.1.5 + '@sveltejs/kit': link:../../../kit svelte: 3.37.0 svelte-preprocess: 4.7.1_svelte@3.37.0+typescript@4.2.4 typescript: 4.2.4 @@ -647,16 +647,6 @@ packages: rollup: 2.42.3 dev: true - /@rollup/pluginutils/4.1.0: - resolution: {integrity: sha512-TrBhfJkFxA+ER+ew2U2/fHbebhLT/l/2pRk0hfj9KusXUuRXd2v0R58AfaZK9VXDQ4TogOSEmICVrQAA3zFnHQ==} - engines: {node: '>= 8.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0 - dependencies: - estree-walker: 2.0.2 - picomatch: 2.2.3 - dev: true - /@rollup/pluginutils/4.1.0_rollup@2.41.1: resolution: {integrity: sha512-TrBhfJkFxA+ER+ew2U2/fHbebhLT/l/2pRk0hfj9KusXUuRXd2v0R58AfaZK9VXDQ4TogOSEmICVrQAA3zFnHQ==} engines: {node: '>= 8.0.0'} @@ -668,24 +658,6 @@ packages: rollup: 2.41.1 dev: false - /@sveltejs/kit/1.0.0-next.84_svelte@3.37.0+vite@2.1.5: - resolution: {integrity: sha512-v3XsG2Gvl4Fo7j5Uqmeq7NxpdzL6ODi9fV7eQhVNF2/J1Dko2ptG786jC3ynuCR7vrp67Mv+1MgraqGwIBETAQ==} - engines: {node: '>= 12.17.0'} - hasBin: true - peerDependencies: - svelte: ^3.32.1 - vite: ^2.1.0 - dependencies: - '@sveltejs/vite-plugin-svelte': 1.0.0-next.7_svelte@3.37.0+vite@2.1.5 - cheap-watch: 1.0.3 - sade: 1.7.4 - svelte: 3.37.0 - vite: 2.1.5 - transitivePeerDependencies: - - rollup - - supports-color - dev: true - /@sveltejs/vite-plugin-svelte/1.0.0-next.7_93fef3a16c1b45ac67b14a795df10192: resolution: {integrity: sha512-ENvKYY36jrvFP7h1G87k5uOoEh5UM1m8n40J2duqV/R3wHnxfW81SCR1aXo+5CVU8Prm3/jtS4TWs8CUTqO1fw==} engines: {node: '>=12.0.0'} @@ -708,28 +680,6 @@ packages: - supports-color dev: false - /@sveltejs/vite-plugin-svelte/1.0.0-next.7_svelte@3.37.0+vite@2.1.5: - resolution: {integrity: sha512-ENvKYY36jrvFP7h1G87k5uOoEh5UM1m8n40J2duqV/R3wHnxfW81SCR1aXo+5CVU8Prm3/jtS4TWs8CUTqO1fw==} - engines: {node: '>=12.0.0'} - peerDependencies: - svelte: ^3.37.0 - vite: ^2.1.5 - dependencies: - '@rollup/pluginutils': 4.1.0 - chalk: 4.1.0 - debug: 4.3.2 - hash-sum: 2.0.0 - require-relative: 0.8.7 - slash: 3.0.0 - source-map: 0.7.3 - svelte: 3.37.0 - svelte-hmr: 0.14.0_svelte@3.37.0 - vite: 2.1.5 - transitivePeerDependencies: - - rollup - - supports-color - dev: true - /@types/amphtml-validator/1.0.1: resolution: {integrity: sha512-DWE7fy6KtC+Uw0KV/HAmjuH2GB/o8yskXlvmVWR7mOVsLDybp+XrwkzEeRFU9wGjWKeRMBNGsx+5DRq7sUsAwA==} dependencies: @@ -1247,6 +1197,7 @@ packages: /cheap-watch/1.0.3: resolution: {integrity: sha512-xC5CruMhLzjPwJ5ecUxGu1uGmwJQykUhqd2QrCrYbwvsFYdRyviu6jG9+pccwDXJR/OpmOTOJ9yLFunVgQu9wg==} engines: {node: '>=8'} + dev: false /ci-info/2.0.0: resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} @@ -1435,6 +1386,7 @@ packages: optional: true dependencies: ms: 2.1.2 + dev: false /decamelize-keys/1.1.0: resolution: {integrity: sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=} @@ -2127,6 +2079,7 @@ packages: /hash-sum/2.0.0: resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==} + dev: false /hosted-git-info/2.8.8: resolution: {integrity: sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==} @@ -2881,6 +2834,7 @@ packages: /picomatch/2.2.3: resolution: {integrity: sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==} engines: {node: '>=8.6'} + dev: false /pify/2.3.0: resolution: {integrity: sha1-7RQaasBDqEnqWISY59yosVMw6Qw=} @@ -3140,6 +3094,7 @@ packages: /require-relative/0.8.7: resolution: {integrity: sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=} + dev: false /resolve-from/4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} @@ -3473,14 +3428,6 @@ packages: svelte: 3.35.0 dev: false - /svelte-hmr/0.14.0_svelte@3.37.0: - resolution: {integrity: sha512-Rc4w11U+U30m/cHqOJ/xioFSEAY5fd5muiQC7FL6XJuJAuB2OIJoEZl3KEJR2uO1/f4Bw0PdrugtbxcngSsOtQ==} - peerDependencies: - svelte: '>=3.19.0' - dependencies: - svelte: 3.37.0 - dev: true - /svelte-preprocess/4.7.0: resolution: {integrity: sha512-iNrY4YGqi0LD2e6oT9YbdSzOKntxk8gmzfqso1z/lUJOZh4o6fyIqkirmiZ8/dDJFqtIE1spVgDFWgkfhLEYlw==} engines: {node: '>= 9.11.2'}