webpack-contrib / mini-css-extract-plugin

Lightweight CSS extraction plugin
MIT License
4.66k stars 388 forks source link

The publicPath in the CSS file is incorrect, when using webpack cache filesystem #1065

Closed simon-woo closed 8 months ago

simon-woo commented 11 months ago
// webpack.config.js

const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const webpack = require("webpack");

module.exports = {
  mode: "development",
  entry: {
    main: "/src/main.js",
  },
  optimization: {
    minimize: false,
    runtimeChunk: {
      name: "runtime",
    },
  },
  cache: {
    type: "filesystem",
    buildDependencies: {
      config: [__filename],
    },
  },
  output: {
    publicPath: process["env"]["NODE_ENV"],
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          { loader: MiniCssExtractPlugin.loader },
          {
            loader: "css-loader",
            options: {
              importLoaders: 2,
              sourceMap: false,
              modules: false,
            },
          },
        ],
      },
      {
        test: /\.(ico|gif|png|jpg|jpeg|webp)$/i,
        oneOf: [
          {
            type: "asset/resource",
            generator: {
              filename: "[name]-[hash:8][ext]",
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name].[chunkhash:8].css",
      chunkFilename: "[name].[id].css",
    }),
    new webpack.CleanPlugin(),
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: "src/index.html",
      inject: "body",
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true,
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: "auto",
    }),
  ],
};
// package.json
{
  "name": "asset-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --node-env /sit-12.45/"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "assets-webpack-plugin": "^7.1.1",
    "css-loader": "^6.8.1",
    "html-webpack-plugin": "^5.5.4",
    "mini-css-extract-plugin": "^2.7.6",
    "webpack": "^5.89.0",
    "webpack-cli": "^5.1.4"
  }
}

Bug report

Actual Behavior

In my project, publicPath is a variable that changes every time it is packaged When I change the sit version in package.json, I expect the publicPath of the background image: URL (${publicPath}/collect. png) in the CSS file to change

Expected Behavior

But the actual packaging result has not changed, Still the previous version

// package.json
"build": "webpack --node-env /sit-12.45/"
// dist/ main.css
#test{
      background-image: url(/sit-12.44/collect-f3bfe062.png);
}

How Do We Reproduce?

https://github.com/simon-woo/minicssextract-assets

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

simon-woo commented 11 months ago

Hi alexander, can you help? @alexander-akait

edwardw-cit commented 11 months ago

I face the same issue, perhaps the

      const isAbsolutePublicPath = /^[a-zA-Z][a-zA-Z\d+\-.]*?:/.test(publicPath);

reg test is not correct?

simon-woo commented 11 months ago

When I enable caching and execute build, the picth method stops executing. It seems that it's not because of mini-css-extract-plugin, but because of the webpack caching mechanism. @edwardw-cit image

simon-woo commented 11 months ago

The current question is whether using dynamic publicePath can we use webpack5's filesystem cache?

edwardw-cit commented 11 months ago

image

I can get in the pitch function when i enable the webpack cache, looks like you are using different version of the Mini plugin? @simon-woo , or you have multiple version in node_modules?

simon-woo commented 11 months ago

image

I can get in the pitch function when i enable the webpack cache, looks like you are using different version of the Mini plugin? @simon-woo , or you have multiple version in node_modules?

I am using version 2.7.6, and webpack cache is filesystem mode. https://github.com/simon-woo/minicssextract-assets

simon-woo commented 11 months ago

The first build is definitely executed, and the second time using a cached build, it should not be executed @edwardw-cit

edwardw-cit commented 11 months ago

yeah, i'm not sure this issue is related with the cache system. The function executed only once in my scenario whatever the webpack cache system enabled or not. @simon-woo

alexander-akait commented 10 months ago

Hello, sorry for delay, I will look at this soon

alexander-akait commented 10 months ago

@simon-woo I tried to reproduce the problem using your repo, but no luck, all works as expected, can you provide more details, like your OS, environment, maybe video or screenshots

alexander-akait commented 10 months ago

Also check you don't have different caches between git branches or etc

alexander-akait commented 8 months ago

I see the problem, just use:

 cache: {
    type: "filesystem",
    version: JSON.stringify(process["env"]["NODE_ENV"]),
    buildDependencies: {
      config: [__filename],
    },
  },

you can pass any numbers of arguments to JSON.stringify, because we can't know what is --node-env /sit-12.45/ and can't undestand when we should invalidate cache, we have the version option, note webpack will override previous cache, but if you want to have multiple caches you can use the name option, for example:

 cache: {
    name: `my-unique-name-${process["env"]["NODE_ENV"]}`
    type: "filesystem",
    buildDependencies: {
      config: [__filename],
    },
  },

So it will use different caches when you have different value of process["env"]["NODE_ENV"]

I used process["env"]["NODE_ENV"] to provide an example as in your repo, but I think in the real application you have other env variables (i.e. process["env"]["MY_PUBLIC_PATH"])

Feel free to feedback