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

CJS plugins file (and ideally also allowing an ESM one) #16467

Closed
brettz9 opened this issue May 12, 2021 · 21 comments
Closed

CJS plugins file (and ideally also allowing an ESM one) #16467

brettz9 opened this issue May 12, 2021 · 21 comments

Comments

@brettz9
Copy link

brettz9 commented May 12, 2021

Especially with Node 10 reaching EOL, and native ESM being used increasingly in Node projects (type: module in package.json), including those which may also house browser code in need of testing, the apparent inability to use at least an index.cjs plugins file with Cypress seems rather problematic. (It complains about the extension; pointing pluginsFile in cypress.json to a .cjs file didn't work either; only switching to .js works--or removing type: module but that causes problems for Node ESM execution.)

(Please note that I'm not speaking about a @babel/register problem--I mean one simply can't use a cjs file at all.)

Are there any plans (or workarounds) about this? Thanks!

@sainthkh sainthkh added the stage: proposal 💡 No work has been done of this issue label Jun 14, 2021
@zhammer
Copy link

zhammer commented Jun 14, 2021

my workaround was switching index.js to index.ts, then using ESM style imports. i have my repo configured for typescript elsewhere though; this'd be more trouble if your project doesn't already use typescript

@brettz9
Copy link
Author

brettz9 commented Jun 16, 2021

Yeah, thanks. In my case, however, I'm not using TS and not inclined to do so.

@brettz9
Copy link
Author

brettz9 commented Jul 10, 2021

Could I ask where this might fit on your overall priorities? I don't see anything at https://docs.cypress.io/guides/references/roadmap but this is kind of a blocker for many projects wishing to convert to native ESM. Thanks!

@bahmutov
Copy link
Contributor

bahmutov commented Jul 10, 2021 via email

@brettz9
Copy link
Author

brettz9 commented Jul 10, 2021

As per the blog post referenced in the OP, the prolific npm publisher, sindresorhus (over 1100 projects, many of which are well-used) has begun migrating projects to be ESM only. (One popular one, got has 15 million weekly downloads, though I don't know how many are using the latest version.) I recently needed a smaller package, semver-regex which similar is ESM only and perhaps another I can't recall now, but a greater issue for me personally at this time is more about my own projects.

I would very much prefer to migrate to ESM (as I have already begun to do on my non-UI projects) for various reasons:

  1. To do my own small part to encourage the transition (a change which avoids extra tooling and expands libraries that may work out-of-the-box in browsers)
  2. To get started on more future-proofed code without the hassle of converting the codebase later (though preferably without the hassle now of having to add a build step in those subset of Node projects where I don't want or need such a step). (Node docs mentioned the type in package.json could switch in the future to default to module, thus potentially breaking old code in the future. However far-off or unlikely that might seem now, it is assuring and appealing to ensure one's ESM code is working not just with bundlers but with actual native ESM.)
  3. Avoiding a build step for browser-compatible code (e.g., for code that can be simply imported by one's own ESM-using browser demos or where a project just leaves it to consumers to build their targets from a ESM distribution).

ESM appears to be a popular development (e.g., some feature requests related to ESM indicate "strongly positive" feedback from web developers on the likes of import maps), and I think developers are just eager to finally make the transition, particularly I would imagine, those developers who are concerned enough about the quality and up-to-date maintenance of their code, such as Cypress users I would imagine would tend to be.

I expect at least sindresorhus' projects are likely to nudge some to make the transition in the present or nearer future (not to mention I now can't use my own ESM-only projects I already have created, either! :-) ), but as mentioned, my main concern at this point is not so much that I have to change now, so much as that I can't set my projects up as I'd like or need to do my own extra build steps for others' (or my own) code.

So this might not be a huge blocker yet, but with Node 10 end-of-lifed, native ESM is now available, and people such as myself do want to start using it (and not being forced to use ".mjs" everywhere), as well as follow a best practice that many projects have been following well before native ESM was available, not to mention get access to the smaller number of ESM-only packages that are being created. Thanks!

@bahmutov
Copy link
Contributor

Can you set up a tiny example repo that fails to run because of esm module use? So what we discuss is concrete rather than abstract?

@brettz9
Copy link
Author

brettz9 commented Jul 10, 2021

Sure. See https://github.com/brettz9/cypress-esm . It is a very minimalist repo, as it is easy to reproduce. See the README for how the options to try to fix it (without getting rid of type: 'module') also don't work.

@IanVS
Copy link
Contributor

IanVS commented Jul 13, 2021

I wanted to chime in to say that I just installed cypress and ran npx cypress open and was met with an error The plugins file is missing or invalid.. I am guessing this is because I have "type": "module" set in my package.json. I think that's not a great experience for a new user, so it would be great to either support ESM, or create an index.cjs file when it's detected that the project is using ESM. Changing the filename manually seems to have resolved the error (using cypress 7.7.0).

Edit: nevermind, changing the name to index.cjs removes the error but the file seems to silently not be detected/used. That's also a bit confusing, since I thought it was working but couldn't figure out what I was doing wrong that caused my changes not to take effect.

@stolinski
Copy link

@IanVS did you get Cypress working with type:'module' ?

@IanVS
Copy link
Contributor

IanVS commented Aug 23, 2021

Yes, I changed my files to typescript which works fine. My point was to mention that the experience is somewhat broken for new users.

@AlexMoutonNoble
Copy link

one more here for cjs please

@albertstill
Copy link

albertstill commented Nov 17, 2021

+1 for ESM support, this is the only tool I use that doesn't support it, I have to manually remove the type=module field from my package.json to run e2e.

I would suggest doing something similar to Jest, it catches the ESM error after require and does a dynamic import, https://github.com/facebook/jest/blob/09278348b355c0450ddd6d40d074e69e4add688e/packages/jest-util/src/requireOrImportModule.ts#L34

I wrote an article about migrating a server and it's tools to ESM here that might be useful for reference https://medium.com/@albertstill/is-node-ready-for-native-ecmascript-modules-b8c6d5463d67

@giltayar
Copy link

A simple workaround, till Cypress enables *.cjs configuration scripts, is to add a package.json in the cypress/plugins and cypress/supportfolders that have the following text in them:

{"type": "commonjs"}

This tells Node.js that all "js" files in this folder are CJS, and Cypress will load them without any problem.

@pbadenski
Copy link

Lack of ESM support in Cypress is indeed a bit of a buzkill. We're trying to incrementally migrate our project to ESM. We started with Webpack configs and had to revert because of Cypress - we reuse our webpack configs in Cypress setup and aren't able to import webpack.config.mjs to Cypress because of lack of ESM support.

@dbo
Copy link

dbo commented Feb 22, 2022

The trick mentioned by @giltayar works for me, too. I don't need one for the support folder, since that seems to just work fine when webpack'ed. I am using "type": "module" throughout the workspace with cypress 9.5.

@dbo
Copy link

dbo commented Feb 22, 2022

One important detail though is that since the plugins file is commonJS, the only way to use your esm modules is via dynamic import, e.g.

const webpackPreprocessor = require("@cypress/webpack-preprocessor");

module.exports = async (on, config) => {
    const {default: webpackOptions} = await import("../../webpack.config.mjs");

    on("file:preprocessor", webpackPreprocessor({
        webpackOptions,
    }));
...

@pbadenski
Copy link

Works for me @dbo, thank you!!

@NorseGaud
Copy link

New user of Cypress here and this really caused me a lot of headaches.

@zhammer
Copy link

zhammer commented Apr 25, 2022

#16467 (comment)

this also has stopped working for me after some version upgrades :/

@lmiller1990
Copy link
Contributor

I think we are now working with type: module. Is this still an issue?
If it is, please post a reproduction and I will fix it.

@brettz9
Copy link
Author

brettz9 commented Nov 8, 2022

Yes, seems to be working now, thanks, so closing.

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