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

fix: Webpack 5 automatic publicPath error #23760

Merged
merged 9 commits into from
Sep 19, 2022

Conversation

caseyjhol
Copy link
Contributor

@caseyjhol caseyjhol commented Sep 9, 2022

User facing changelog

Fixed an issue with Webpack 5 and modules that contain dynamic imports. Fixes #18435.

Additional details

This PR implements the fix suggested in the relevant issue. The default publicPath value in Webpack < 5 is ''. In Webpack 5, it's 'auto'. So, this is a backwards compatible change that will have no effect in prior versions of Webpack.

PR Tasks

  • Have tests been added/updated?
  • Has the original issue (or this PR, if no issue exists) been tagged with a release in ZenHub? (user-facing changes only)
  • Has a PR for user-facing changes been opened in cypress-documentation?
  • Have API changes been updated in the type definitions?

@cypress-bot
Copy link
Contributor

cypress-bot bot commented Sep 9, 2022

Thanks for taking the time to open a PR!

@CLAassistant
Copy link

CLAassistant commented Sep 9, 2022

CLA assistant check
All committers have signed the CLA.

@caseyjhol caseyjhol marked this pull request as ready for review September 9, 2022 19:09
@emilyrohrbough
Copy link
Member

@ZachJW34 I know you are familiar with this package (at least more-so than me) and can better evaluate the impact of adding this default value. Mind taking a look? Wondering if this should really be in the batteries-included package?

@ZachJW34
Copy link
Contributor

ZachJW34 commented Sep 9, 2022

@emilyrohrbough not too familiar but the change makes sense to me. With the change being in @cypress/webpack-preprocessor, the @cypress/webpack-preprocessor-batteries-included package will inherit the changes made to it and we want the change in both.

Do you know if we document the usage of our webpack preprocessors with Webpack 5? I feel like a system-test would make sense here, even if it's not officially supported since it seems like a lot of users are doing this.

@lmiller1990
Copy link
Contributor

We do document webpack 5

This version is only compatible with webpack 4.x+ and Babel 7.x+.

There have been a few PRs fixing the preprocessor for webpack 5 over the last little while. I agree a system test makes sense, lucky there's a minimal reproduction here we could use: #18435

@ZachJW34
Copy link
Contributor

@caseyjhol have you tried this change out for a project that contains a dynamic import? I wrote a system test here and had to make some additional changes to disable webpack chunking, otherwise the webpack will create an additional chunk for the dynamic import and then fail to fetch the chunk.

@caseyjhol
Copy link
Contributor Author

@ZachJW34 Ah, good catch. This change resolved an issue I was having when an import contained a function that called a dynamic import, but that function wasn't actually being called in my spec. I tested calling the function from my spec and ran into the error you described.

I think disabling Webpack chunking makes sense for now, but it might be good to get to the root of the problem - why isn't code splitting working? I could imagine a scenario where someone writes a test to explicitly check that code splitting is working as expected. However, I'm sure in most cases having code splitting disabled for tests would be more desirable.

@ZachJW34
Copy link
Contributor

@caseyjhol I don't think there is a valid use case for testing that something was actually code-split as that is an implementation detail of the bundler being used. The bundling of the spec and the bundling of the application under test are separate, so I don't see any value in testing that your specs are being code-split.

The webpack-preprocessor compiles a spec when a request for the spec is made and the assumption is that all the code for that spec is bundled in a single file that we can execute once fetched. In most scenarios, most people shouldn't be dynamically importing code in their spec files as there is no benefit over a top-level import/require. That said, it should still work (especially when it comes to importing a library that might be using a dynamic import, the syntax should be valid but we don't actually care about the code-splitting). To actually support code-splitting, we would have to have an endpoint to proxy the request to where we disted the result of the compilation, or run a dev-server locally that we could proxy to. Not sure there is any value in this so I'm good with limiting the number of chunks to 1.

As for the PR, do you want me to submit a PR to your fork (given that I have permissions)? Or you could copy/paste the code from my branch and push up a commit. Up to you!

@caseyjhol
Copy link
Contributor Author

caseyjhol commented Sep 13, 2022

@ZachJW34 Agreed - that makes sense! That would be great if you could update my PR if you have the chance. Otherwise I'll try to get to it ASAP. Merged in your changes.

@ZachJW34
Copy link
Contributor

ZachJW34 commented Sep 14, 2022

@caseyjhol can you give me permissions to push to your fork?

Edit: Looks like you got it! Cool will review soon

@ZachJW34
Copy link
Contributor

@caseyjhol looks like the webpack-preprocessor tests are failing (due to my recommended changes 😅). Can you add:

const LimitChunkCountPluginStub = sinon.stub()

webpack.optimize = {
  LimitChunkCountPlugin: LimitChunkCountPluginStub,
}

to the npm/webpack-preprocessor/test/unit/index.spec.js before the mock is registered? This would be right after the const webpack = sinon.stub() on line 12. This should fix up the test.

Copy link
Contributor

@lmiller1990 lmiller1990 left a comment

Choose a reason for hiding this comment

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

One q, this is looking pretty good


Module._load = function (request, parent, isMain) {
if (request === 'webpack' || request.startsWith('webpack/')) {
const resolvePath = require.resolve(request, {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to try/catch this?

Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't hurt adding it for safety, where it falls back to the original load if it throws

Copy link
Contributor

@lmiller1990 lmiller1990 Sep 16, 2022

Choose a reason for hiding this comment

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

Ok, I'll leave it to youif you want to add it... dropped a ✅

@lmiller1990 lmiller1990 self-requested a review September 16, 2022 00:42
@lmiller1990 lmiller1990 removed the request for review from emilyrohrbough September 19, 2022 01:33
@lmiller1990
Copy link
Contributor

Nice job @caseyjhol this will be in the next release 🎉

@OliverJAsh
Copy link
Contributor

I'm not sure this fixed #18435. I can still reproduce this issue. See #24034.

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

Successfully merging this pull request may close these issues.

webpack v5 error when module contains dynamic import: "Automatic publicPath is not supported in this browser"
6 participants