From 5a232993cd9a01f43f44607650652fe6ff18847d Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 6 Feb 2026 14:12:19 -0500 Subject: [PATCH] WIP --- .oxlintrc.json | 10 +++-- eslint.config.js | 33 +--------------- oxlint/custom.js | 38 +++++++++++++++++++ package.json | 1 + .../compiler/phases/1-parse/state/element.js | 1 + pnpm-lock.yaml | 14 ++++++- 6 files changed, 59 insertions(+), 38 deletions(-) create mode 100644 oxlint/custom.js diff --git a/.oxlintrc.json b/.oxlintrc.json index a8b73bb8de..5f2f60b2ef 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -1335,6 +1335,7 @@ "no-unsafe-negation": "off", "no-var": "error", "no-with": "off", + "prefer-const": "error", "prefer-rest-params": "error", "prefer-spread": "error" } @@ -1374,12 +1375,13 @@ "packages/svelte/src/**/*" ], "rules": { - "custom/no_compiler_imports": "error", - "svelte/no-svelte-internal": "off" + "svelte/no-svelte-internal": "off", + "custom/no-compiler-imports": "error" }, "jsPlugins": [ - "eslint-plugin-custom" + "eslint-plugin-custom", + "./oxlint/custom.js" ] } ] -} \ No newline at end of file +} diff --git a/eslint.config.js b/eslint.config.js index 0e0e0bc729..5851a462b4 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,37 +1,6 @@ import svelte_config from '@sveltejs/eslint-config'; import lube from 'eslint-plugin-lube'; - -const no_compiler_imports = { - meta: { - type: /** @type {const} */ ('problem'), - docs: { - description: - 'Enforce that there are no imports to the compiler in runtime code. ' + - 'This prevents accidental inclusion of the compiler runtime and ' + - "ensures that TypeScript does not pick up more ambient types (for example from Node) that shouldn't be available in the browser." - } - }, - create(context) { - return { - Program: () => { - // Do a simple string search because ESLint doesn't provide a way to check JSDoc comments. - // The string search could in theory yield false positives, but in practice it's unlikely. - const text = context.sourceCode.getText(); - const idx = Math.max(text.indexOf('../compiler/'), text.indexOf('#compiler')); - if (idx !== -1) { - context.report({ - loc: { - start: context.sourceCode.getLocFromIndex(idx), - end: context.sourceCode.getLocFromIndex(idx + 12) - }, - message: - 'References to compiler code are forbidden in runtime code (both for type and value imports)' - }); - } - } - }; - } -}; +import no_compiler_imports from './oxlint/no-compiler-imports.js'; /** @type {import('eslint').Linter.FlatConfig[]} */ export default [ diff --git a/oxlint/custom.js b/oxlint/custom.js new file mode 100644 index 0000000000..99cbf38f47 --- /dev/null +++ b/oxlint/custom.js @@ -0,0 +1,38 @@ +// @ts-check +import { eslintCompatPlugin } from '@oxlint/plugins'; + +const plugin = eslintCompatPlugin({ + meta: { + name: 'custom' + }, + rules: { + // Enforce that there are no imports to the compiler in runtime code. + // This prevents accidental inclusion of the compiler runtime and + // ensures that TypeScript does not pick up more ambient types + // (for example from Node) that shouldn't be available in the browser. + 'no-compiler-imports': { + create(context) { + return { + Program: () => { + // Do a simple string search because ESLint doesn't provide a way to check JSDoc comments. + // The string search could in theory yield false positives, but in practice it's unlikely. + const text = context.sourceCode.getText(); + const idx = Math.max(text.indexOf('../compiler/'), text.indexOf('#compiler')); + if (idx !== -1) { + context.report({ + loc: { + start: context.sourceCode.getLocFromIndex(idx), + end: context.sourceCode.getLocFromIndex(idx + 12) + }, + message: + 'References to compiler code are forbidden in runtime code (both for type and value imports)' + }); + } + } + }; + } + } + } +}); + +export default plugin; diff --git a/package.json b/package.json index e795bc799b..3b78c1a076 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ }, "devDependencies": { "@changesets/cli": "^2.29.8", + "@oxlint/plugins": "^1.43.0", "@stylistic/eslint-plugin": "^5.7.1", "@sveltejs/eslint-config": "^8.3.3", "@svitejs/changesets-changelog-github-compact": "^1.1.0", diff --git a/packages/svelte/src/compiler/phases/1-parse/state/element.js b/packages/svelte/src/compiler/phases/1-parse/state/element.js index d9fe33bbac..bc23df3cfe 100644 --- a/packages/svelte/src/compiler/phases/1-parse/state/element.js +++ b/packages/svelte/src/compiler/phases/1-parse/state/element.js @@ -29,6 +29,7 @@ const regex_valid_element_name = export const regex_valid_component_name = // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#identifiers adjusted for our needs // (must start with uppercase letter if no dots, can contain dots) + // eslint-disable-next-line no-misleading-character-class /^(?:\p{Lu}[$\u200c\u200d\p{ID_Continue}.]*|\p{ID_Start}[$\u200c\u200d\p{ID_Continue}]*(?:\.[$\u200c\u200d\p{ID_Continue}]+)+)$/u; /** @type {Map} */ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4ed27d7fab..12f9df9337 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@changesets/cli': specifier: ^2.29.8 version: 2.29.8(@types/node@20.19.17) + '@oxlint/plugins': + specifier: ^1.43.0 + version: 1.43.0 '@stylistic/eslint-plugin': specifier: ^5.7.1 version: 5.7.1(eslint@9.9.1) @@ -708,6 +711,10 @@ packages: cpu: [x64] os: [linux] + '@oxlint/plugins@1.43.0': + resolution: {integrity: sha512-hx8aiUIM9firpmHY6XU/MIKcsUvGgFPOKcBgbGUdhAlbOKGWtEYP0hapXIsaNlO0eixmLomNmQWwgjpunc9q7g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@oxlint/win32-arm64@1.42.0': resolution: {integrity: sha512-lAPS2YAuu+qFqoTNPFcNsxXjwSV0M+dOgAzzVTAN7Yo2ifj+oLOx0GsntWoM78PvQWI7Q827ZxqtU2ImBmDapA==} cpu: [arm64] @@ -1547,6 +1554,7 @@ packages: glob@10.5.0: resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true globals@14.0.0: @@ -3084,6 +3092,8 @@ snapshots: '@oxlint/linux-x64-musl@1.42.0': optional: true + '@oxlint/plugins@1.43.0': {} + '@oxlint/win32-arm64@1.42.0': optional: true @@ -3747,7 +3757,7 @@ snapshots: eslint-plugin-es-x@7.8.0(eslint@9.9.1): dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.9.1) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.9.1) '@eslint-community/regexpp': 4.12.2 eslint: 9.9.1 eslint-compat-utils: 0.5.1(eslint@9.9.1) @@ -3756,7 +3766,7 @@ snapshots: eslint-plugin-n@17.16.1(eslint@9.9.1)(typescript@5.5.4): dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.9.1) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.9.1) '@typescript-eslint/utils': 8.48.1(eslint@9.9.1)(typescript@5.5.4) enhanced-resolve: 5.18.3 eslint: 9.9.1