component-template
component-template copied to clipboard
Add a TypeScript component template
Is your feature request related to a problem? Please describe.
Many people want to use Svelte with TypeScript. With svelte-preprocess, a fitting rollup-config and Svelte extension from VSCode this is working good already.
Describe the solution you'd like
Add a sveltejs/typescript-component-template similar to https://github.com/sveltejs/component-template.
How important is this feature to you? Important to get the word out that Svelte supports TypeScript in the component-template as well.
Related issues
This issue is based on the issue in the svelte/svelte repository. The app-template is already "migrated" to TypeScript, but this issue addresses the component-template.
I've "migrated" this component template to support TypeScript: https://github.com/devrnt/component-template. This fork is ready to be used if TypeScript is desired.
Known warnings when building (and solutions)
- Plugin typescript: @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.
Set
sourcemap: truein theoutputentries inrollup.config.js
Possible improvements
- Out-of-the-box terser integration in production
- Integration of linter and formatter
- Integration of https://github.com/testing-library/svelte-testing-library
I'm having troubles with this template, I built a component using it (https://github.com/jnordberg/svelte-qr) and it works fine when installing it locally (in a svelte typescript template project) with yarn link but when installing it from npm (it is published under svelte-qr) I get the following error:
bundles src/main.ts → public/build/bundle.js...
[!] (plugin typescript) Error: Could not load myproject/node_modules/svelte-qr/src/index.ts (imported by src/pages/login.svelte): Debug Failure. False expression: Expected fileName to be present in command line
Error: Could not load myproject/node_modules/svelte-qr/src/index.ts (imported by src/pages/login.svelte): Debug Failure. False expression: Expected fileName to be present in command line
at Object.getOutputFileNames (myproject/node_modules/typescript/lib/typescript.js:94573:18)
at findTypescriptOutput (myproject/node_modules/@rollup/plugin-typescript/dist/index.js:392:33)
at Object.load (myproject/node_modules/@rollup/plugin-typescript/dist/index.js:594:28)
Looks like svelte is trying to use the svelte entry in your package.json which allows Svelte apps to import the source code directly.
Does it work if you remove the svelte entry in your package.json? I guess this should be updated in the TypeScript component template.
If I remove the svelte entry it works. Strange part is that the exact same code works fine when symlinked into node_modules...
However I was able to get it to work by changing typescript rollup plugin in the project consuming svelte-qr. Switching from import typescript from '@rollup/plugin-typescript' to import typescript from '@wessberg/rollup-plugin-ts' in my rollup.config.js
If I remove the
svelteentry it works. Strange part is that the exact same code works fine when symlinked into node_modules...However I was able to get it to work by changing typescript rollup plugin in the project consuming svelte-qr. Switching from
import typescript from '@rollup/plugin-typescript'toimport typescript from '@wessberg/rollup-plugin-ts'in my rollup.config.js
This works and it's really weird that @rollup/plugin-typescipt is throwing that error.
Removing svelte from package.json works for me as well, but the build setup from https://github.com/devrnt/component-template doesn't seem to output typings? @devrnt am I using it wrong?
My current best guess is that tsconfig.json is generally not setup to include .ts files directly from node_modules, which is what causes the svelte directive to break the build. I don't know what benefits there would be to make that work, but outputting typings would at least provide the full benefit of using typescript.
It would also be great to understand what definitions to extend for component development.
From @svelte/types?
It has been a while since I've read any updates regarding TypeScript in Svelte (since the "official" TypeScript support). I think you should take a look at the docs of @rollup/plugin-typescript for the declaration files. @daaku
@devrnt I managed to get types outputted, but not for the .svelte files. Seems like that's a known limitation for now?
Auto-generation of d.ts files / types for .svelte files is not supported yet. There is an open RFC which will make authoring those easier though.
@devrnt I managed to get types outputted, but not for the
.sveltefiles. Seems like that's a known limitation for now?
Can I ask you how, please, @daaku?
For non .svelte files I added this to get types:
typescript({
declaration: true,
declarationDir: 'dist/types',
rootDir: 'src'
}),
Same problem here! I think this really needs to be addressed, since it seems to be documented nowhere and caused me at least 5 hours of searching (originally had another error message from a local yarn link that gave no results).
The solution from @jnordberg about replacing @rollup/plugin-typescript with @wessberg/rollup-plugin-ts is what worked 100% for me (thank you omg).
For @devrnt's solution, removing the svelte entry from package.json effectively removed the error message and fixed the compilation. However, it broke the html-ref bindings (bind:this directive), resulting in null variables. It also broke the hot-reloading, since without that svelte entry, Svelte takes the components for the compiled js file in the build folder.
I also saw https://github.com/rollup/plugins/issues/282 (which seems to define the same problem) and tried the given solution (moving the resolve before the svelte one), and it did exactly the same as removing the svelte entry.
Anyway, I really think this should be moved to a separate issue since it's unclear if it's related to Svelte itself or to the typescript plugin, and it seems to be more a bug that just a misconfiguration or something.
I've made a component template that supports the svelte entry for both javascript and typescript consumers: https://github.com/mattjennings/svelte-typescript-component-template
It does this by preprocessing the .svelte components and using that for the svelte entry, but keeps the types pointing to the unprocessed components for type safety.
Nice one! Can't wait to try it!
I used this template without modification and consume in in a svelte-kit project by using yarn link and I get the following error
500
<Component> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules
Error: <Component> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules
at Object.validate_component (/_snowpack/pkg/svelte/internal.js:1345:15)
at eval (/_app/routes/index.svelte.js:18:86)
at Object.$$render (/_snowpack/pkg/svelte/internal.js:1368:22)
at Object.default (/_app/assets/generated/root.svelte.js:61:103)
at eval (/_app/assets/components/layout.svelte.js:7:41)
at Object.$$render (/_snowpack/pkg/svelte/internal.js:1368:22)
at eval (/_app/assets/generated/root.svelte.js:58:50)
at $$render (/_snowpack/pkg/svelte/internal.js:1368:22)
at Object.render (/_snowpack/pkg/svelte/internal.js:1376:26)
at get_response (/Users/jmsunseri/dev/code/byocss/docs/node_modules/@sveltejs/kit/src/renderer/page.js:238:27)
at render_page (/Users/jmsunseri/dev/code/byocss/docs/node_modules/@sveltejs/kit/src/renderer/page.js:339:9)
at Object.render (/Users/jmsunseri/dev/code/byocss/docs/node_modules/@sveltejs/kit/src/renderer/index.js:25:20)
at /Users/jmsunseri/dev/code/byocss/docs/node_modules/@sveltejs/kit/src/api/dev/index.js:172:22
To everyone who wants to place TypeScript files or Svelte files which require preprocessors inside node_modules: It is strongly advised to not do this. It's not officially supported and also places the burden of preprocessing your package on all your users. Instead you should preprocess Svelte files, transpile TS to JS and provide type definitions. More info: https://github.com/sveltejs/language-tools/blob/master/docs/preprocessors/typescript.md#typing-components-authoring-packages . SvelteKit's package command gives you these capabilities out of the box, so you should probably use that instead to author component libraries: https://svelte.dev/docs#Component_format
I can't speak for absolutely everyone, but I am approaching this from wanting to reference components in another sibling project (like in a monorepo) while maintaining HMR and other niceties.
If creating a component library with SvelteKit's package command (which I am) there are a couple of complications. You can add a local reference like "my-lib": "file:../my-lib/package" and this will work, assuming you've built your library at least once. However the package command doesn't have a watch mode, so you'll need to manually run it or set up your own watcher. And the other issue which interferes with even this is that the package command deletes the full package folder. This messes with the file watcher on the application side (at least on Windows) and the changes aren't recognized. You need to stop and restart the dev server to pick them up. This behavior can be fixed by deleting just the contents of the folder, but this would need to be patched in Svelte/kit.
It would be nice if this configuration was possible out of the box.
Hey, I refactored my tiny library from including the raw TS files to using the SvelteKit package command https://github.com/TeemuKoivisto/svelte-tree-view to compile it into JS. However, as I try to import the library in a project I still get weird errors if I try to run it without TS support:
[!] (plugin svelte) ValidationError: The $ prefix is reserved, and cannot be used for variable and import names
../node_modules/svelte-tree-view/package/TreeView.svelte
68: rootElementStore.set(rootElement);
69: });
70: var $$$$$$$$ = null;
^
71: var $$vars$$ = [$$props, rootElement, $treeStore, treeStore, TreeNode_svelte_1.default];</script>
Adding
typescript: {
tsconfigFile: './tsconfig.json'
}
to my svelte.config.js fixes this issue as I describe in a SO post. Also as a sidenote I had to make my own custom script to update my package.json instead of somehow publishing the outputted package folder (which seemed more difficult to do). Weirdly enough, the "scripts" block was totally gone from the package/package.json file.