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"
}
CodePudding user response:
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 imported package can do to enforce this setting), e.g.
// 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.