From 854b7bb1a30e92f84dde017540beb620b43d64fb Mon Sep 17 00:00:00 2001 From: Princesseuh Date: Fri, 8 Jul 2022 12:02:42 -0400 Subject: [PATCH 1/5] Add editor integration to language integrations --- .../integrations/svelte/editor/editor.cts | 23 ++++++++ .../integrations/svelte/editor/tsconfig.json | 10 ++++ packages/integrations/svelte/package.json | 4 +- packages/integrations/vue/editor/editor.cts | 55 +++++++++++++++++++ .../integrations/vue/editor/tsconfig.json | 10 ++++ packages/integrations/vue/package.json | 3 +- pnpm-lock.yaml | 13 +++++ 7 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 packages/integrations/svelte/editor/editor.cts create mode 100644 packages/integrations/svelte/editor/tsconfig.json create mode 100644 packages/integrations/vue/editor/editor.cts create mode 100644 packages/integrations/vue/editor/tsconfig.json diff --git a/packages/integrations/svelte/editor/editor.cts b/packages/integrations/svelte/editor/editor.cts new file mode 100644 index 000000000000..202609d3393f --- /dev/null +++ b/packages/integrations/svelte/editor/editor.cts @@ -0,0 +1,23 @@ +import { svelte2tsx } from 'svelte2tsx'; + +export function toTSX(code: string, className: string): string { + let result = ` + let ${className}__AstroComponent_: Error + export default ${className}__AstroComponent_ + `; + + try { + let tsx = svelte2tsx(code).code; + tsx = 'let Props = render().props;\n' + tsx; + + // Replace Svelte's class export with a function export + result = tsx.replace( + /^export default[\S\s]*/gm, + `export default function ${className}__AstroComponent_(_props: typeof Props): any {}` + ); + } catch (e: any) { + return result; + } + + return result; +} diff --git a/packages/integrations/svelte/editor/tsconfig.json b/packages/integrations/svelte/editor/tsconfig.json new file mode 100644 index 000000000000..7e1f9d0ca879 --- /dev/null +++ b/packages/integrations/svelte/editor/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../../../tsconfig.base.json", + "compilerOptions": { + "allowJs": true, + "emitDeclarationOnly": false, + "module": "CommonJS", + "outDir": "../dist", + "target": "ES2020" + } +} diff --git a/packages/integrations/svelte/package.json b/packages/integrations/svelte/package.json index 53ce95147aa4..d2991d00bf00 100644 --- a/packages/integrations/svelte/package.json +++ b/packages/integrations/svelte/package.json @@ -20,13 +20,14 @@ "homepage": "https://astro.build", "exports": { ".": "./dist/index.js", + "./editor": "./dist/editor.cjs", "./*": "./*", "./client.js": "./client.js", "./server.js": "./server.js", "./package.json": "./package.json" }, "scripts": { - "build": "astro-scripts build \"src/**/*.ts\" && tsc", + "build": "astro-scripts build \"src/**/*.ts\" && tsc && tsc -p ./editor/tsconfig.json", "build:ci": "astro-scripts build \"src/**/*.ts\"", "dev": "astro-scripts dev \"src/**/*.ts\"" }, @@ -34,6 +35,7 @@ "@sveltejs/vite-plugin-svelte": "^1.0.0-next.48", "postcss-load-config": "^3.1.4", "svelte-preprocess": "^4.10.7", + "svelte2tsx": "^0.5.11", "vite": "^2.9.10" }, "devDependencies": { diff --git a/packages/integrations/vue/editor/editor.cts b/packages/integrations/vue/editor/editor.cts new file mode 100644 index 000000000000..29adaa09cad6 --- /dev/null +++ b/packages/integrations/vue/editor/editor.cts @@ -0,0 +1,55 @@ +import { parse } from '@vue/compiler-sfc'; + +export function toTSX(code: string, className: string): string { + let result = `export default function ${className}__AstroComponent_(_props: Record): any {}`; + + // NOTE: As you can expect, using regexes for this is not exactly the most reliable way of doing things + // However, I couldn't figure out a way to do it using Vue's compiler, I tried looking at how Volar does it, but I + // didn't really understand everything happening there and it seemed to be pretty Volar-specific. I do believe + // someone more knowledgable on Vue's internals could figure it out, but since this solution is good enough for most + // Vue components (and it's an improvement over, well, nothing), it's alright, I think + try { + const parsedResult = parse(code); + + if (parsedResult.errors.length > 0) { + return ` + let ${className}__AstroComponent_: Error + export default ${className}__AstroComponent_ + `; + } + + if (parsedResult.descriptor.scriptSetup) { + const definePropsType = + parsedResult.descriptor.scriptSetup.content.match(/defineProps<([\s\S]+)>/m); + + if (definePropsType) { + result = ` + ${parsedResult.descriptor.scriptSetup.content} + + export default function ${className}__AstroComponent_(_props: ${definePropsType[1]}): any { +
+ } + `; + } else { + const defineProps = + parsedResult.descriptor.scriptSetup.content.match(/defineProps\([\s\S]+\)/m); + + if (defineProps) { + result = ` + import { defineProps } from '@vue/runtime-core'; + + const Props = ${defineProps[0]} + + export default function ${className}__AstroComponent_(_props: typeof Props): any { +
+ } + `; + } + } + } + } catch (e: any) { + return result; + } + + return result; +} diff --git a/packages/integrations/vue/editor/tsconfig.json b/packages/integrations/vue/editor/tsconfig.json new file mode 100644 index 000000000000..7e1f9d0ca879 --- /dev/null +++ b/packages/integrations/vue/editor/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../../../tsconfig.base.json", + "compilerOptions": { + "allowJs": true, + "emitDeclarationOnly": false, + "module": "CommonJS", + "outDir": "../dist", + "target": "ES2020" + } +} diff --git a/packages/integrations/vue/package.json b/packages/integrations/vue/package.json index a6b2989fe9b4..74503cc20943 100644 --- a/packages/integrations/vue/package.json +++ b/packages/integrations/vue/package.json @@ -20,13 +20,14 @@ "homepage": "https://astro.build", "exports": { ".": "./dist/index.js", + "./editor": "./dist/editor.cjs", "./*": "./*", "./client.js": "./client.js", "./server.js": "./server.js", "./package.json": "./package.json" }, "scripts": { - "build": "astro-scripts build \"src/**/*.ts\" && tsc", + "build": "astro-scripts build \"src/**/*.ts\" && tsc && tsc -p ./editor/tsconfig.json", "build:ci": "astro-scripts build \"src/**/*.ts\"", "dev": "astro-scripts dev \"src/**/*.ts\"" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c2f0474368bc..55f283bfa9b8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2174,11 +2174,13 @@ importers: postcss-load-config: ^3.1.4 svelte: ^3.48.0 svelte-preprocess: ^4.10.7 + svelte2tsx: ^0.5.11 vite: ^2.9.10 dependencies: '@sveltejs/vite-plugin-svelte': 1.0.0-next.49_svelte@3.49.0+vite@2.9.14 postcss-load-config: 3.1.4 svelte-preprocess: 4.10.7_k3vaqsyrx2lfvza3vdeafxime4 + svelte2tsx: 0.5.11_svelte@3.49.0 vite: 2.9.14 devDependencies: astro: link:../../astro @@ -14267,6 +14269,17 @@ packages: resolution: {integrity: sha512-+lmjic1pApJWDfPCpUUTc1m8azDqYCG1JN9YEngrx/hUyIcFJo6VZhj0A1Ai0wqoHcEIuQy+e9tk+4uDgdtsFA==} engines: {node: '>= 8'} + /svelte2tsx/0.5.11_svelte@3.49.0: + resolution: {integrity: sha512-Is95G1wqNvEUJZ9DITRS2zfMwVJRZztMduPs1vJJ0cm65WUg/avBl5vBXjHycQL/qmFpaqa3NG4qWnf7bCHPag==} + peerDependencies: + svelte: ^3.24 + typescript: ^4.1.2 + dependencies: + dedent-js: 1.0.1 + pascal-case: 3.1.2 + svelte: 3.49.0 + dev: false + /svelte2tsx/0.5.11_ueozcsexptisi2awlbuwt6eqmq: resolution: {integrity: sha512-Is95G1wqNvEUJZ9DITRS2zfMwVJRZztMduPs1vJJ0cm65WUg/avBl5vBXjHycQL/qmFpaqa3NG4qWnf7bCHPag==} peerDependencies: From 10c7d8151c1126735e683482d350c412f84f1898 Mon Sep 17 00:00:00 2001 From: Princesseuh Date: Fri, 8 Jul 2022 13:01:38 -0400 Subject: [PATCH 2/5] Use astro-scripts instead of tsc --- packages/integrations/svelte/editor/tsconfig.json | 10 ---------- packages/integrations/svelte/package.json | 4 ++-- .../integrations/svelte/{editor => src}/editor.cts | 0 packages/integrations/vue/editor/tsconfig.json | 10 ---------- packages/integrations/vue/package.json | 4 ++-- packages/integrations/vue/{editor => src}/editor.cts | 0 scripts/cmd/build.js | 12 ++++++++++-- 7 files changed, 14 insertions(+), 26 deletions(-) delete mode 100644 packages/integrations/svelte/editor/tsconfig.json rename packages/integrations/svelte/{editor => src}/editor.cts (100%) delete mode 100644 packages/integrations/vue/editor/tsconfig.json rename packages/integrations/vue/{editor => src}/editor.cts (100%) diff --git a/packages/integrations/svelte/editor/tsconfig.json b/packages/integrations/svelte/editor/tsconfig.json deleted file mode 100644 index 7e1f9d0ca879..000000000000 --- a/packages/integrations/svelte/editor/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../../../tsconfig.base.json", - "compilerOptions": { - "allowJs": true, - "emitDeclarationOnly": false, - "module": "CommonJS", - "outDir": "../dist", - "target": "ES2020" - } -} diff --git a/packages/integrations/svelte/package.json b/packages/integrations/svelte/package.json index d2991d00bf00..7688b2024088 100644 --- a/packages/integrations/svelte/package.json +++ b/packages/integrations/svelte/package.json @@ -27,8 +27,8 @@ "./package.json": "./package.json" }, "scripts": { - "build": "astro-scripts build \"src/**/*.ts\" && tsc && tsc -p ./editor/tsconfig.json", - "build:ci": "astro-scripts build \"src/**/*.ts\"", + "build": "astro-scripts build \"src/index.ts\" && astro-scripts build \"src/editor.cts\" --force-cjs --no-clean-dist && tsc", + "build:ci": "astro-scripts build \"src/**/*.ts\" && astro-scripts build \"src/editor.cts\" --force-cjs --no-clean-dist", "dev": "astro-scripts dev \"src/**/*.ts\"" }, "dependencies": { diff --git a/packages/integrations/svelte/editor/editor.cts b/packages/integrations/svelte/src/editor.cts similarity index 100% rename from packages/integrations/svelte/editor/editor.cts rename to packages/integrations/svelte/src/editor.cts diff --git a/packages/integrations/vue/editor/tsconfig.json b/packages/integrations/vue/editor/tsconfig.json deleted file mode 100644 index 7e1f9d0ca879..000000000000 --- a/packages/integrations/vue/editor/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../../../tsconfig.base.json", - "compilerOptions": { - "allowJs": true, - "emitDeclarationOnly": false, - "module": "CommonJS", - "outDir": "../dist", - "target": "ES2020" - } -} diff --git a/packages/integrations/vue/package.json b/packages/integrations/vue/package.json index 74503cc20943..3185237f347e 100644 --- a/packages/integrations/vue/package.json +++ b/packages/integrations/vue/package.json @@ -27,8 +27,8 @@ "./package.json": "./package.json" }, "scripts": { - "build": "astro-scripts build \"src/**/*.ts\" && tsc && tsc -p ./editor/tsconfig.json", - "build:ci": "astro-scripts build \"src/**/*.ts\"", + "build": "astro-scripts build \"src/index.ts\" && astro-scripts build \"src/editor.cts\" --force-cjs --no-clean-dist && tsc", + "build:ci": "astro-scripts build \"src/**/*.ts\" && astro-scripts build \"src/editor.cts\" --force-cjs --no-clean-dist", "dev": "astro-scripts dev \"src/**/*.ts\"" }, "dependencies": { diff --git a/packages/integrations/vue/editor/editor.cts b/packages/integrations/vue/src/editor.cts similarity index 100% rename from packages/integrations/vue/editor/editor.cts rename to packages/integrations/vue/src/editor.cts diff --git a/scripts/cmd/build.js b/scripts/cmd/build.js index 764b26eeda3d..5d59f5180127 100644 --- a/scripts/cmd/build.js +++ b/scripts/cmd/build.js @@ -47,6 +47,9 @@ export default async function build(...args) { )) ); + const noClean = args.includes('--no-clean-dist'); + const forceCJS = args.includes('--force-cjs'); + const { type = 'module', version, @@ -54,9 +57,13 @@ export default async function build(...args) { } = await fs.readFile('./package.json').then((res) => JSON.parse(res.toString())); // expose PACKAGE_VERSION on process.env for CLI utils config.define = { 'process.env.PACKAGE_VERSION': JSON.stringify(version) }; - const format = type === 'module' ? 'esm' : 'cjs'; + const format = type === 'module' && !forceCJS ? 'esm' : 'cjs'; + const outdir = 'dist'; - await clean(outdir); + + if (!noClean) { + await clean(outdir); + } if (!isDev) { await esbuild.build({ @@ -64,6 +71,7 @@ export default async function build(...args) { bundle: false, entryPoints, outdir, + outExtension: forceCJS ? { '.js': '.cjs' } : {}, format, }); return; From 144752416b5b93449e135fa986539043c2d6d2b5 Mon Sep 17 00:00:00 2001 From: Princesseuh Date: Fri, 8 Jul 2022 13:25:26 -0400 Subject: [PATCH 3/5] Make TypeScript an optional peerDep for svelte2tsx --- packages/integrations/svelte/package.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/integrations/svelte/package.json b/packages/integrations/svelte/package.json index 7688b2024088..09a2c7bc21af 100644 --- a/packages/integrations/svelte/package.json +++ b/packages/integrations/svelte/package.json @@ -48,5 +48,16 @@ }, "engines": { "node": "^14.15.0 || >=16.0.0" + }, + "pnpm": { + "packageExtensions": { + "svelte2tsx": { + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + } + } } } From 9f02775c06dfaee98501794b8db3c4e335eccbc3 Mon Sep 17 00:00:00 2001 From: Princesseuh Date: Fri, 8 Jul 2022 13:31:05 -0400 Subject: [PATCH 4/5] Putting it in the proper place should work better --- package.json | 9 +++++++++ packages/integrations/svelte/package.json | 11 ----------- pnpm-lock.yaml | 8 ++++++++ 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index ee49bddefab6..06c40e400d68 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,15 @@ }, "packageManager": "pnpm@7.5.0", "pnpm": { + "packageExtensions": { + "svelte2tsx": { + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + } + }, "peerDependencyRules": { "ignoreMissing": [ "rollup", diff --git a/packages/integrations/svelte/package.json b/packages/integrations/svelte/package.json index 09a2c7bc21af..7688b2024088 100644 --- a/packages/integrations/svelte/package.json +++ b/packages/integrations/svelte/package.json @@ -48,16 +48,5 @@ }, "engines": { "node": "^14.15.0 || >=16.0.0" - }, - "pnpm": { - "packageExtensions": { - "svelte2tsx": { - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - } - } } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 55f283bfa9b8..34ab70e17090 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,5 +1,7 @@ lockfileVersion: 5.4 +packageExtensionsChecksum: 01871422d489547c532184effb134b35 + patchedDependencies: '@changesets/cli@2.23.0': hash: kcozqtpxuwjzskw6zg5royevn4 @@ -14274,6 +14276,9 @@ packages: peerDependencies: svelte: ^3.24 typescript: ^4.1.2 + peerDependenciesMeta: + typescript: + optional: true dependencies: dedent-js: 1.0.1 pascal-case: 3.1.2 @@ -14285,6 +14290,9 @@ packages: peerDependencies: svelte: ^3.24 typescript: ^4.1.2 + peerDependenciesMeta: + typescript: + optional: true dependencies: dedent-js: 1.0.1 pascal-case: 3.1.2 From 66ab23be60847558c814973cb6704ce0fa0233b1 Mon Sep 17 00:00:00 2001 From: Princesseuh Date: Fri, 8 Jul 2022 13:46:48 -0400 Subject: [PATCH 5/5] Add changeset --- .changeset/nasty-students-run.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/nasty-students-run.md diff --git a/.changeset/nasty-students-run.md b/.changeset/nasty-students-run.md new file mode 100644 index 000000000000..e83afd915a43 --- /dev/null +++ b/.changeset/nasty-students-run.md @@ -0,0 +1,6 @@ +--- +'@astrojs/svelte': patch +'@astrojs/vue': patch +--- + +Add entrypoints for editor support for Vue and Svelte (destined to be used by our language server)