简体   繁体   中英

Can't import module using package.json "exports" in React

I am trying to import a (typescript) package into a (typescript) React project. This modules uses the exports property in the package.json file to control what can be imported from it. But, in my React project, I can not get the paths exported in exports to work. Instead, I can import anything from the module. So for example, I export a path ./certificate using exports in package.json . But instead of importing like:

import {test} from "certificationtypes/certificate"

I need to import like:

import {test} from "certificationtypes/src/certificate"

(It also exposes all other files not exported using the exports directive).

This is the package.json of the module:

{
  "name": "inputsvalidator",
  "version": "1.0.0",
  "description": "",
  "main": "./build/src/index.js",
  "exports": {
    "./certificate": "./build/src/certificate.js"
  },
  "scripts": {
    "build": "tsc",
    "prepare": "npm run build",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "devDependencies": {
    "typescript": "^4.9.4"
  },
  "dependencies": {
    "@types/validator": "^13.7.10",
    "certificationtypes": "file:../certificationTypes",
    "countries": "file:../../../../../lib/shared/countries",
    "types": "file:../../../../../lib/shared/types",
    "validator": "^13.7.0"
  }
}

The strange thing is that this does work in Node.js projects? So is there something extra I should do to also make this work in my React project. I did read that this should be supported using webpack.

My package.json for my React project:

{
  "name": "front-end",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "@types/jest": "^27.5.2",
    "@types/node": "^16.18.11",
    "@types/react": "^18.0.26",
    "@types/react-dom": "^18.0.10",
    "certificationtypes": "file:../../lib/shared/certificationTypes",
    "countries": "file:../../../../lib/shared/countries",
    "inputsvalidator": "file:../../lib/shared/inputsValidator",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "react-spinners": "^0.13.7",
    "styled-components": "^5.3.6",
    "typescript": "^4.9.4",
    "validator": "^13.7.0",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "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": {
    "@types/styled-components": "^5.1.26"
  },
  "proxy": "http://localhost:3003"
}

By default, TypeScript does not regard "exports" fields in package.json files when importing packages.

In TypeScript 4.7 or later, this feature can be enabled explicitly in the compiler options by setting moduleResolution to "node16" or "nodeNext" in the current project (there is nothing the import ed package can do to enforce this setting), eg

// tsconfig.json
{
  ...
  "compilerOptions": {
    ...
    "moduleResolution": "node16",
    ...
  },
  ...
}

Just be careful that doing so may unexpectedly break other parts of your applications, because then other settings in package.json start to play a role as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM