question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Some dependencies don't support ES modules

See original GitHub issue

Edit 2: Per request, I’ve simplified this down to a few simple questions and answers.

What did you do? I attempted to use dom-testing-library in a test suite that’s be run via Web Test Runner.

What happened? The test runner bombed out complaining about CJS modules that are dependencies of dom-testing-library: aria-query, corejs, and lz-string. There may be more but that’s as far as I spent time digging into them. image

What did you expect to happen? I expected the test runner to actually run without dependency errors.

Is there a repro? https://github.com/jimsimon/wtr-dtl/tree/wtr-using-wds (note the branch name)

What have you tried so far? I’ve tried using the Web Test Runner’s CJS support that leverages Rollup’s CJS plugin but that did not help. It appears the dependencies causing the errors are not supported by Rollup’s CJS plugin.

Is there a proposed solution? Upgrade to versions of these dependencies that support native ES modules or migrate to alternatives that do.

Any other notes? One of the conflicting dependencies (aria-query) was updated in #1058 so that one may no longer be problematic. I haven’t had a chance to test it though. I just tried the repro with the latest versions of all dependencies and I’m still having issues.



------------------------------------------------ FIRST EDIT STARTS BELOW -----------------------------------------------------------

Edit: This issue originally started as a request to have dom-testing-library broken down into separate packages to make it easier to consume by non-Jest based test runners. It has since transformed into a discussion about what’s preventing dom-testing-libary form working with web-test-runner. In an effort to focus this ticket, I’ve copied the relevant parts of the conversation below.

First a TLDR: dom-testing-library does not work with web-test-runner. Multiple dependencies used by dom-testing-library do not publish native esm modules and are not compatible with rollup’s commonjs plugin (which can be used by web-test-runner). One big offender is aria-query, which may be fixed with #1058 but has not been tested yet. Main repro can be found in https://github.com/jimsimon/wtr-dtl/tree/wtr-using-wds (note the branch name since there are multiple different repros for different attempts to workaround the problem in this repo).

The main problem is that web-test-runner is designed for “buildless” environments using entirely native ESM in the browser. Dom-testing-library has a handful of dependencies that only provide CJS modules that don’t play nice in this environment. You can actually use the rollup commonjs plugin for some of these, but some still don’t work. Specifically, I recall running into issues with aria-query, corejs, and lz-string. The corejs dependency is some sort of weird prebundled one coming transitively via aria-query.

I’ll try to create a sample repo tomorrow and provide a link here, but it’s pretty simple to replicate. Create a brand new node project, add web-test-runner and dom-testing-library, write a simple test that uses screen, run the tests via web-test-runner. You’ll see web-test-runner just choke and/or throw an error about the CJS deps.

The most success I’ve had was using snowpack with their web-test-runner plugin in “remote” dependency mode. Unfortunately even that approach errors out.

My suggestion to split the queries out to a separate package was to hopefully reduce the dependency load. A better approach might be to work towards updating to dependencies that also provide native ESM distributions (or remove them altogether).

– <cite>@jimsimon</cite>

Does web-test-runner use the module field in package.json?

– <cite>@nickmccurdy</cite>

It does as it actually uses https://github.com/rollup/plugins/tree/master/packages/node-resolve under the hood for them. Just for clarity sake, web-test-runner is built on top of web-dev-server, which is what actually handles file transformation.

The main issue seems to be some dependencies that aren’t providing ESM distributions. Aria-query in specific is keeping corejs3-runtime as a dependency to support people still on Node 6. There’s a ton of discussions about that in https://github.com/A11yance/aria-query/issues/158 and a PR to clean a lot of it up here: https://github.com/A11yance/aria-query/pull/180. So it seems part of the solution here may be to encourage that PR to move forward and then update dom-testing-library accordingly? There are still other dependencies that may need updating as well, but maybe there’s some alternatives that provide ESM output available?

– <cite>@jimsimon</cite>

I pushed up a couple versions of my demo repo:

Snowpack using remote sources (main branch): https://github.com/jimsimon/wtr-dtl Snowpack using local sources (snowpack-local branch): https://github.com/jimsimon/wtr-dtl/tree/snowpack-local WTR using it’s built in Web Dev Server + ESBuild (wtr-using-wds branch): https://github.com/jimsimon/wtr-dtl/tree/wtr-using-wds Hopefully these help. The last link is the one I’d most like to see working and is what spawned this ticket and convo. The Snowpack stuff was an attempt at working around the issue.

Note: The test won’t actually pass if you get it to run. That’s a different issue/concern regarding being able to pass ShadowRoot to queries. I’m hoping we can address that in a different issue/ticket if we can get this one resolved.

– <cite>@jimsimon</cite>

Note that @testing-library/dom itself would not work with native ES modules. But then I see mentions of aria-query which may be fixed with https://github.com/testing-library/dom-testing-library/pull/1058.

So could somebody summarize what the issue is? The issue description is currently missing what is concretely not working (ideally with a repro).

– <cite>@eps1lon</cite>

This is the end of the conversation as of this edit. Hopefully this helps!



--------------------------- ORIGINAL ISSUE DESCRIPTION BELOW -------------------------------------------------

Suggested implementation:

Create a new @testing-library/queries package and move all query related code to it.

Describe alternatives you’ve considered:

The only alternative I can think of would be to reimplement the same queries in an entirely new project. This seems like wasted effort if we can simply extract the ones that testing-library already provides.

Teachability, Documentation, Adoption, Migration Strategy:

There should be no outward facing impact on users as API’s would remain backwards compatible. Documentation for the new package would need to be created, and some minor documentation updates might be needed for the main site.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:4
  • Comments:25 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
sheremet-vacommented, Aug 3, 2022

Could you file an issue against NodeJS in that case please? Their documentation clearly states you can import CommonJS from ES modules:

An import statement can reference an ES module or a CommonJS module.

It doesn’t contradict documentation. You can import CJS module, but you might not be able to use named exports, if they are not statically analysable:

Live binding updates or new exports added to module.exports are not detected for these named exports.

The detection of named exports is based on common syntax patterns but does not always correctly detect named exports. In these cases, using the default import form described above can be a better option.

Named exports detection covers many common export patterns, reexport patterns and build tool and transpiler outputs. See cjs-module-lexer for the exact semantics implemented.

https://nodejs.org/api/esm.html#commonjs-namespaces

If it cannot detect a named export, it will throw an error that I described.

I think in this specific case it has more to do with the way we import

Yes, technically lz-string cannot be exported as { namedExport }, since its exports are not statically analysable (it just puts an object on module.exports - as you can see from the quote above these bindings are not detectable).

I made a small reproduction for you, using stackblitz: https://stackblitz.com/edit/node-fpxnof?file=index.mjs

There are several ways to fix this:

  • If you use typescript, you can use import name = require('path'), which is a way to tell typescript to use require here
  • You can also use what Node recommends in its error: import defaultLz from 'lz-string'; const { namedExport } = defaultLz
1reaction
sheremet-vacommented, Aug 3, 2022

I’m having a hard time understanding why this is an issue on our side? So far the guarantee was always that you can import CJS from ESM. So everything should be working without any work on our side.

@eps1lon this is not actually true. Node cannot guarantee safe importing. I am trying to create a loader that will allow Node to understand module field, and I was quite successful with it. However, Node doesn’t allow importing named exports, if it didn’t find them (they were defined not in a global namespace, or dynamically). Currently, I am getting this error from this package:

SyntaxError: Named export 'compressToEncodedURIComponent' not found. The requested module 'lz-string' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'lz-string';
const { compressToEncodedURIComponent } = pkg;

I guess the solution would be to use import { compressToEncodedURIComponent } = require('lz-string'). That way transpiler can understand that you use CJS package, and will transform it into:

const require = createRequire(import.meta.url)
const { compressToEncodedURIComponent } = require('lz-string')
Read more comments on GitHub >

github_iconTop Results From Across the Web

Error [ERR_REQUIRE_ESM]: require() of ES Module not ...
However I keep getting this message: [ERR_REQUIRE_ESM]: require() of ES Module from not supported. Instead change the require of index.js in...
Read more >
Node Modules at War: Why CommonJS and ES ... - Code Red
In Node 14, there are now two kinds of scripts: there are old-style CommonJS (CJS) scripts and new-style ESM scripts (aka MJS).
Read more >
Using ES modules in Node.js - LogRocket Blog
Learn about the state of ES modules in Node today, including concerns realted to transitioning from and interoperability with CommonJS.
Read more >
CommonJS vs ES Modules in Node.js - A Detailed Comparison
However, NodeJS supports the CommonJS module format by default, ... ES modules do not have any dependencies other than the module loader ...
Read more >
How to Bypass ES Modules Errors in Next.js with Dynamic ...
When we begin to interface with a lot of dependencies or packages in our applications, some things might start going wrong if we...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found