testdouble / quibble

Makes it easy to replace require'd dependencies.
94 stars 25 forks source link

TypeError [ERR_IMPORT_ASSERTION_TYPE_MISSING] #55

Open anonrig opened 3 years ago

anonrig commented 3 years ago

Using the following code on quibble fails

import WebhookExamples from '@octokit/webhooks-examples/api.github.com/index.json'
  Uncaught exception in test/events/github/delete.test.js

  TypeError [ERR_IMPORT_ASSERTION_TYPE_MISSING]: Module "file:///home/runner/work/api/api/node_modules/@octokit/webhooks-examples/api.github.com/index.json" needs an import assertion of type "json"

  › load (file://node_modules/quibble/lib/quibble.mjs:120:7)
searls commented 3 years ago

cc/ @giltayar -- I imagine we don't support loading fake JSON via ESM?

anonrig commented 3 years ago

Originally, I'm not mocking a json file, I'm just importing a JSON file outside of one of our unit tests, and somehow only on Github CI I receive this error. I couldn't replicate this issue on our local machine.

anonrig commented 3 years ago

@searls @giltayar I've once again opened a pull request to address this problem: https://github.com/testdouble/quibble/pull/56

giltayar commented 2 years ago

This has nothing to do with quibble: In ESM you're not allowed to import JSON, either with a loader or without. Try it without quibble: write an ESM file that tries to import a JSON, and it will fail.

This is by design, as TC39 didn't want to open this to JSON for security reasons. They fixed this security problem by a new feature in JS that allows you to assert that you want a JSON. This new JS feature is implemented in Node v17: https://nodejs.org/dist/latest-v17.x/docs/api/esm.html#import-assertions.

A good workaround for this (till you start using Node >= 17) would be to use require in the ESM. To use require in ESM, you need to use module.createRequire (https://nodejs.org/dist/latest-v17.x/docs/api/module.html#modulecreaterequirefilename).

anonrig commented 2 years ago

Hi Giltayar,

By default quibble assumes are imported giles are modules. The pull request I've opened properly sets the format for a json "module", and instead of just returns it as a module with a export default it just returns a stringified json.

Previously, the way quibble handled JSON "modules" was just wrong, even though it kind of works.

anonrig commented 2 years ago

Hi Giltayar,

By default quibble assumes are imported files are modules. The pull request I've opened properly sets the format for a json "module", and instead of just returns it as a module with a export default it just returns a stringified json.

Previously, the way quibble handled JSON "modules" was just wrong, even though it kind of worked.

giltayar commented 2 years ago

@anonrig I'm not sure you understood what I said above.

I just tried importing a JSON in regular Node.js (sans quibble):

image

As you can see from the screenshot it doesn't work in Node.js. So why should we make it work with quibble?

anonrig commented 2 years ago

The title of this issue is different from the error message you've provided.

anonrig commented 2 years ago

With the latest changes in Node.js 17.1.0, Node disables import of JSON modules without using an assertion. This pull request uses JSON assertion, and therefore handles 17.1.0

For more information about JSON assertions please look into https://github.com/nodejs/node/pull/40250

giltayar commented 2 years ago

I just tried this code in the current quibble:

import quibble from 'quibble'

await quibble.esm('./package.json', undefined, {version: 'worked!'})

console.log((await import('./package.json', {assert: {type: 'json'}})).default.version)

And it output worked, just like it should. (you need to run node with --experimental-json-modules for it to work)

This means that quibble supports JSON imports in Node>=17 out of the box.