Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Importing from TypeScript fails (because of problem with exports field?) #268

Closed
joliss opened this issue Feb 29, 2024 · 4 comments
Closed

Comments

@joliss
Copy link
Contributor

joliss commented Feb 29, 2024

I'm having trouble importing memoize-fs using TypeScript, and I've been struggling for the past hour to figure out why it's failing. I made a minimal test case at https://github.com/joliss/import-problem so you can run it yourself if you like.

I have the following index.ts:

import memoizeFs from "memoize-fs";
memoizeFs({});

TypeScript can't find the import (both with tsc and in VS Code), even though memoize-fs is clearly installed:

~/src/import-problem $ tsc
index.ts:1:23 - error TS2307: Cannot find module 'memoize-fs' or its corresponding type declarations.

1 import memoizeFs from 'memoize-fs'
                        ~~~~~~~~~~~~
~/src/import-problem $ ls -l node_modules/memoize-fs/
total 20
-rw-r--r-- 1 ubuntu ubuntu  1079 Feb 29 15:44 LICENSE
-rwxr-xr-x 1 ubuntu ubuntu 12026 Feb 29 15:44 README.md
drwxr-xr-x 2 ubuntu ubuntu    41 Feb 29 15:44 dist
-rw-r--r-- 1 ubuntu ubuntu  2034 Feb 29 15:44 package.json

tsc nonetheless produces a compiled index.js file. If I run it, I get the following error from Node's module resolver:

~/src/import-problem $ node index.js
node:internal/modules/cjs/loader:598
      throw e;
      ^

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined in /home/ubuntu/src/import-problem/node_modules/memoize-fs/package.json
    at exportsNotFound (node:internal/modules/esm/resolve:303:10)
    at packageExportsResolve (node:internal/modules/esm/resolve:593:13)
    at resolveExports (node:internal/modules/cjs/loader:591:36)
    at Module._findPath (node:internal/modules/cjs/loader:668:31)
    at Module._resolveFilename (node:internal/modules/cjs/loader:1130:27)
    at Module._load (node:internal/modules/cjs/loader:985:27)
    at Module.require (node:internal/modules/cjs/loader:1235:19)
    at require (node:internal/modules/helpers:176:18)
    at Object.<anonymous> (/home/ubuntu/src/import-problem/index.js:6:38)
    at Module._compile (node:internal/modules/cjs/loader:1376:14) {
  code: 'ERR_PACKAGE_PATH_NOT_EXPORTED'
}

Node.js v20.11.1

I can see the following exports declaration in the package.json:

~/src/import-problem $ cat node_modules/memoize-fs/package.json
{
   ...
  "module": "./dist/index.mjs",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "import": "./dist/index.mjs"
    }
  },
  ...
}

The dist/index.d.ts and dist/index.mjs files do exist in the distribution.

I'm not sure why exactly the exports field isn't being picked up properly by Node.

I'm running the latest stable Node and TypeScript versions:

~/src/import-problem $ node --version
v20.11.1
~/src/import-problem $ tsc --version
Version 5.3.3

For what it's worth, my actual workflow doesn't involve transpiling with tsc but rather running with ts-node, but it's showing the same error (ts-node index.ts and ts-node --transpile-only index.ts).

@borisdiakur
Copy link
Owner

Hi @joliss, please install the latest version of memoize-fs, which is currently 3.0.2, then add "type": "module" to your package.json file. This should resolve your issue. ✌🏻

@joliss
Copy link
Contributor Author

joliss commented Mar 2, 2024

Hm, the importing works now, but I'm noticing that calls into Node modules like path.join are now getting replaced with (void 0) in the dist/index.js file. For example (this is after applying #271 and #272 for readability) I'm getting the following line in dist/index.js:

    return checkOptions(allOptions), await initCache((void 0)(allOptions.cachePath, allOptions.cacheId), allOptions), function() {

The corresponding source is

    checkOptions(allOptions)

    await initCache(
      path.join(allOptions.cachePath, allOptions.cacheId),
      allOptions
    )

    return function () {

I'm seeing the following warning when running npm run build:

[plugin:vite:resolve] Module "path" has been externalized for browser compatibility, imported by "/home/ubuntu/src/memoize-fs/src/index.ts". See https://vitejs.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.

The linked document doesn't show any way to disable this behavior, so perhaps it's just not really possible to build Node library code with Vite.

Thanks for your patience -- I wish I knew more about the intricacies of Node's module handling to be more helpful.

@joliss
Copy link
Contributor Author

joliss commented Mar 3, 2024

I'm also wondering if it isn't possible to make memoize-fs importable from TypeScript without adding "type": "module" to package.json, as that will subtly change how import behaves in some edge cases. Will try and investigate once the void 0 issue is sorted out.

@borisdiakur
Copy link
Owner

borisdiakur commented Mar 3, 2024

Looks like setting build.ssr to true in the vite config resolves the void 0 issue. I'm going to publish another patch release. Thanks for the support! 🙏🏻
v3.0.3 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants