Skip to content

Commit

Permalink
fix typescript bundling for svelte2tsx, config loading (#3514)
Browse files Browse the repository at this point in the history
  • Loading branch information
acao committed Jan 25, 2024
1 parent a562c96 commit 36c7f25
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 40 deletions.
10 changes: 10 additions & 0 deletions .changeset/new-tips-sneeze.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'graphql-language-service-server': patch
'vscode-graphql': patch
---

fix svelte parsing, re-load config only on config changes

- fix esbuild bundling of `typescript` for `svelte2tsx`!
- confirm with manual testing of the vsix extension bundle ✅
- ensure that the server only attemps to parse opened/saved files when the server is activated or the file is a config file
4 changes: 3 additions & 1 deletion packages/graphql-language-service-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,12 @@
"nullthrows": "^1.0.0",
"source-map-js": "1.0.2",
"svelte": "^4.1.1",
"svelte2tsx": "^0.7.0",
"vscode-jsonrpc": "^8.0.1",
"vscode-languageserver": "^8.0.1",
"vscode-languageserver-types": "^3.17.2",
"vscode-uri": "^3.0.2"
"vscode-uri": "^3.0.2",
"typescript": "^5.3.3"
},
"devDependencies": {
"@types/glob": "^8.1.0",
Expand Down
56 changes: 31 additions & 25 deletions packages/graphql-language-service-server/src/MessageProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,9 @@ export class MessageProcessor {
require('dotenv').config({ path: settings.dotEnvPath });
}
this._settings = { ...settings, ...vscodeSettings };
const rootDir =
this._settings?.load?.rootDir ??
this._loadConfigOptions?.rootDir ??
this._rootPath;
const rootDir = this._settings?.load?.rootDir.length
? this._settings?.load?.rootDir
: this._rootPath;
this._rootPath = rootDir;
this._loadConfigOptions = {
...Object.keys(this._settings?.load ?? {}).reduce((agg, key) => {
Expand All @@ -247,9 +246,9 @@ export class MessageProcessor {
this._graphQLCache,
this._logger,
);
if (this._graphQLCache?.getGraphQLConfig()) {
const config = (this._graphQLConfig =
this._graphQLCache.getGraphQLConfig());
if (this._graphQLConfig || this._graphQLCache?.getGraphQLConfig) {
const config =
this._graphQLConfig ?? this._graphQLCache.getGraphQLConfig();
await this._cacheAllProjectFiles(config);
}
this._isInitialized = true;
Expand Down Expand Up @@ -296,6 +295,24 @@ export class MessageProcessor {
`\nfor more information on using 'graphql-config' with 'graphql-language-service-server', \nsee the documentation at ${configDocLink}`,
);
}
async _isGraphQLConfigFile(uri: string) {
const configMatchers = ['graphql.config', 'graphqlrc', 'graphqlconfig'];
if (this._settings?.load?.fileName?.length) {
configMatchers.push(this._settings.load.fileName);
}

const fileMatch = configMatchers
.filter(Boolean)
.some(v => uri.match(v)?.length);
if (fileMatch) {
return fileMatch;
}
if (uri.match('package.json')?.length) {
const graphqlConfig = await import(URI.parse(uri).fsPath);
return Boolean(graphqlConfig?.graphql);
}
return false;
}

async handleDidOpenOrSaveNotification(
params: DidSaveTextDocumentParams | DidOpenTextDocumentParams,
Expand All @@ -304,13 +321,16 @@ export class MessageProcessor {
* Initialize the LSP server when the first file is opened or saved,
* so that we can access the user settings for config rootDir, etc
*/
const isGraphQLConfigFile = await this._isGraphQLConfigFile(
params.textDocument.uri,
);
try {
if (!this._isInitialized || !this._graphQLCache) {
// don't try to initialize again if we've already tried
// and the graphql config file or package.json entry isn't even there
// if (this._isGraphQLConfigMissing === true) {
// return null;
// }
if (this._isGraphQLConfigMissing === true && !isGraphQLConfigFile) {
return null;
}
// then initial call to update graphql config
await this._updateGraphQLConfig();
}
Expand Down Expand Up @@ -343,21 +363,7 @@ export class MessageProcessor {

await this._invalidateCache(textDocument, uri, contents);
} else {
const configMatchers = [
'graphql.config',
'graphqlrc',
'graphqlconfig',
].filter(Boolean);
if (this._settings?.load?.fileName) {
configMatchers.push(this._settings.load.fileName);
}

const hasGraphQLConfigFile = configMatchers.some(
v => uri.match(v)?.length,
);
const hasPackageGraphQLConfig =
uri.match('package.json')?.length && require(uri)?.graphql;
if (hasGraphQLConfigFile || hasPackageGraphQLConfig) {
if (isGraphQLConfigFile) {
this._logger.info('updating graphql config');
await this._updateGraphQLConfig();
return { uri, diagnostics: [] };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,7 @@ query {id}`);
`);

expect(JSON.stringify(contents[0].range)).toEqual(
// TODO: change back to 29 when we get svelte parser working again
JSON.stringify(new Range(new Position(2, 27), new Position(12, 0))),
JSON.stringify(new Range(new Position(2, 29), new Position(12, 0))),
);
});

Expand Down Expand Up @@ -488,4 +487,46 @@ export function Example(arg: string) {}`;
const contents = findGraphQLTags(text, '.js');
expect(contents.length).toEqual(0);
});
it('handles full svelte example', () => {
const text = `
<script>
import { ApolloClient, gql } from '@apollo/client';
import { setClient, getClient, query } from 'svelte-apollo';
import { onMount } from 'svelte';
let country;
const QUERY = gql\`
query GetCountryData {
countries(namePrefix: "America") {
edges {
node {
name
flagImageUri
}
}
}
}
\`;
const client = new ApolloClient({
uri: 'https://geodb-cities-graphql.p.rapidapi.com/',
});
setClient(client);
onMount(async () => {
const response = query(client, { query: QUERY });
country = response.data;
});
</script>
<div>
{#if country}
<h2>
{country.name}
</h2>
<img src={country.flagImageUri} alt="Country Flag" />
{:else}
<p>loading...</p>
{/if}
</div>
`;
const contents = findGraphQLTags(text, '.svelte');
expect(contents.length).toEqual(1);
});
});
10 changes: 3 additions & 7 deletions packages/graphql-language-service-server/src/findGraphQLTags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ import { Position, Range } from 'graphql-language-service';

import { TAG_MAP } from './constants';
import { ecmaParser, tsParser } from './parsers/babel';
// import { svelteParser } from './parsers/svelte';
import { vueParser } from './parsers/vue';
import { astroParser } from './parsers/astro';
import type { Logger, NoopLogger } from './Logger';
import { RangeMapper } from './parsers/types';
import { svelteParser } from './parsers/svelte';

type TagResult = { tag: string; template: string; range: Range };

Expand All @@ -41,9 +41,7 @@ const parserMap = {
'.tsx': tsParser,
'.cts': tsParser,
'.mts': tsParser,
// disabled for now, until we can figure out how to get svelte2tsx working in esbuild bundle
// '.svelte': svelteParser,
'.svelte': vueParser,
'.svelte': svelteParser,
'.vue': vueParser,
'.astro': astroParser,
};
Expand Down Expand Up @@ -90,7 +88,6 @@ export function findGraphQLTags(
if (parsed) {
result.push(parsed);
}
return;
}
}

Expand Down Expand Up @@ -133,7 +130,7 @@ export function findGraphQLTags(
// check if the template literal is prefixed with #graphql
const hasGraphQLPrefix =
node.quasis[0].value.raw.startsWith('#graphql\n');
// check if the template expression has
// check if the template expression has /* GraphQL */ comment
const hasGraphQLComment = Boolean(
node.leadingComments?.[0]?.value.match(/^\s*GraphQL\s*$/),
);
Expand All @@ -148,7 +145,6 @@ export function findGraphQLTags(
for (const ast of asts) {
visit(ast, visitors);
}

return result;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { babelParser } from './babel';
// TODO: Remove this when we have a working svelte parsing implementation
// eslint-disable-next-line import/no-extraneous-dependencies
import { svelte2tsx } from 'svelte2tsx';
import { SourceMapConsumer } from 'source-map-js';
import { Position, Range } from 'graphql-language-service';
Expand Down Expand Up @@ -32,7 +30,6 @@ export const svelteParser: SourceParser = (text, uri, logger) => {
new Position(end.line, end.column),
);
};

try {
return {
asts: [babelParser(svelteResult.code, ['typescript'])],
Expand Down
3 changes: 2 additions & 1 deletion packages/vscode-graphql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@
"dependencies": {
"graphql": "^16.8.1",
"graphql-language-service-server": "^2.11.10",
"vscode-languageclient": "8.0.2"
"vscode-languageclient": "8.0.2",
"typescript": "^5.3.3"
}
}
15 changes: 14 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2387,7 +2387,7 @@
"@babel/parser" "^7.12.13"
"@babel/types" "^7.12.13"

"@babel/traverse@^7.16.8", "@babel/traverse@^7.17.3", "@babel/traverse@^7.20.5", "@babel/traverse@^7.20.7", "@babel/traverse@^7.21.0", "@babel/traverse@^7.21.2", "@babel/traverse@^7.22.5", "@babel/traverse@^7.22.6", "@babel/traverse@^7.22.8", "@babel/traverse@^7.23.7", "@babel/traverse@^7.7.2":
"@babel/traverse@^7.16.8", "@babel/traverse@^7.17.3", "@babel/traverse@^7.20.5", "@babel/traverse@^7.20.7", "@babel/traverse@^7.21.0", "@babel/traverse@^7.21.2", "@babel/traverse@^7.22.5", "@babel/traverse@^7.22.6", "@babel/traverse@^7.22.8", "@babel/traverse@^7.23.2", "@babel/traverse@^7.23.7", "@babel/traverse@^7.7.2":
version "7.23.7"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.7.tgz#9a7bf285c928cb99b5ead19c3b1ce5b310c9c305"
integrity sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==
Expand Down Expand Up @@ -18452,6 +18452,14 @@ svelte2tsx@^0.6.16:
dedent-js "^1.0.1"
pascal-case "^3.1.1"

svelte2tsx@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/svelte2tsx/-/svelte2tsx-0.7.0.tgz#ac7b39f8b5fb9fe20994dfbce71c2d2442fb478e"
integrity sha512-qAelcydnmuiDvD1HsrWi23RWx24RZTKRv6n4JaGC/pkoJfbLkJPQT2wa1qN0ZyfKTNLSyoj2FW9z62l/AUzUNA==
dependencies:
dedent-js "^1.0.1"
pascal-case "^3.1.1"

svelte@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/svelte/-/svelte-4.1.1.tgz#468ed0377d3cae542b35df8a22a3ca188d93272a"
Expand Down Expand Up @@ -19048,6 +19056,11 @@ typescript@^4.6.3:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9"
integrity sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==

typescript@^5.3.3:
version "5.3.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37"
integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==

ua-parser-js@^1.0.2:
version "1.0.33"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.33.tgz#f21f01233e90e7ed0f059ceab46eb190ff17f8f4"
Expand Down

0 comments on commit 36c7f25

Please sign in to comment.