carbon-design-system / carbon-preprocess-svelte

Svelte preprocessors for the Carbon Design System
Apache License 2.0
68 stars 6 forks source link

Unexpected Token Error when importing types #28

Closed WilliamDiakite closed 7 months ago

WilliamDiakite commented 2 years ago

Hello, I have had a bug when importing typescript types in Svelte components:

<script lang="ts">
    import type { MyType } from './MyType'
    // ...
</script>

<h1>Welcome</h1>

The import statement in MyComponent.svelte throws an Unexpected token error.

After some search, I figured out this error is thrown whenever icons() and/or pictograms() preprocessors are used in svelte.config.js. It is this particular issue that led me thinking that carbon processors might be involved in the error.

Steps to reproduce the bug

  1. Install new sveltekit project

    npm init svelte@next my-app
    cd my-app
    npm install
  2. Modify project code and declare new type to import

2.1 Create new file my-app/src/routes/MyType.d.ts

export type MyType = {
    name: string;
}

2.2 Import type in my-app/src/routes/index.svelte

<script lang="ts">
    import type { MyType } from './MyType'
    let a = {} as MyType;
</script>

<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>

At this point, everything should work as expected.

  1. Install carbon tools

    npm i -D carbon-components-svelte carbon-preprocess-svelte carbon-icons-svelte
    npm install
  2. Change svelte.config.js to include carbon preprocesses

    
    import adapter from '@sveltejs/adapter-auto';
    import preprocess from 'svelte-preprocess';
    import { optimizeImports, elements, icons, pictograms } from 'carbon-preprocess-svelte';

/* @type {import('@sveltejs/kit').Config} / const config = { // Consult https://github.com/sveltejs/svelte-preprocess // for more information about preprocessors preprocess: [preprocess(), optimizeImports(), elements(), icons(), pictograms()],

kit: {
    adapter: adapter()
}

};

export default config;



**It is this last step that causes the bug**

### Workaround

Removing both `icons()` and `pictograms()` fixes the bug.

Thank you for your time and help.
metonym commented 2 years ago

Removing both icons() and pictograms() fixes the bug.

That's interesting, as neither icons nor pictograms processes the script block.

Curious - how are you using carbon-icons-svelte? Because the icons preprocessor is designed to replace carbon-icons-svelte.

WilliamDiakite commented 2 years ago

Curious - how are you using carbon-icons-svelte? Because the icons preprocessor is designed to replace carbon-icons-svelte.

In my current project icons() and pictograms() are in the preprocess array of svelte.config.js. Then in a component I would use icons like this :

<script lang='ts'>
    import { Link } from 'carbon-components-svelte'
    import { Add16 } from 'carbon-icons-svelte'
</script>

<Link icon={Add16} />

After going through docs again, I get the feeling that I misunderstood the docs when I installed carbon-preprocess-svelte. It seems that in my case, using icons() preprocessor is not necessary. Is that correct?

That's interesting, as neither icons nor pictograms processes the script block.

Have you been able to reproduce the bug?

I just tried fixing the bug (by removing icons() and pictograms()) in my current project. The workaround I provided just doesn't seem to work here : I still get an Unexpected Token Error when importing.

Would it possible that the bug is caused by another preprocessor (optimizeImports() or elements())?

Don't now if this can help but here the package.jsonof my current project:

{
    "name": "cbc-client",
    "version": "0.0.1",
    "scripts": {
        "dev": "svelte-kit dev",
        "build": "svelte-kit build",
        "package": "svelte-kit package",
        "preview": "svelte-kit preview",
        "check": "svelte-check --tsconfig ./tsconfig.json",
        "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
        "lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. . && eslint --ignore-path .gitignore .",
        "format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ."
    },
    "devDependencies": {
        "@sveltejs/adapter-auto": "next",
        "@sveltejs/kit": "next",
        "@typescript-eslint/eslint-plugin": "^5.15.0",
        "@typescript-eslint/parser": "^5.15.0",
        "carbon-components-svelte": "^0.62.1",
        "carbon-icons-svelte": "^10.45.1",
        "carbon-preprocess-svelte": "^0.7.0",
        "eslint": "^8.11.0",
        "eslint-config-prettier": "^8.5.0",
        "eslint-plugin-svelte3": "^3.4.1",
        "mdsvex": "^0.10.5",
        "prettier": "^2.6.0",
        "prettier-plugin-svelte": "^2.6.0",
        "svelte": "^3.46.4",
        "svelte-check": "^2.4.6",
        "svelte-preprocess": "^4.10.4",
        "svelte-range-slider-pips": "^2.0.3",
        "tslib": "^2.3.1",
        "typescript": "^4.6.2"
    },
    "type": "module",
}

And here is the package.json from the skeleton project I used to replicate the bug:

{
  "name": "svelte-types",
  "version": "0.0.1",
  "scripts": {
    "dev": "svelte-kit dev",
    "build": "svelte-kit build",
    "package": "svelte-kit package",
    "preview": "svelte-kit preview",
    "prepare": "svelte-kit sync",
    "check": "svelte-check --tsconfig ./tsconfig.json",
    "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
    "lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. . && eslint --ignore-path .gitignore .",
    "format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ."
  },
  "devDependencies": {
    "@sveltejs/adapter-auto": "next",
    "@sveltejs/kit": "next",
    "@typescript-eslint/eslint-plugin": "^5.10.1",
    "@typescript-eslint/parser": "^5.10.1",
    "carbon-components-svelte": "^0.62.1",
    "carbon-icons-svelte": "^10.45.1",
    "carbon-preprocess-svelte": "^0.7.0",
    "eslint": "^7.32.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-svelte3": "^3.2.1",
    "prettier": "^2.5.1",
    "prettier-plugin-svelte": "^2.5.0",
    "svelte": "^3.44.0",
    "svelte-check": "^2.2.6",
    "svelte-preprocess": "^4.10.1",
    "tslib": "^2.3.1",
    "typescript": "~4.6.2"
  },
  "type": "module"
}

I will update svelte in my current project and check whether or not the bug persists. Please, tell me if you need more information, I will try to reply as soon as I can tomorrow morning (EST).

metonym commented 2 years ago

After going through docs again, I get the feeling that I misunderstood the docs when I installed carbon-preprocess-svelte. It seems that in my case, using icons() preprocessor is not necessary. Is that correct?

That's correct, optimizeImports will attempt to automatically optimize imports from "carbon-components-svelte", "carbon-icons-svelte", and "carbon-pictograms-svelte."

WilliamDiakite commented 2 years ago

From what I understand, the problem comes from the order in which the preprocesses are executed.

In svelte.config.js I changed

import preprocess from 'svelte-preprocess';
import { optimizeImports, elements } from 'carbon-preprocess-svelte';

const config = {
    // ...,
    preprocess: [optimizeImports(), elements(), preprocess()],
    // ...
}

to

import preprocess from 'svelte-preprocess';
import { optimizeImports, elements } from 'carbon-preprocess-svelte';

const config = {
    // ...,
    preprocess: [preprocess(), optimizeImports(), elements()],
    // ...
}

Making this change fixed the problem of importing types. Maybe a note could be added to the docs to clarify the fact that Svelte preprocess()has to be called first?

Thank you for your help!

metonym commented 2 years ago

That's a good point – if using TypeScript, svelte-preprocess must be invoked first.

d0x7 commented 2 years ago

I think I have a similar - or maybe the same issue. Also partly caused by icons() and "fixed" when removed. But I have two seperate exceptions.

1) Unexpected token mentioning a TypeScript type "n: number" - working without icons() 2) Cannot read properties of undefined (reading 'some') - working without elements()

Tried on a npm init @svelte-add/kit@latest template (with TypeScript, CSS, Example Code), and manually added carbon components/icons/preprocess.

With only optimizeImports() I can manually import e.g. Airplay from carbon-icons-svelte and use it with <Airplay/> successfully. But obviously not with the <icon name=Airplay/> syntax.

I also get alot of warnings like these:

[carbon:elements] Invalid breakpoint name "min-width"
[carbon:elements] Invalid breakpoint name "min-width"
Error on preprocess: Cannot read properties of undefined (reading 'some')
[carbon:icons] invalid icon name "Airplay"

The last message is related to HMR. Added icons() to the config, it hot-reloaded, printed the message but after a restart of vite, I was back at the error described at 1).

Honestly, I didn't want to open another issue, because I am not sure whether this is my fault or not. If it is, I cannot see what I'm doing wrong. I followed the README.md closely. I "changed" preprocess() to be the first plugin, even if it was from the beginning and I just changed it back after trying around. elements() and icons() just don't wanna work for "me" (it's a blank project, so yeah..). Any ideas?

The svelte.config.js I used ```typescript import adapter from '@sveltejs/adapter-auto'; import preprocess from 'svelte-preprocess'; import { optimizeImports, optimizeCss, elements, icons } from 'carbon-preprocess-svelte'; /** @type {import('@sveltejs/kit').Config} */ const config = { // preprocess was already the first most of the time. // I swapped the order around a lot, but didn't notice any other outcome. preprocess: [preprocess(), optimizeImports(), elements({theme: 'all'}), icons()], kit: { adapter: adapter(), vite: { plugins: [ process.env.NODE_ENV === 'production' && optimizeCss() ] } } }; export default config; ```
metonym commented 2 years ago

@d0x7 The icons preprocessor hasn't yet been updated to use Carbon Icons v11. Instead of Airplay, can you try specifying the icon size in the name (e.g., Airplay20)?

d0x7 commented 2 years ago

@metonym It's kinda weird. As I said, I just started vite with npm run dev but without icons() in the config. Then added icons() after it started, and vite hot reloads. <icon> tags are working now, as you said with Airplay20 or Add16. But when I stop Vite and start it again (this time having icons() in the config already) I get the same error as before.

Error on preprocess: Unexpected token
project/src/components/Counter.svelte:11:18 Error while preprocessing project/src/components/Counter.svelte - Unexpected token
project/src/components/Counter.svelte:11:18 Error while preprocessing project/src/components/Counter.svelte - Unexpected token
  9 |  
 10 |    // handle negative numbers
 11 |    function modulo(n: number, m: number) {
                          ^
 12 |      return ((n % m) + m) % m;
 13 |    }