I am attempting to import a local ESM package into a node 16 application. The application is unable to resolve the local package dependencies outputting the following error.
Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@prismicio/client' imported from /Users/***/Workspace/wisdom-store/lib/prismic-utils/index.mjs
at packageResolve (internal/modules/esm/resolve.js:664:9)
at moduleResolve (internal/modules/esm/resolve.js:705:18)
at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:819:11)
at Loader.resolve (internal/modules/esm/loader.js:89:40)
at Loader.getModuleJob (internal/modules/esm/loader.js:242:28)
at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:73:40)
at link (internal/modules/esm/module_job.js:72:36) {
code: 'ERR_MODULE_NOT_FOUND'
The consuming node application is declaring the local package in the devDependencies using the file option.
{
"name": "node-application",
"devDependencies" : {
"prismic-utils": "file:../lib/prismic-utils"
}
}
The local package (pismic-utils) defines @prismicio/client as a dependency.
{
"name": "prismic-utils",
"version": "0.0.0",
"private": true,
"main": "index.mjs",
"dependencies": {
"@prismicio/helpers": "^2.3.9",
"@prismicio/client": "^6.7.3"
},
"devDependencies": {
"eslint": "^8.35.0",
"eslint-plugin-node": "^11.1.0",
"msw": "^1.1.0",
"node-fetch": "^3.3.0",
"vitest": "^0.28.5"
}
}
I am at a complete loss as to why the consuming node application is having trouble resolving the @prismicio/client and @prismicio/helpers inherited dependencies. If I populate the node_modules folder inside the local package the node application resolves the dependencies. The local prismic-utils package dependencies are being installed to the consuming application node_modules folder.
Any help is greatly appreciated.
Thanks
This happens because using file:
in a dependency's version results in a symbolic link. It acts like npm link
(see npm link
docs here).
npm treats linked packages differently than those installed from a registry like npmjs.com. npm assumes the linked package has its own dependencies installed, so it does not install them.
There are a few ways to resolve your issue:
Best Option: Use npm workspaces to automatically handle linked dependency installation.
Update your package.json
file to include a workspaces
property:
// package.json
{
"workspaces": [
"./relative/path/to/prismic-utils",
"./relative/path/to/app"
]
}
Install file:
dependencies like registry dependencies using npm's --install-links
option.
# In the Node.js app:
npm install --install-links
Changes to prismic-utils
will not be reflected in the app until it is re-installed, just like non-file:
dependencies.
Note: Dependencies' devDependencies
are not installed using this method. You will need to move node-fetch
from devDependencies
into dependencies
.
Install dependencies in prismic-utils
before starting your app. Once they are installed, prismic-utils
will have access to its own dependencies via its node_modules
directory.
Because you are using Node.js 16, which includes npm >=7 and support for workspaces, Option 1 is the best choice.