octet-stream / form-data

Spec-compliant FormData implementation for Node.js
https://www.npmjs.com/package/formdata-node
MIT License
142 stars 17 forks source link

Cannot find module 'formdata-node/file-from-path' using jest #50

Closed frankPairs closed 2 years ago

frankPairs commented 2 years ago

Description

Hi everyone!

I am having some trouble using the fileFromPath in Jest. When I add the import of file-from-path module to a test file using jest, it is showing the next error:

Cannot find module 'formdata-node/file-from-path' from 'fomdata.test.js'

I read in your Release Notes from version 4.0.0 and one of the comments is:

This subpath is NOT available in browsers!

Maybe you can help me to understand if this issue is related to that note.

My main problem is that I am trying to update one test that was using an older version of formdata-node. In that test, we were using the createReadStream method which in the latest version is not available if I understood correctly.

I was trying to replace that piece of code with the method fileFromPath but I found that issue and I am quite stuck.

Below you can find a simple example to reproduce this issue.

I would appreciate some help with this!

Thanks a lot in advance!

Example

package.json

{
  "name": "testing-formdata-node",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "jest"
  },
  "dependencies": {
    "formdata-node": "^4.3.2"
  },
  "devDependencies": {
    "@babel/core": "^7.16.12",
    "@babel/preset-env": "^7.14.1",
    "babel-jest": "^27.0.0",
    "jest": "^27.0.0"
  },
  "author": "",
  "license": "ISC"
}

jest.config.js

module.exports = {
  testEnvironment: 'node' // Just to show that I am using Node environment
}

babel.config.js

module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          node: 'current'
        }
      }
    ]
  ]
}

formdata.test.js

import { fileFromPath } from "formdata-node/file-from-path";

describe("testing fileFromPath", () => {
  it("should fileFromPath be defined", () => {
    expect(fileFromPath).toBeDefined();
  });
});
octet-stream commented 2 years ago

Could you file more information about the environment in which you run your tests? More specifically I need Node.js version and Jest version, so I can try and create a project to reproduce this issue.

I read in your Release Notes from version 4.0.0 and one of the comments is: This subpath is NOT available in browsers!

That is true. But you run your test in Node.js, not in browsers, so this have nothing to do with your issue.

octet-stream commented 2 years ago

Ah, I see Jest version now.

frankPairs commented 2 years ago

hi @octet-stream , thanks for your quick reply! my apologies, I missed the node version. the test was done with the lts version (v16.3.2)

octet-stream commented 2 years ago

I see. Let me just look at this. From what I can tell now - this might be the problem with how Jest may resolve my package. Not sure tho whether Jest has own logic to resolve packages. You can try and create some file with that import and run it in Node.js directly - it should work without issues. In test file you can try and import this helper directly from formdata-node/lib/cjs/fileFromPath.js (or formdata-node/lib/esm/fileFromPath.js if you're running in ESM context) - this should work too, but it won't be the solution.

octet-stream commented 2 years ago

Just tried out your code - it seems like jest does something with modules resolution, that it likely why this error appears.

octet-stream commented 2 years ago

This might be related issue: https://github.com/facebook/jest/issues/9771

frankPairs commented 2 years ago

just to provide more information (because I spent some time testing this issue). I tested one library that we are using in the project that is using submodules as well (concretely graphql-ws) and jest tests were able to recognize them.

one of the differences I saw is that they are exporting the esm files with the extension .mjs but I am not sure if that is the real solution for this issue. I will spend some more time investigating this issue

simoneb commented 2 years ago

As a workaround, this works:

const { fileFromPath } = require('formdata-node/lib/cjs/fileFromPath')
octet-stream commented 2 years ago

Sorry for a late response guys, I will be able to try and investigate the issue this weekend.

I saw is that they are exporting the esm files with the extension .mjs but I am not sure if that is the real solution for this issue.

Maybe you're right and I'll need to rethink the build system for my library. But I am not so sure if it worth it, because I will move to ESM only near Node 12 EOL anyways

frankPairs commented 2 years ago

no worries @octet-stream ! let me know if you need anything from my side

octet-stream commented 2 years ago

I think Jest can resolve graphql-ws just fine, because it actually have the files by the paths they mentioned in their package.json. Like, ./lib/use/ws does really exists by that path. In my package, I don't have a file at formdata-node/file-from-path. If I create such file - Jest can import it just fine. You can try it yourself: just create a file-from-path.js file in formdata-node root in your node_modules and re-export the actual fileFromPath.js like so:

module.exports = require("./lib/cjs/fileFromPath.js")
octet-stream commented 2 years ago

It looks like the problem has been solved in jest@28.0.0-alpha.0

frankPairs commented 2 years ago

thanks @octet-stream for following up!

octet-stream commented 2 years ago

So, Jest 28 is released, the problem is not occur anymore so I think this issue can now be closed.