cypress-io / cypress

Fast, easy and reliable testing for anything that runs in a browser.
https://cypress.io
MIT License
47.01k stars 3.18k forks source link

Allow `@cypress/webpack-dev-server` webpack configuration `optimization` options to act as defaults and not overrides #29073

Open AtofStryker opened 8 months ago

AtofStryker commented 8 months ago

What would you like?

For @cypress/webpack-dev-server, we want to allow the optimization option defined in makeDefaultWebpackConfig to act as user defaults for their component testing. However, users should be able to specify different configuration options in their webpack configuration to override these defaults. Currently that is not happening and is not possible without patching the package.

Why is this needed?

Many of our users with larger component testing suites are running into ChunkLoadError issues from within their CI runs. This likely has to do with async chunks timing out in the browser and are failing to load.

To remedy this, the internal cypress team has had some luck in setting the splitChunks options to initial instead of all (see splitChunks.chunks). Since we cannot currently configure the optimization option for @cypress/webpack-dev-server, we needed to install @cypress/webpack-dev-server as a separate package and patch it via patch-package to remove the override option splitChunks.chunks = 'all' and pass in initial config when spinning up the dev server, like so:

cypress.config.js

import { devServer } from '@cypress/webpack-dev-server'

export default {
  component: {
    devServer: (devServerConfig) => {
      webpackConfig.optimization.splitChunks.chunks = 'initial'
      return devServer({
        ...devServerConfig,
        framework: 'react',
        bundler: 'webpack',
        webpackConfig,
      })
    },
  },
}

The patch looks something like this:

If we can give users a way to control the optimization options from within the dev server without overriding them, they can likely configure and tune their splitChunks optimization to fit their needs. In the case of the ChunkLoadError, omit async chunks.

Other

No response

raphaelbadia commented 6 months ago

Hello, where does the webpackConfig variable comes from in your example ?

My config currently looks like this :

component: {
    downloadsFolder: '/tmp/cypress/downloads', // the default download folder triggers a hot reload when downloading files, which makes the tests loop over and over
    specPattern: '**/*.(cy|spec).(ts|tsx)',
    supportFile: 'cypress/support/component.tsx',
    setupNodeEvents(on, config) {
      require('cypress-fail-fast/plugin')(on, config);
      return config;
    },
    devServer: {
      framework: 'next',
      bundler: 'webpack',
      webpackConfig: {
        devServer: {
          port: process.env.CYPRESS_WEBPACK_DEV_SERVER ?? 8080,
        },
        plugins: [
          new NormalModuleReplacementPlugin(
            /next\/image/,
            require.resolve(path.join(__dirname, 'mocks', 'next', 'image.tsx')),
          ),
        ],
      },
    },

I don't think I have the ability to use a function instead of the webpackConfig object :

Screenshot 2024-05-02 at 10 14 29

AtofStryker commented 6 months ago

In this example it can be defined in the file or you can import it, like:

import { devServer } from '@cypress/webpack-dev-server'
import webpackConfig from './my-webpack-config-location'

export default {
  component: {
    devServer: (devServerConfig) => {
      webpackConfig.optimization.splitChunks.chunks = 'initial'
      return devServer({
        ...devServerConfig,
        framework: 'react',
        bundler: 'webpack',
        webpackConfig,
      })
    },
  },
}
raphaelbadia commented 6 months ago

ok thanks, for nextjs we don't have access to the webpack config so I guess I'll wait for this issue to be handled ! ☺️