Skip to content
New issue

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

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

Already on GitHub? # to your account

fix: allow javascript dependencies to import other files without a file extension #31150

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

Netail
Copy link

@Netail Netail commented Feb 20, 2025

Additional details

When a dependency used by cypress specs was compiled to javascript and has type "type": "module", in the package.json, it throws the following error:

Did you mean 'request-method.js'?
BREAKING CHANGE: The request './request-method' failed to resolve only because it was resolved as fully specified
(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.

As the default typescript transpiler (tsc) does not add file extensions to the imports & exports I think it's best to allow resolving imports without a file extension by default.

Solution by: webpack/webpack#11467 (comment)

Also setting "moduleResolution": "Bundler", in the tsconfig.json does not seem to make a difference

Kind of like:

https://stackoverflow.com/questions/62619058/appending-js-extension-on-relative-import-statements-during-typescript-compilat
https://stackoverflow.com/questions/75807785/why-do-i-need-to-include-js-extension-in-typescript-import-for-custom-module

But on webpack level instead of runtime

Steps to test

Have a helper package which QAs can use, transpiled from typescript with tsc and use it in Cypress specs.

// --------- Specs
import { RequestMethod } from 'cypress-helpers';

...do something with this

// --------- Helper package

// package.json
{
    "name": "cypress-helpers",
    "type": "module",
    "main": "index.js"
	...
}

// index.js (barrel file)
export { RequestMethod } from './request-method';

// request-method.js
export var RequestMethod;
(function (RequestMethod) {
    RequestMethod["POST"] = "POST";
    RequestMethod["PUT"] = "PUT";
    RequestMethod["GET"] = "GET";
    RequestMethod["DELETE"] = "DELETE";
})(RequestMethod || (RequestMethod = {}));

How has the user experience changed?

Easier support for external helper packages transpiled by typescript

PR Tasks

@CLAassistant
Copy link

CLAassistant commented Feb 20, 2025

CLA assistant check
All committers have signed the CLA.

@cypress-app-bot
Copy link
Collaborator

@Netail
Copy link
Author

Netail commented Feb 20, 2025

Is there some way to try this locally, can't find the webpack configs in my node_modules. Maybe a PR version I can try?

Copy link
Contributor

@AtofStryker AtofStryker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Netail

Thank you for the contribution PR! I am not entirely sure this PR is completely passive but I think it should be, but I am also not convinced it fixes the issue. To help verify, are you able to provide a light reproduction of the extension problem you are seeing that I can run on my end? I'm curious to see what the bundle looks like.

On a side note, I think you need to run the linter on these files (should be a comma after the false).

Right now Cypress does some odd things when trying to run ESM Typescript projects. We are working on replacing the method we use to load and parse cypress typescript configs/projects for Cypress 15 which I would also like to run against your sample project if you are able to upload one.

@Netail
Copy link
Author

Netail commented Feb 21, 2025

Hi @AtofStryker
Sure, I'll get you a small repro tonight. Didn't had time yesterday, just wanted to get at least a draft version out of there with the question how I can change the webpack configs of Cypress locally.

Regarding the formatting, I used the online VSCode editor, but will get that sorted too

@Netail
Copy link
Author

Netail commented Feb 21, 2025

Here is a repro: : https://github.com/Netail/repro-cypress-esm, the instructions can be found in the README.

@Netail Netail requested a review from AtofStryker February 24, 2025 10:52
@AtofStryker
Copy link
Contributor

Here is a repro: : https://github.com/Netail/repro-cypress-esm, the instructions can be found in the README.

I was able to pull the repro down and run cypress against your branch. Unfortunately it doesn't fix the issue you are experiencing, but I think that is mostly due to @repo being a node_modules dependency, which we exclude from preprocessing, as packages installed are expected to be somewhat build environment agnostic. If I remove that line (even with the fullySpecified config removed), the changes work.

This wouldn't be something we would add since we expect dependencies to be transpiled already and would negatively impact the performance of the preprocessor, but if it is something you need you can download @cypress/webpack-preprocessor and pass in the webpack options you need there.

@Netail
Copy link
Author

Netail commented Feb 24, 2025

This wouldn't be something we would add since we expect dependencies to be transpiled already

But the thing is, the package IS transpiled to Javascript with TSC. It's just that the current webpack configuration does not like ESM imports/exports without a file extension.

would negatively impact the performance of the preprocessor

I think that would only be the case if it also had to transpile packages from Typescript to Javascript, only disabling fullySpecified won't make that much of a difference (if any at all).

--

And as the guys at Typescript mentioned they won't modify import/export URLs. I think from a DX point of view, supporting imports/exports without a file extension (The output by TSC), would be nice :)

We could add a seperate entry in the webpack config which disables fullySpecified for all js/mjs files (separate from the one excluding node_modules)

And it does seem like other people have ran into the same issue before (in their case Angular dependencies);

Preventing this issue, instead of manually adding a workaround would be great in terms of DX

@Netail Netail force-pushed the fix/resolve-javascript-without-ext branch from 3c291bb to 14feb6b Compare February 24, 2025 22:33
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants