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

CSS with [contenthash] not refreshing with HMR, webpack-dev-middleware #1089

Open
YellowSaleTag opened this issue Mar 17, 2024 · 6 comments
Open

Comments

@YellowSaleTag
Copy link

YellowSaleTag commented Mar 17, 2024

Bug report

CSS with [contenthash] not refreshing with HMR, webpack-dev-middleware

1. We see our stylesheet loaded in the document with the expected CSS.

Screenshot 2024-03-17 at 2 24 45 AM

2. We make an update to our CSS. We change the padding from 50 to 75 px.

Screenshot 2024-03-17 at 2 27 24 AM

3. We see a request in the network tab for the CSS update. However, the contents is stale. It has the old value of 50 px.

Screenshot 2024-03-17 at 2 31 01 AM

4. We refresh the page using the refresh button and see the updated value of 75 px.

Screenshot 2024-03-17 at 2 34 53 AM

Package Versions

"express": "4.18.2",
"webpack": "5.90.3",
"webpack-dev-middleware": "7.0.0",
"webpack-hot-middleware": "2.26.1",
"webpack-manifest-plugin": "5.0.0"

Webpack Config (relevant parts)

{
  name: '<build-name>',
  mode: 'development',
  devtool,
  context: __dirname,
  entry: [`webpack-hot-middleware/client?name=<build-name>&path=${publicPath}__webpack_hmr`],
  output: {
    chunkFilename: '[name].[contenthash].js',
    filename: '[name].[contenthash].js',
    path: path.resolve(__dirname, 'dist', 'browser'),
    publicPath
  },
  optimization: {
    splitChunks: {
      chunks: 'all'
    }
  },
  module: {
    rules: [
      {
        test: /\.(css)$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1, // https://webpack.js.org/loaders/css-loader/#importloaders
              modules: {
                localIdentName: '[hash:8]'
              }
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      inject: false,
      template: path.resolve(__dirname, 'src', 'targets', 'browser', 'index-browser.html')
    }),
    new MiniCssExtractPlugin({
      chunkFilename: '[name].[contenthash].css',
      filename: '[name].[contenthash].css'
    })
  ]
}

Middleware Config

webpackDevMiddleware(compiler, { serverSideRender: true })
webpackHotMiddleware(compiler, { path: `/dist/__webpack_hmr` })

Actual Behavior

  1. We see our stylesheet loaded in the document with the expected CSS.
  2. We make an update to our CSS. We change the padding from 50 to 75 px.
  3. We see a request in the network tab for the CSS update. However, the contents is stale. It has the old value of 50 px.
  4. We refresh the page using the refresh button and see the updated value of 75 px.

Expected Behavior

  1. The requested CSS via hot reload update should render the new CSS values and the page should update.

How Do We Reproduce?

Minimal configuration provided above for now...

Please paste the results of npx webpack-cli info here, and mention other relevant information

  System:
    OS: macOS 14.3.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 1.03 GB / 32.00 GB
  Binaries:
    Node: 18.19.0 - ~/.nvm/versions/node/v18.19.0/bin/node
    Yarn: 1.22.18 - /opt/homebrew/bin/yarn
    npm: 10.2.3 - ~/.nvm/versions/node/v18.19.0/bin/npm
  Browsers:
    Edge: 122.0.2365.92
    Safari: 17.3.1
  Packages:
    babel-loader: 9.1.3 => 9.1.3 
    copy-webpack-plugin: 12.0.2 => 12.0.2 
    css-loader: 6.8.1 => 6.8.1 
    html-webpack-plugin: 5.5.4 => 5.5.4 
    style-loader: 3.3.3 => 3.3.3 
    webpack: 5.90.3 => 5.90.3 
    webpack-cli: 5.1.4 => 5.1.4 
    webpack-hot-middleware: 2.26.1 => 2.26.1 
    webpack-manifest-plugin: 5.0.0 => 5.0.0 
  Global Packages:
    webpack: 5.90.3
@alexander-akait
Copy link
Member

Please create a github repo with the reproducible example of the problem, thank you

@YellowSaleTag
Copy link
Author

YellowSaleTag commented Mar 17, 2024

Thank you so much for taking the time to respond. I created a minimal example here.

@YellowSaleTag
Copy link
Author

YellowSaleTag commented Mar 17, 2024

I found the root cause.

It breaks when:

new MiniCssExtractPlugin({
  chunkFilename: '[name].[contenthash].id-[id].css',
  filename: '[name].[contenthash].css'
}),

It works when:

new MiniCssExtractPlugin({
  chunkFilename: '[name].[contenthash].id-[id].css',
  filename: '[name].css'
})

It seems [contenthash] with hot module reloading does not work. I use content hash to avoid caching of the CSS file.

Is there another way I can avoid caching of the css file?

I updated the minimal PoC to reflect this. Here too.

Attached is a screenshot of the PoC with [contenthash] and a stale CSS payload in hot reload network request.
Screenshot 2024-03-17 at 4 30 54 PM

@YellowSaleTag YellowSaleTag reopened this Mar 17, 2024
@YellowSaleTag YellowSaleTag changed the title CSS not automatically loading with HMR, webpack-dev-middleware CSS with [contenthash] not refreshing with HMR, webpack-dev-middleware Mar 17, 2024
@alexander-akait
Copy link
Member

alexander-akait commented Mar 18, 2024

Weird, I can't reproduce, even more, we have test cases for this...

@alexander-akait
Copy link
Member

alexander-akait commented Mar 18, 2024

Can you provide full steps using your repo above - https://github.com/YellowSaleTag/hmr-stale-css-payload/?

@YellowSaleTag
Copy link
Author

YellowSaleTag commented Mar 19, 2024

Hmm interesting, sure see the following.

  1. npm i
  2. npm run build
  3. npm run start
  4. browse localhost:3000
  5. inspect the network logs to see the main.css request and payload. confirm the html rule has padding of 200px
  6. change the padding value in ./app/components/App/app.css to 50 px
  7. confirm the hot update network request - main.css update request should have a payload with an html padding value of 50px
  8. kill the app
  9. modify ./webpack.config.js both lines 89 and 128. At these lines change [name].css to [name].[contenthash].css.
  10. run npm run build
  11. run npm run start
  12. follow steps 4, 5 (confirm 50px), 6 (update to 200px).
  13. follow step 7. except when you confirm the hot update request for main.[contenthash].css you'll find padding: 50px even though you changed it to 200px

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

2 participants