sveltejs/rollup-plugin-svelte

Typescript files imported from a svelte component are ignored

Tokimon opened this issue · 3 comments

Hi

I have already reached out to the stack overflow community. But to me this seems like an actual issue as nothing I can come up with helps.

And please let me know if this is a more appropriate question for the svelte-preprocess team.

Context

I am trying to build an app with Svelte and Typescript using Rollup and when I try to build my Svelte components I just can't seem to make it compile my .ts files that are included from a .svelte component.

Problem

I keep getting this error:

[!] Error: Unexpected token (Note that you need plugins to import files that are not JavaScript)
src/ui/pages/files-page/utils/mapPaths.ts (1:12)
1: import type { PathMapping } from '~/types/path.d';
               ^

Which indicates to me that the .ts file imported from the .svelte file is not being interpreted correctly by Typescript.

I have been playing around with the order of the Rollup plugins but to no avail. They should be, as far as I understand, in the recommended order (except for maybe alias).

Setup

This is my FilesPage.svelte that includes the mapPaths.ts file:

<script lang="ts">
  import FileList from '~/ui/layouts/file-list/FileList.svelte';

  import mapPaths from './utils/mapPaths';

  export let paths: string[] = [];

  $: mappedPaths = mapPaths(paths);
</script>

<FileList paths={mappedPaths} />

and my mapPaths.ts file:

import type { PathMapping } from '~/types/path.d';

export default (paths: string[]): PathMapping => {
  const mapping = paths.reduce(
    (m, path) => {
      const root = path.replace(/_\d+$/, '');
      m.set(root, (m.get(root) || 0) + 1);
      return m;
    },
    new Map() as Map<string, number>
  );

  return Array.from(mapping.entries());
};

This is my rollup.config.js:

import typescript from '@rollup/plugin-typescript';
import nodeResolve from '@rollup/plugin-node-resolve';
import alias from '@rollup/plugin-alias';
import commonjs from 'rollup-plugin-commonjs';
import svelte from 'rollup-plugin-svelte';
import sveltePreprocess from 'svelte-preprocess';

export default {
  input: 'src/web.ts',

  output: {
    sourcemap: false,
    format: 'iife',
    name: 'app',
    file: 'build/web.js'
  },

  plugins: [
    svelte({
      preprocess: sveltePreprocess(),
      emitCss: false
    }),

    alias({
      entries: [
        { find: '~', replacement: 'src' }
      ]
    }),

    nodeResolve({
      dedupe: ['svelte']
    }),

    commonjs(),

    typescript()
  ]
};

and for good measure my tsconfig.json:

{
  "extends": "@tsconfig/svelte/tsconfig.json",
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "node_modules/*"
  ],
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "module": "es2020",
    "moduleResolution": "node",
    "baseUrl": ".",
    "paths": {
      "~/*": [
        "src/*"
      ]
    }
  }
}

I've also been facing this issue and like you I couldn't figure out what the root cause was, but I did manage to find a workaround. I had a Svelte component importing a TypeScript file like this:

<script lang="ts" context="module">
  import { AuthLink } from '../../auth';
</script>

And when running my app it would fail with Unexpected token (Note that you need plugins to import files that are not JavaScript). I managed to make the error go away simply by appending .ts to the name of the file:

<script lang="ts" context="module">
  // @ts-expect-error
  import { AuthLink } from '../../auth.ts';
</script>

However, if you're using VSCode, you need to add @ts-expect-error to silence intellisense. I was never able to figure out the root cause, and strangely enough other .svelte files in my app could import the auth file without the suffix - it was just a select few components that would break. I'm not sure if that means there's something wrong with my config, or a rollup or svelte-preprocess bug...

Hope that helps

Ok!? Weird. Thanks for the input. Finally I went with Webpack. But if I decide to give rollup another go I will be sure to check it out.

I wasn't able to reproduce this with a simple example I just created. I do think this is probably a better issue to file with svelte-preprocess, so will close it out in this repo, but please feel free to reopen there. If you do reopen, can you please include a minimal example to reproduce?