diff --git a/packages/sveltekit/package.json b/packages/sveltekit/package.json index 256fd02c206a..50a3deb7bbb2 100644 --- a/packages/sveltekit/package.json +++ b/packages/sveltekit/package.json @@ -47,18 +47,17 @@ } }, "dependencies": { - "@babel/parser": "7.26.9", "@sentry/cloudflare": "10.40.0", "@sentry/core": "10.40.0", "@sentry/node": "10.40.0", "@sentry/svelte": "10.40.0", "@sentry/vite-plugin": "^5.1.0", + "@sveltejs/acorn-typescript": "^1.0.9", + "acorn": "^8.14.0", "magic-string": "~0.30.0", - "recast": "0.23.11", "sorcery": "1.0.0" }, "devDependencies": { - "@babel/types": "^7.26.3", "@sveltejs/kit": "^2.52.2", "@sveltejs/vite-plugin-svelte": "^3.0.0", "svelte": "^4.2.8", diff --git a/packages/sveltekit/src/vite/autoInstrument.ts b/packages/sveltekit/src/vite/autoInstrument.ts index 58862e452ddc..2a1301ce00d9 100644 --- a/packages/sveltekit/src/vite/autoInstrument.ts +++ b/packages/sveltekit/src/vite/autoInstrument.ts @@ -1,10 +1,11 @@ +import { tsPlugin } from '@sveltejs/acorn-typescript'; +import * as acorn from 'acorn'; import * as fs from 'fs'; import * as path from 'path'; -import * as recast from 'recast'; import type { Plugin } from 'vite'; import { WRAPPED_MODULE_SUFFIX } from '../common/utils'; -import { parser } from './recastTypescriptParser'; -import t = recast.types.namedTypes; + +const AcornParser = acorn.Parser.extend(tsPlugin()); export type AutoInstrumentSelection = { /** @@ -123,23 +124,21 @@ export async function canWrapLoad(id: string, debug: boolean): Promise const code = (await fs.promises.readFile(id, 'utf8')).toString(); - const ast = recast.parse(code, { - parser, - }); - - const program = (ast as { program?: t.Program }).program; - - if (!program) { + let program: acorn.Program; + try { + program = AcornParser.parse(code, { + sourceType: 'module', + ecmaVersion: 'latest', + locations: true, + }); + } catch { // eslint-disable-next-line no-console debug && console.log(`Skipping wrapping ${id} because it doesn't contain valid JavaScript or TypeScript`); return false; } const hasLoadDeclaration = program.body - .filter( - (statement): statement is recast.types.namedTypes.ExportNamedDeclaration => - statement.type === 'ExportNamedDeclaration', - ) + .filter((statement): statement is acorn.ExportNamedDeclaration => statement.type === 'ExportNamedDeclaration') .find(exportDecl => { // find `export const load = ...` if (exportDecl.declaration?.type === 'VariableDeclaration') { @@ -160,11 +159,8 @@ export async function canWrapLoad(id: string, debug: boolean): Promise return exportDecl.specifiers.find(specifier => { return ( (specifier.exported.type === 'Identifier' && specifier.exported.name === 'load') || - // Type casting here because somehow the 'exportExtensions' plugin isn't reflected in the possible types - // This plugin adds support for exporting something as a string literal (see comment above) - // Doing this to avoid adding another babel plugin dependency - ((specifier.exported.type as 'StringLiteral' | '') === 'StringLiteral' && - (specifier.exported as unknown as t.StringLiteral).value === 'load') + // ESTree/acorn represents `export { x as "load" }` with a Literal node (not Babel's StringLiteral) + (specifier.exported.type === 'Literal' && specifier.exported.value === 'load') ); }); } diff --git a/packages/sveltekit/src/vite/recastTypescriptParser.ts b/packages/sveltekit/src/vite/recastTypescriptParser.ts deleted file mode 100644 index ca37439ddae9..000000000000 --- a/packages/sveltekit/src/vite/recastTypescriptParser.ts +++ /dev/null @@ -1,91 +0,0 @@ -// This babel parser config is taken from recast's typescript parser config, specifically from these two files: -// see: https://github.com/benjamn/recast/blob/master/parsers/_babel_options.ts -// see: https://github.com/benjamn/recast/blob/master/parsers/babel-ts.ts -// -// Changes: -// - we don't add the 'jsx' plugin, to correctly parse TypeScript angle bracket type assertions -// (see https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#type-assertions) -// - minor import and export changes -// - merged the two files linked above into one for simplicity - -// Date of access: 2025-03-04 -// Commit: https://github.com/benjamn/recast/commit/ba5132174894b496285da9d001f1f2524ceaed3a - -// Recast license: - -// Copyright (c) 2012 Ben Newman - -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: - -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import type { ParserPlugin } from '@babel/parser'; -import { parse as babelParse } from '@babel/parser'; -import type { Options } from 'recast'; - -export const parser: Options['parser'] = { - parse: (source: string) => - babelParse(source, { - strictMode: false, - allowImportExportEverywhere: true, - allowReturnOutsideFunction: true, - startLine: 1, - tokens: true, - plugins: [ - 'typescript', - 'asyncGenerators', - 'bigInt', - 'classPrivateMethods', - 'classPrivateProperties', - 'classProperties', - 'classStaticBlock', - 'decimal', - 'decorators-legacy', - 'doExpressions', - 'dynamicImport', - 'exportDefaultFrom', - 'exportNamespaceFrom', - 'functionBind', - 'functionSent', - 'importAssertions', - 'exportExtensions' as ParserPlugin, - 'importMeta', - 'nullishCoalescingOperator', - 'numericSeparator', - 'objectRestSpread', - 'optionalCatchBinding', - 'optionalChaining', - [ - 'pipelineOperator', - { - proposal: 'minimal', - }, - ], - [ - 'recordAndTuple', - { - syntaxType: 'hash', - }, - ], - 'throwExpressions', - 'topLevelAwait', - 'v8intrinsic', - ], - sourceType: 'module', - }), -}; diff --git a/yarn.lock b/yarn.lock index c4b44e29e3fa..e1e05dd6fd21 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1914,13 +1914,6 @@ "@babel/template" "^7.28.6" "@babel/types" "^7.28.6" -"@babel/parser@7.26.9": - version "7.26.9" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.9.tgz#d9e78bee6dc80f9efd8f2349dcfbbcdace280fd5" - integrity sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A== - dependencies: - "@babel/types" "^7.26.9" - "@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.4", "@babel/parser@^7.18.10", "@babel/parser@^7.20.7", "@babel/parser@^7.22.10", "@babel/parser@^7.22.16", "@babel/parser@^7.23.5", "@babel/parser@^7.23.6", "@babel/parser@^7.25.4", "@babel/parser@^7.26.7", "@babel/parser@^7.27.7", "@babel/parser@^7.28.0", "@babel/parser@^7.28.4", "@babel/parser@^7.28.5", "@babel/parser@^7.28.6", "@babel/parser@^7.29.0", "@babel/parser@^7.4.5", "@babel/parser@^7.7.0": version "7.29.0" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.0.tgz#669ef345add7d057e92b7ed15f0bac07611831b6" @@ -2981,7 +2974,7 @@ "@babel/types" "^7.29.0" debug "^4.3.1" -"@babel/types@^7.0.0", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.20.7", "@babel/types@^7.22.10", "@babel/types@^7.22.15", "@babel/types@^7.22.17", "@babel/types@^7.22.19", "@babel/types@^7.23.6", "@babel/types@^7.24.7", "@babel/types@^7.25.4", "@babel/types@^7.26.3", "@babel/types@^7.26.8", "@babel/types@^7.26.9", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.27.7", "@babel/types@^7.28.2", "@babel/types@^7.28.5", "@babel/types@^7.28.6", "@babel/types@^7.29.0", "@babel/types@^7.3.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.7.2": +"@babel/types@^7.0.0", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.20.7", "@babel/types@^7.22.10", "@babel/types@^7.22.15", "@babel/types@^7.22.17", "@babel/types@^7.22.19", "@babel/types@^7.23.6", "@babel/types@^7.24.7", "@babel/types@^7.25.4", "@babel/types@^7.26.8", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.27.7", "@babel/types@^7.28.2", "@babel/types@^7.28.5", "@babel/types@^7.28.6", "@babel/types@^7.29.0", "@babel/types@^7.3.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.7.2": version "7.29.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7" integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A== @@ -8497,10 +8490,10 @@ "@supabase/realtime-js" "2.11.2" "@supabase/storage-js" "2.7.1" -"@sveltejs/acorn-typescript@^1.0.5": - version "1.0.8" - resolved "https://registry.yarnpkg.com/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.8.tgz#69c746a7c232094c117c50dedbd1279fc64887b7" - integrity sha512-esgN+54+q0NjB0Y/4BomT9samII7jGwNy/2a3wNZbT2A2RpmXsXwUt24LvLhx6jUq2gVk4cWEvcRO6MFQbOfNA== +"@sveltejs/acorn-typescript@^1.0.5", "@sveltejs/acorn-typescript@^1.0.9": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.9.tgz#ac0bde368d6623727b0e0bc568cf6b4e5d5c4baa" + integrity sha512-lVJX6qEgs/4DOcRTpo56tmKzVPtoWAaVbL4hfO7t7NVwl9AAXzQR6cihesW1BmNMPl+bK6dreu2sOKBP2Q9CIA== "@sveltejs/kit@^2.52.2": version "2.52.2" @@ -25634,17 +25627,6 @@ real-require@^0.2.0: resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.2.0.tgz#209632dea1810be2ae063a6ac084fee7e33fba78" integrity sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg== -recast@0.23.11, recast@^0.23.4: - version "0.23.11" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.23.11.tgz#8885570bb28cf773ba1dc600da7f502f7883f73f" - integrity sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA== - dependencies: - ast-types "^0.16.1" - esprima "~4.0.0" - source-map "~0.6.1" - tiny-invariant "^1.3.3" - tslib "^2.0.1" - recast@^0.18.1: version "0.18.10" resolved "https://registry.yarnpkg.com/recast/-/recast-0.18.10.tgz#605ebbe621511eb89b6356a7e224bff66ed91478" @@ -25665,6 +25647,17 @@ recast@^0.20.5: source-map "~0.6.1" tslib "^2.0.1" +recast@^0.23.4: + version "0.23.11" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.23.11.tgz#8885570bb28cf773ba1dc600da7f502f7883f73f" + integrity sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA== + dependencies: + ast-types "^0.16.1" + esprima "~4.0.0" + source-map "~0.6.1" + tiny-invariant "^1.3.3" + tslib "^2.0.1" + rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"