-1

EDIT: This question is outdated. As of 12.8.2022, svelte-kit package https://kit.svelte.dev/docs/packaging, is the recommended option.

I created a library (https://github.com/TeemuKoivisto/svelte-tree-view) which I import in another project as a Svelte component. Which works fine linked locally (yarn link svelte-tree-view) but when I use the npm downloaded version inside my node_modules, I get this extremely weird error:

[!] (plugin svelte) ValidationError: The $ prefix is reserved, and cannot be used for variable and import names
../node_modules/svelte-tree-view/src/TreeView.svelte
77:     rootElementStore.set(rootElement);
78: });
79: var $$$$$$$$ = null;
    ^
80: var $$vars$$ = [$$props, rootElement, $treeStore, treeStore, TreeNode_svelte_1.default];</script>

Which is quite difficult to debug as there isn't much discussion or blog posts out there. Anyway, I surprised myself and finally solved it with a quite simple solution and I want to make this post to help others out there. Here are the most important libraries related to this problem:

    "rollup": "^2.56.3",
    "rollup-plugin-svelte": "^7.1.0",
    "rollup-plugin-ts": "^1.4.2",
    "svelte": "^3.42.6",
    "svelte-preprocess": "^4.9.4",
    "tslib": "^2.3.1",
    "typescript": "^4.4.3"
TeemuK
  • 2,095
  • 1
  • 18
  • 17

2 Answers2

1

The specific error you are getting is likely fixed with svelte-preprocess version 4.9.5 . It's likely not finding your tsconfig.json as that one is tried to find from the file going up, and maybe you are in a monorepo where your node_modules are above the project with the tsconfig.json in question.

But as you said, this all comes down to providing an unpreprocessed version of the library, which should not be done, as you force everyone who wants to use your library to setup TypeScript preprocessing + you run into weird errors like yours.

Fortunately, SvelteKit has you covered with its packaging command. It will preprocess Svelte files (JS/HTML/CSS afterwards) and also handle TS->JS transpilation. It will also output type definitions files (d.ts) of these files. So you can keep writing your library using TS and provide a consumable package for everyone. More info: https://kit.svelte.dev/docs#packaging

dummdidumm
  • 4,828
  • 15
  • 26
  • Hey, thanks for the explanation! I did actually proceed to convert the library to use SvelteKit package command. However, I still receive errors when I try to import it from a Svelte project without that tsconfig hack. Also hopefully that command gets incorporated to bundler pipelines as now I'm manipulating the exports block myself (to eg simulate rollup watch by setting the main export to the raw index.ts). But all in all, nice work - too bad I cant spend my time helping more – TeemuK Sep 23 '21 at 08:28
  • Try packaging the library with the latest SvelteKit version. The error might stem from the fact that the `lang="ts"` tag was not removed before, which caused `svelte-preprocess` to preprocess the file again. – dummdidumm Sep 25 '21 at 20:56
  • The new version (next.174) does remove the lang tag which now makes it work for my TS Svelte project without having to add that typescript block to `svelte.config.js`. Yet in another Svelte project that is JS-only, it still throws `Cannot read properties of undefined (reading '$$')`. I wonder what's up with that. – TeemuK Sep 27 '21 at 05:24
  • Also as I was messing around with importing the library, I noticed that using it outside of svelte is not really supported. Say in a TS React app. Because the svelte types are not loaded without them being a dependency which would break things and in general, be an unnecessary burden (as they are bundled together with the source). – TeemuK Sep 30 '21 at 05:49
  • Okay, well the types work when you install svelte as a devDependency regardless of the framework you are using. Good enough! – TeemuK Sep 30 '21 at 06:04
0

Well, the answer is adding typescript block to your svelte.config.js that defines a tsconfigFile. Why you need it, somewhat unclear still to me, but I'm glad it works.

The full svelte.config.js:

const autoPreprocess = require('svelte-preprocess')

const preprocessOptions = {
  scss: { prependData: `@import 'src/global.scss';` },
  typescript: {
    tsconfigFile: './tsconfig.json'
  }
}

module.exports = {
  preprocess: autoPreprocess(preprocessOptions),
  preprocessOptions
}

EDIT: Looking at the problem more closely, apparently it's not recommended to create TypeScript Svelte libraries. https://github.com/sveltejs/component-template/issues/29#issuecomment-905481560 Which means I have to waste even more time on this. Oh the humanity..

TeemuK
  • 2,095
  • 1
  • 18
  • 17