component-template icon indicating copy to clipboard operation
component-template copied to clipboard

Add a TypeScript component template

Open devrnt opened this issue 5 years ago • 19 comments
trafficstars

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.

devrnt avatar Jul 15 '20 20:07 devrnt

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: true in the output entries in rollup.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

devrnt avatar Jul 15 '20 21:07 devrnt

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)

jnordberg avatar Jul 26 '20 12:07 jnordberg

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.

devrnt avatar Jul 26 '20 13:07 devrnt

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

jnordberg avatar Jul 26 '20 13:07 jnordberg

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

This works and it's really weird that @rollup/plugin-typescipt is throwing that error.

jerriclynsjohn avatar Sep 07 '20 20:09 jerriclynsjohn

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.

daaku avatar Sep 21 '20 13:09 daaku

It would also be great to understand what definitions to extend for component development.

From @svelte/types?

frederikhors avatar Sep 21 '20 18:09 frederikhors

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 avatar Sep 21 '20 19:09 devrnt

@devrnt I managed to get types outputted, but not for the .svelte files. Seems like that's a known limitation for now?

daaku avatar Sep 22 '20 05:09 daaku

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.

dummdidumm avatar Sep 22 '20 07:09 dummdidumm

@devrnt I managed to get types outputted, but not for the .svelte files. Seems like that's a known limitation for now?

Can I ask you how, please, @daaku?

frederikhors avatar Sep 22 '20 07:09 frederikhors

For non .svelte files I added this to get types:

typescript({
  declaration: true,
  declarationDir: 'dist/types',
  rootDir: 'src'
}),

daaku avatar Sep 22 '20 12:09 daaku

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.

vigenere23 avatar Oct 06 '20 14:10 vigenere23

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.

mattjennings avatar Oct 20 '20 03:10 mattjennings

Nice one! Can't wait to try it!

vigenere23 avatar Oct 20 '20 12:10 vigenere23

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

jmsunseri avatar Feb 01 '21 01:02 jmsunseri

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

dummdidumm avatar Aug 25 '21 13:08 dummdidumm

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.

colinbate avatar Aug 30 '21 18:08 colinbate

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.

TeemuKoivisto avatar Sep 22 '21 19:09 TeemuKoivisto