簡體   English   中英

為什么 SVGR 沒有在我的 esbuild 配置中生成 TypeScript 聲明文件?

[英]Why does SVGR not generate a TypeScript declaration file in my esbuild configuration?

我正在 TypeScript 中創建一個 SVG 圖標庫。 到目前為止,SVGR 非常棒,但我需要的最后一部分是生成的類型,以允許將titleref傳遞給捆綁的組件。

再生產

我不確定看到哪些內容可能會有所幫助,因此我將包含一個 repo 和一些代碼示例。 但是通過以下設置,svgr 正在從 SVG 導入創建組件,但沒有生成任何類型。 結果,每當我嘗試使用此包中的圖標時,都會警告我找不到它的聲明文件。

POC 回購: https ://github.com/yuschick/icon-demo

src/index.ts

export { default as TestIcon } from "./svg/test.svg";
export { default as ArrowThinLeft } from './svg/arrow-thin-left.svg';

包.json

{
  "module": "dist/index.js",
  "types": "dist/index.d.ts",
  "type": "module",
  "scripts": {
    "build": "node esbuild.config.js",
  },
  "devDependencies": {
    "esbuild": "^0.14.39",
    "esbuild-plugin-svgr": "^1.0.1",
    "typescript": "^4.6.3"
  }
}

esbuild.config.js

import esbuild from "esbuild";
import svgr from "esbuild-plugin-svgr";

esbuild.build({
    bundle: true,
    entryPoints: ["src/index.ts"],
    external: ["react"],
    format: "esm",
    // minify: true,
    outfile: "dist/index.js",
    plugins: [svgr({ titleProp: true, ref: true, expandProps: false, typescript: true })],
})
  .catch(() => process.exit(1));

tsconfig.json

{
  "compilerOptions": {
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "alwaysStrict": true,
    "baseUrl": "src",
    "checkJs": true,
    "declaration": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "isolatedModules": true,
    "lib": ["dom", "dom.iterable", "esnext"],
    "module": "esnext",
    "moduleResolution": "node",
    "noEmit": true,
    "outDir": "dist",
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "strict": true,
    "target": "esnext"
  },
  "include": ["src", "global.d.ts"]
}

全球.d.t​​s

declare module '*.svg' {
    const content: string;
    export default content;
}

預期行為

通過將 typescript typescript: true傳遞給svgr選項,我期望基於生成的組件生成一個index.d.tsx文件。

根據 SVGR 文檔:

使用TypeScript類型生成 .tsx 文件。

注意:雖然我在 ESBuild 中使用 SVGR,但在嘗試使用 Rollup 時也存在同樣的問題。

問題

通過將 typescript typescript: true傳遞給svgr選項,我期望基於生成的組件生成一個index.d.tsx文件。

這種預期是不正確的。 如果您指定typescript選項而不是.d.ts文件,SVGR 只會生成.tsx文件。 文檔(您也找到了):

打字稿

使用 TypeScript 類型生成.tsx文件。

但是,即使指定了此選項,SVGR 也不會生成.tsx文件,因為您在 esbuild 插件中使用它。 esbuild-plugin-svgr在底層利用了來自@svgr/coretransform函數(參見esbuild-plugin-svgr/index.js:L4 )。 transform函數僅將 SVG 轉換為 JSX 或 TSX,但從不寫入輸出。 @svgr/cli處理將輸出寫入文件,例如參見@svgr/cli/src/dirCommand.ts

解決方案

我認為你有兩個選擇:

從esbuild中分離出SVGR,然后生成.d.ts文件

換句話說,停止使用esbuild-plugin-svgr並改用@svgr/cli 然后,您必須在 esbuild 之前運行 SVGR; 手動,在腳本中鏈接命令或使用npm 的 pre-script hook 之后您必須生成一個.d.ts file 雖然,看看esbuild#95 ,它似乎並不支持開箱即用。 您可能想探索那里列出的建議,包括:

  • 使用 TypeScript 編譯器發出聲明文件 ( tsc --emitDeclarationOnly )
  • 使用esbuild-plugin-d.ts等插件

您的構建鏈最后可能如下所示:

  1. 使用@svgr/cli從 SVG 生成.tsx文件。
  2. 使用 esbuild 捆綁。
  3. 生成.d.ts文件,可以使用tsc作為單獨的步驟,也可以使用 esbuild 插件與上述步驟合並。

從 JavaScript 包生成.d.ts文件

如果出於某種原因您真的想保留當前的構建配置,您可以使用tsc dist/index.js --declaration --allowJs --emitDeclarationOnly從您的 JavaScript 捆綁文件生成一個.d.ts文件(請參閱TypeScript 文檔)。 需要注意的是,TypeScript 可能無法推斷所有類型,因此您的類型聲明文件可能不完整。

嘗試將 typescript 類型與 rollup-plugin-dts 插件捆綁在一起時,svgr 遇到了類似的問題。

通過創建單個 icon.d.ts 文件來解決它:

import { SVGProps } from 'react';
declare const ReactComponent: (props: SVGProps<SVGSVGElement>) => JSX.Element;
export { ReactComponent };

然后像這樣使用別名插件:

import alias from '@rollup/plugin-alias';
...
      plugins: [
        alias({
          entries: [
            {
              find: /^.*\.svg$/,
              replacement: 'src/types/icon.d.ts',
            },
          ],
        }),
        dts(),
      ],

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM