Skip to content

Commit

Permalink
(feat) support ESM configs (#930)
Browse files Browse the repository at this point in the history
Config loading switches to using dynamic import statements. Commit consists of:
- rework of the config loader to make sure to not load the same config twice in parallel, and to load all possible sub-svelte-configs upon tsconfig initialization, so that all configs are available synchronously to all snapshots that are retrieved. throwing out cosmiconfig in that process.
- resulting tedious "make this function async" modifications since the ts service initialization is now async
  • Loading branch information
dummdidumm authored Apr 6, 2021
1 parent 562c944 commit 78df663
Show file tree
Hide file tree
Showing 26 changed files with 555 additions and 164 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ jobs:
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: "12.x"

- name: Get yarn cache directory path
id: yarn-cache-dir-path
Expand Down Expand Up @@ -37,6 +39,8 @@ jobs:
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: "12.x"

- name: Get yarn cache directory path
id: yarn-cache-dir-path
Expand Down
2 changes: 1 addition & 1 deletion docs/preprocessors/in-general.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

If a svelte file contains some language other than `html`, `css` or `javascript`, `svelte-vscode` needs to know how to [preprocess](https://svelte.dev/docs#svelte_preprocess) it. This can be achieved by creating a `svelte.config.js` file at the root of your project which exports a svelte options object (similar to `svelte-loader` and `rollup-plugin-svelte`). It's recommended to use the official [svelte-preprocess](https://github.com/sveltejs/svelte-preprocess) package which can handle many languages.

> NOTE: you **cannot** use the new `import x from y` and `export const` / `export default` syntax in `svelte.config.js`.
> NOTE: Prior to `svelte-check 1.4.0` / `svelte-language-server 0.13.0` / `Svelte for VS Code 104.9.0` you **cannot** use the new `import x from y` and `export const` / `export default` syntax in `svelte.config.js`.
```js
// svelte.config.js
Expand Down
9 changes: 6 additions & 3 deletions packages/language-server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "svelte-language-server",
"version": "0.12.0",
"version": "0.13.0",
"description": "A language server for Svelte",
"main": "dist/src/index.js",
"typings": "dist/src/index",
Expand Down Expand Up @@ -30,10 +30,13 @@
"url": "https://github.com/sveltejs/language-tools/issues"
},
"homepage": "https://github.com/sveltejs/language-tools#readme",
"engines": {
"node": ">= 12.0.0"
},
"devDependencies": {
"@tsconfig/node12": "^1.0.0",
"@types/cosmiconfig": "^6.0.0",
"@types/estree": "^0.0.42",
"@types/glob": "^7.1.1",
"@types/lodash": "^4.14.116",
"@types/mocha": "^7.0.2",
"@types/node": "^13.9.0",
Expand All @@ -47,8 +50,8 @@
},
"dependencies": {
"chokidar": "^3.4.1",
"cosmiconfig": "^7.0.0",
"estree-walker": "^2.0.1",
"glob": "^7.1.6",
"lodash": "^4.17.19",
"prettier": "2.2.1",
"prettier-plugin-svelte": "~2.2.0",
Expand Down
49 changes: 35 additions & 14 deletions packages/language-server/src/lib/documents/Document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { urlToPath } from '../../utils';
import { WritableDocument } from './DocumentBase';
import { extractScriptTags, extractStyleTag, TagInformation } from './utils';
import { parseHtml } from './parseHtml';
import { SvelteConfig, loadConfig } from './configLoader';
import { SvelteConfig, configLoader } from './configLoader';
import { HTMLDocument } from 'vscode-html-languageservice';

/**
Expand All @@ -13,23 +13,42 @@ export class Document extends WritableDocument {
scriptInfo: TagInformation | null = null;
moduleScriptInfo: TagInformation | null = null;
styleInfo: TagInformation | null = null;
config!: SvelteConfig;
configPromise: Promise<SvelteConfig | undefined>;
config?: SvelteConfig;
html!: HTMLDocument;

constructor(public url: string, public content: string) {
super();
this.configPromise = configLoader.awaitConfig(this.getFilePath() || '');
this.updateDocInfo();
}

private updateDocInfo() {
if (!this.config || this.config.loadConfigError) {
this.config = loadConfig(this.getFilePath() || '');
}
this.html = parseHtml(this.content);
const scriptTags = extractScriptTags(this.content, this.html);
this.scriptInfo = this.addDefaultLanguage(scriptTags?.script || null, 'script');
this.moduleScriptInfo = this.addDefaultLanguage(scriptTags?.moduleScript || null, 'script');
this.styleInfo = this.addDefaultLanguage(extractStyleTag(this.content, this.html), 'style');
const update = (config: SvelteConfig | undefined) => {
this.config = config;
this.scriptInfo = this.addDefaultLanguage(config, scriptTags?.script || null, 'script');
this.moduleScriptInfo = this.addDefaultLanguage(
config,
scriptTags?.moduleScript || null,
'script'
);
this.styleInfo = this.addDefaultLanguage(
config,
extractStyleTag(this.content, this.html),
'style'
);
};

const config = configLoader.getConfig(this.getFilePath() || '');
if (config && !config.loadConfigError) {
update(config);
} else {
this.configPromise = configLoader.awaitConfig(this.getFilePath() || '');
update(undefined);
this.configPromise.then((c) => update(c));
}
}

/**
Expand Down Expand Up @@ -76,17 +95,19 @@ export class Document extends WritableDocument {
}

private addDefaultLanguage(
config: SvelteConfig | undefined,
tagInfo: TagInformation | null,
tag: 'style' | 'script'
): TagInformation | null {
if (!tagInfo) {
return null;
if (!tagInfo || !config) {
return tagInfo;
}

const defaultLang = Array.isArray(this.config.preprocess)
? this.config.preprocess.find((group) => group.defaultLanguages?.[tag])
?.defaultLanguages?.[tag]
: this.config.preprocess?.defaultLanguages?.[tag];
const defaultLang = Array.isArray(config.preprocess)
? config.preprocess.find((group) => group.defaultLanguages?.[tag])?.defaultLanguages?.[
tag
]
: config.preprocess?.defaultLanguages?.[tag];

if (!tagInfo.attributes.lang && !tagInfo.attributes.type && defaultLang) {
tagInfo.attributes.lang = defaultLang;
Expand Down
Loading

0 comments on commit 78df663

Please sign in to comment.