簡體   English   中英

無法導入生成的類型文件 create-react-app

[英]Can't import generated typings file create-react-app

這是我第一次創建 typescript 反應 npm 模塊,我正在嘗試在我的項目中導入使用新 npm 模塊的類型定義之一。 VSCode 智能感知能夠找到並建議自動生成的.d.ts文件之一,但應用程序無法加載它。 到底是怎么回事?

./src/components/MyPage.tsx
Module not found: Can't resolve '@myorg/component-library/build/Input/Input.types' in '/Users/jbaczuk/path/to/project/src/components'

如果我將導入路徑更改為'@myorg/component-library/build/Input/Input.types.d'它會拋出:

./node_modules/@myorg/component-library/build/Input/Input.types.d.ts 2:7
Module parse failed: Unexpected token (2:7)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> export declare enum Type {
|     text = "text",
|     number = "number"

輸入.types.d.ts

export declare enum Type {
    text = "text",
    number = "number"
}
export interface InputProps {
    type?: Type;
}
//# sourceMappingURL=Input.types.d.ts.map

我的頁面.ts

import React from 'react';
import { Type } from '@myorg/component-library/build/Input/Input.types.d';

export default function MyPage(): JSX.Element {

{/** ... more stuff **/}}

return (
{/** ... more stuff **/}}
  <Input
    onChangeValue={onChangeText}
    type={Type.text}
  />
{/** ... more stuff **/}}
)

package.json

{
  "name": "my-project",
  "version": "0.1.0",
  "description": "My Project",
  "private": true,
  "repository": "git@github.com:MyOrg/MyProject.git",
  "license": "UNLICENSED",
  "dependencies": {
    "@myorg/component-library": "../../component-library",
    "axios": "^0.21.1",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-router-dom": "^5.2.0",
    "react-scripts": "4.0.3",
    "styled-components": "^5.2.1",
    "web-vitals": "^1.0.1"
  },
  "scripts": {
    "build:tailwind": "tailwind build src/tailwind.css -o src/tailwind.output.css",
    "watch:tailwind": "chokidar 'src/**/*.css' 'src/**/*.scss' --ignore src/tailwind.output.css -c 'npm run build:tailwind'",
    "start": "npm-run-all build:tailwind --parallel watch:tailwind start:react",
    "start:react": "PORT=3002 react-scripts start",
    "prebuild": "run-s build:tailwind",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "lint": "eslint '*/**/*.{js,ts,tsx}' --quiet --fix",
    "check-types": "tsc"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@tailwindcss/postcss7-compat": "^2.0.4",
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/react": "^11.1.0",
    "@testing-library/user-event": "^12.1.10",
    "@types/jest": "^26.0.15",
    "@types/node": "^12.0.0",
    "@types/react": "^17.0.0",
    "@types/react-dom": "^17.0.0",
    "@types/react-router-dom": "^5.1.7",
    "@types/testing-library__jest-dom": "^5.9.5",
    "@types/testing-library__react": "^10.2.0",
    "@typescript-eslint/eslint-plugin": "^4.14.2",
    "@typescript-eslint/parser": "^4.14.2",
    "autoprefixer": "^9",
    "chokidar-cli": "^2.1.0",
    "eslint": "^7.19.0",
    "eslint-config-prettier": "^7.2.0",
    "eslint-plugin-prettier": "^3.3.1",
    "eslint-plugin-react": "^7.22.0",
    "eslint-plugin-react-hooks": "^4.2.0",
    "husky": "^4.3.8",
    "lint-staged": ">=10",
    "npm-run-all": "^4.1.5",
    "postcss": "^7",
    "prettier": "^2.2.1",
    "react-scripts": "4.0.2",
    "tailwindcss": "npm:@tailwindcss/postcss7-compat",
    "ts-jest": "^26.5.0",
    "typescript": "^4.1.2"
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "*.{js,ts,tsx}": [
      "eslint --fix"
    ]
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "ES2020",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "module": "esnext",
    "allowJs": true,
    "jsx": "react-jsx",
    "outDir": "./build",
    "noEmit": true,
    "isolatedModules": true,
    "strict": true,
    "noFallthroughCasesInSwitch": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "types": [
      "node",
      "jest"
    ],
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": [
    "src"
  ],
  "exclude": [
    "build"
  ]
}

組件庫

package.json

{
  "name": "@myorg/component-library",
  "repository": {
    "type": "git",
    "url": "https://github.com/myOrg/ComponentLibrary.git"
  },
  "version": "0.2.1",
  "description": "MyOrg react component library",
  "main": "build/index.js",
  "module": "build/index.esm.js",
  "files": [
    "build"
  ],
  "types": "build/index.d.ts",
  "scripts": {
    "build": "rm -rf build && rollup -c --environment NODE_ENV:production",
    "test": "jest",
    "test:watch": "jest --watch",
    "lint": "eslint . --ext .ts",
    "lint:fix": "eslint . --fix --ext .ts",
    "storybook": "start-storybook -p 6006",
    "storybook:export": "build-storybook",
    "prepublishOnly": "npm run build",
    "create": "node ./util/create"
  },
  "author": "Jordan Baczuk",
  "license": "UNLICENSED",
  "devDependencies": {
    "@babel/core": "^7.13.14",
    "@rollup/plugin-commonjs": "^18.0.0",
    "@rollup/plugin-node-resolve": "^11.2.1",
    "@storybook/addon-essentials": "^6.2.2",
    "@storybook/addons": "^6.2.2",
    "@storybook/react": "^6.2.2",
    "@tailwindcss/postcss7-compat": "^2.0.4",
    "@testing-library/jest-dom": "^5.11.10",
    "@testing-library/react": "^11.2.6",
    "@testing-library/user-event": "^13.1.1",
    "@types/jest": "^26.0.22",
    "@types/react": "^17.0.3",
    "@typescript-eslint/eslint-plugin": "^4.14.0",
    "@typescript-eslint/parser": "^4.14.0",
    "autoprefixer": "^9",
    "babel-loader": "^8.2.2",
    "babel-preset-react-app": "^10.0.0",
    "eslint": "^7.18.0",
    "eslint-config-prettier": "^7.2.0",
    "eslint-plugin-prettier": "^3.3.1",
    "eslint-plugin-react": "^7.22.0",
    "eslint-plugin-react-hooks": "^4.2.0",
    "husky": "^4.3.8",
    "identity-obj-proxy": "^3.0.0",
    "jest": "^26.6.3",
    "lint-staged": ">=10",
    "postcss": "^7",
    "prettier": "^2.2.1",
    "rollup": "^2.44.0",
    "rollup-plugin-peer-deps-external": "^2.2.4",
    "rollup-plugin-postcss": "3.1.8",
    "rollup-plugin-typescript2": "^0.30.0",
    "tailwindcss": "npm:@tailwindcss/postcss7-compat",
    "ts-jest": "^26.5.4",
    "typescript": "^4.2.3"
  },
  "peerDependencies": {
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged && npm test"
    }
  },
  "lint-staged": {
    "*.{js,ts,tsx}": [
      "eslint --fix"
    ],
    "*.js": "eslint --cache --fix"
  },
  "dependencies": {
    "@fontsource/titillium-web": "^4.2.2",
    "@heroicons/react": "^1.0.0",
    "react-tooltip": "^4.2.17"
  }
}

tsconfig.js

{
  "compilerOptions": {
    "declarationMap": true,
    "declaration": true,
    "declarationDir": "build",
    "module": "esnext",
    "target": "es5",
    "lib": ["es6", "dom", "es2016", "es2017"],
    "sourceMap": true,
    "jsx": "react",
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true
  },
  "include": ["src/**/*"],
  "exclude": [
    "node_modules",
    "build",
    "src/**/*.stories.tsx",
    "src/**/*.spec.ts",
    "src/**/*.tests.tsx"
  ]
}

rollup.config.js

import peerDepsExternal from 'rollup-plugin-peer-deps-external'
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import typescript from 'rollup-plugin-typescript2'
import packageJson from './package.json'
import postcss from 'rollup-plugin-postcss'

export default {
  input: 'src/index.ts',
  output: [
    {
      file: packageJson.main,
      format: 'cjs',
      sourcemap: true
    },
    {
      file: packageJson.module,
      format: 'esm',
      sourcemap: true
    }
  ],
  external: ['styled-components'],
  plugins: [
    peerDepsExternal(),
    postcss({
      minimize: true,
      modules: true,
      use: {
        sass: null,
        stylus: null,
        less: { javascriptEnabled: true }
      },
      extract: true
    }),
    resolve(),
    commonjs(),
    typescript()
  ]
}

我有點驚訝您直接從 types.d 文件加載類型並使用構建路徑! 我希望寧願import { Type } from '@myorg/component-library

That's because as part of creating the package.json for a typescript-authored npm library you'd be defining a main property pointing to the place that exports all the Javascript properties and a types property pointing to the place that exports the typescript types you want .

如果該主要入口點(由於您的構建過程)實際上是build/index.js並且相應的類型文件是build/index.d.ts那么您在導入時永遠不會直接引用構建文件夾或文件 - 指向正確的路徑由捆綁過程處理。

Take a look at a mainstream (but simple) typescript npm module like https://github.com/jamiebuilds/unstated-next/blob/master/package.json ( https://www.npmjs.com/package/unstated-下一個

您可以看到指向應該導出 javascript 名稱https://github.com/jamiebuilds/unstated-next/blob/master/package.json#L6的文件的主要屬性和指向應該導出的文件的類型屬性類型https://github.com/jamiebuilds/unstated-next/blob/master/package.json#L9並且這些類型恰好位於“dist”文件夾中,但是根據https的文檔導入它時從未引用過://www.npmjs.com/package/unstated-next

我終於得到了這個工作,並學到了一些東西。

  1. 枚舉不是類型。

enum 不是一種類型,這意味着它生成的 js 代碼不像類型和接口。 https://github.com/ng-packagr/ng-packagr/issues/809#issuecomment-385187297

  1. 為了從 npm 模塊中導出枚舉,您必須從主模塊文件中顯式導出它:

我的包/src/index.ts

import Card from './Card/Card'
import Input from './Input/Input'
import Form from './Form/Form'
import Link from './Link/Link'
import Text from './Text/Text'
import Button from './Button/Button'
import { HeroIcons } from './style/heroicons'

export { Card, Input, Form, Link, Text, Button, HeroIcons }
export * from './Input/Input.types'

現在我可以像這樣導入它:

import { Type } from '@myorg/component-library';

暫無
暫無

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

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