figma / plugin-typings

Typings for the Figma Plugin API
MIT License
190 stars 44 forks source link

Cannot redeclare block scoped variable #301

Closed AWaleczek closed 1 month ago

AWaleczek commented 1 month ago

Hello,

this seems to be an issue that several others raised before. I think I tried everything I found in the other issues but couldn't resolve it. image

I followed the getting started guide and installed the default dependencies. In addition I installed @types/node which is when the error started occurring.

This is my tsconfig: { "compilerOptions": { "target": "esnext", "lib": ["esnext"], "strict": true, "module": "esnext", "moduleResolution": "Node", "moduleDetection": "force", "typeRoots": [ "./node_modules/@types", "./node_modules/@figma" ] } }

I am on @figma/plugin-typings@1.97.0

cyberalien commented 1 month ago

It is caused by mixing @types/node and plugin types.

They do not belong in same tsconfig file. Plugin does not have access to node, build tools do not have access to plugin, therefore code should not be mixed. You need to separate projects with different tsconfig.json files for plugin and build tools.

For example, this is my tsconfig.json:

{
  "files": [],
  "references": [
    {
      "path": "./tsconfig.node.json"
    },
    {
      "path": "./tsconfig.app.json"
    }
  ]
}

It references 2 files: one for plugin, one for build tools:

tsconfig.app.json:

{
    "extends": "@vue/tsconfig/tsconfig.dom.json",
    "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
    "exclude": ["src/**/__tests__/*"],
    "compilerOptions": {
        "composite": true,
        "baseUrl": ".",
        "typeRoots": [
            "../../node_modules/@types",
            "./node_modules/@types",
            "./node_modules/@figma"
        ],
        "types": ["plugin-typings"]
    }
}

tsconfig.node.json:

{
    "extends": "@tsconfig/node18/tsconfig.json",
    "include": ["vite.config.*"],
    "compilerOptions": {
        "composite": true,
        "module": "ESNext",
        "moduleResolution": "Bundler",
        "types": ["node"]
    }
}

That config is for Vue project that uses Vite for build. If you are using different framework and build process, you can still apply this idea to your config by splitting it into multiple projects.

Ideally there could be 3 config files:

but for my code I've decided to not complicate things further, so only split into build tools and plugin+ui.

AWaleczek commented 1 month ago

Hey, Thanks for explaining that! I am fine with Javascript but new to Typescript, Node, etc. and this helped me a lot to understand how it works. Is that approach mentioned anywhere in the Figma documentation? This answer could have literally saved days of me researching why what I try to do is not working.

So that means if I wanted to use node, I would develop with it in separate files and then import those modules into plugin/ui?

cyberalien commented 1 month ago

So that means if I wanted to use node, I would develop with it in separate files and then import those modules into plugin/ui?

No, you can't use node modules in plugin. Plugin is not ran in node environment, it uses custom javascript runtime that has access to basic javascript stuff and figma global. UI is ran in browser window, it has access to same stuff that usual broser has access to, not node environment.

Node can be used only during build process for purpose of building plugin: bundling code, unit tests.

Additionally, plugin environment in Figma is currently using a bit outdated runtime that does not support modern javascript like spread operators, so make sure your code doesn't use that.