From 4bedd0e4fb561b623e15c4e1a4cdaf7f8a2911d9 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Wed, 15 May 2024 16:45:01 +0200 Subject: [PATCH] feat: error on imports to `svelte/internal/*` (#11632) * feat: error on imports to `svelte/internal/*` closes #11622 * regenerate * also error on svelte/internal --- .changeset/eight-carrots-hunt.md | 5 +++++ packages/svelte/messages/compile-errors/script.md | 4 ++++ packages/svelte/src/compiler/errors.js | 9 +++++++++ .../svelte/src/compiler/phases/2-analyze/validation.js | 10 ++++++++++ .../samples/svelte-internal-import/_config.js | 9 +++++++++ .../samples/svelte-internal-import/main.svelte | 5 +++++ .../samples/svelte-internal-import/main.svelte.js | 1 + 7 files changed, 43 insertions(+) create mode 100644 .changeset/eight-carrots-hunt.md create mode 100644 packages/svelte/tests/compiler-errors/samples/svelte-internal-import/_config.js create mode 100644 packages/svelte/tests/compiler-errors/samples/svelte-internal-import/main.svelte create mode 100644 packages/svelte/tests/compiler-errors/samples/svelte-internal-import/main.svelte.js diff --git a/.changeset/eight-carrots-hunt.md b/.changeset/eight-carrots-hunt.md new file mode 100644 index 000000000..a220e1308 --- /dev/null +++ b/.changeset/eight-carrots-hunt.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +feat: error on imports to `svelte/internal/*` diff --git a/packages/svelte/messages/compile-errors/script.md b/packages/svelte/messages/compile-errors/script.md index 861ac2f56..dbce3403d 100644 --- a/packages/svelte/messages/compile-errors/script.md +++ b/packages/svelte/messages/compile-errors/script.md @@ -46,6 +46,10 @@ > `$host()` can only be used inside custom element component instances +## import_svelte_internal_forbidden + +> Imports of `svelte/internal/*` are forbidden. It contains private runtime code which is subject to change without notice. If you're importing from `svelte/internal/*` to work around a limitation of Svelte, please open an issue at https://github.com/sveltejs/svelte and explain your use case + ## legacy_export_invalid > Cannot use `export let` in runes mode — use `$props()` instead diff --git a/packages/svelte/src/compiler/errors.js b/packages/svelte/src/compiler/errors.js index ab7197b06..8a2832df1 100644 --- a/packages/svelte/src/compiler/errors.js +++ b/packages/svelte/src/compiler/errors.js @@ -198,6 +198,15 @@ export function host_invalid_placement(node) { e(node, "host_invalid_placement", "`$host()` can only be used inside custom element component instances"); } +/** + * Imports of `svelte/internal/*` are forbidden. It contains private runtime code which is subject to change without notice. If you're importing from `svelte/internal/*` to work around a limitation of Svelte, please open an issue at https://github.com/sveltejs/svelte and explain your use case + * @param {null | number | NodeLike} node + * @returns {never} + */ +export function import_svelte_internal_forbidden(node) { + e(node, "import_svelte_internal_forbidden", "Imports of `svelte/internal/*` are forbidden. It contains private runtime code which is subject to change without notice. If you're importing from `svelte/internal/*` to work around a limitation of Svelte, please open an issue at https://github.com/sveltejs/svelte and explain your use case"); +} + /** * Cannot use `export let` in runes mode — use `$props()` instead * @param {null | number | NodeLike} node diff --git a/packages/svelte/src/compiler/phases/2-analyze/validation.js b/packages/svelte/src/compiler/phases/2-analyze/validation.js index 2c0296d69..306a9d20e 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/validation.js +++ b/packages/svelte/src/compiler/phases/2-analyze/validation.js @@ -905,6 +905,11 @@ function ensure_no_module_import_conflict(node, state) { * @type {import('zimmerframe').Visitors} */ export const validation_runes_js = { + ImportDeclaration(node) { + if (typeof node.source.value === 'string' && node.source.value.startsWith('svelte/internal')) { + e.import_svelte_internal_forbidden(node); + } + }, ExportSpecifier(node, { state }) { validate_export(node, state.scope, node.local.name); }, @@ -1077,6 +1082,11 @@ function validate_assignment(node, argument, state) { } export const validation_runes = merge(validation, a11y_validators, { + ImportDeclaration(node) { + if (typeof node.source.value === 'string' && node.source.value.startsWith('svelte/internal')) { + e.import_svelte_internal_forbidden(node); + } + }, Identifier(node, { path, state }) { let i = path.length; let parent = /** @type {import('estree').Expression} */ (path[--i]); diff --git a/packages/svelte/tests/compiler-errors/samples/svelte-internal-import/_config.js b/packages/svelte/tests/compiler-errors/samples/svelte-internal-import/_config.js new file mode 100644 index 000000000..731d23308 --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/svelte-internal-import/_config.js @@ -0,0 +1,9 @@ +import { test } from '../../test'; + +export default test({ + error: { + code: 'import_svelte_internal_forbidden', + message: + "Imports of `svelte/internal/*` are forbidden. It contains private runtime code which is subject to change without notice. If you're importing from `svelte/internal/*` to work around a limitation of Svelte, please open an issue at https://github.com/sveltejs/svelte and explain your use case" + } +}); diff --git a/packages/svelte/tests/compiler-errors/samples/svelte-internal-import/main.svelte b/packages/svelte/tests/compiler-errors/samples/svelte-internal-import/main.svelte new file mode 100644 index 000000000..d31b8d0b7 --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/svelte-internal-import/main.svelte @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/packages/svelte/tests/compiler-errors/samples/svelte-internal-import/main.svelte.js b/packages/svelte/tests/compiler-errors/samples/svelte-internal-import/main.svelte.js new file mode 100644 index 000000000..8047b01e6 --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/svelte-internal-import/main.svelte.js @@ -0,0 +1 @@ +import { something } from 'svelte/internal/server';