[New to webpack]autoprefix problem with webpack manifest plugin

Viewed 3507

I tried to use webpack manifest plugin to build manifest.json file that has keys and values of my assets with contenthash in its name, but it include prefix "auto" in value and my index.html has the href and src with prefix keyword "auto" in path also. And It's not working in testing server because It can't locate the real files. How could i fix this?

const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const {
  CleanWebpackPlugin
} = require('clean-webpack-plugin');
const {
  WebpackManifestPlugin
} = require('webpack-manifest-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
  //watch: true,
  mode: "production",
  devtool: "eval-cheap-module-source-map",
  entry: {
    application: "./src/index.js",
    admin: './src/admin.js'
  },
  output: {
    filename: "[name]-[contenthash].js",
    path: path.resolve(__dirname, 'build')
  },
  optimization: {
    minimizer: [
      new TerserJSPlugin({}),
      new OptimizeCssAssetsPlugin({})
    ]
  },
  module: {
    rules: [{
        test: /\m?js$/,
        exclude: '/(node_modules|bower_components)/',
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      },
      {
        test: /\.css$/i,
        use: [
          //'style-loader',
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: ''
            }
          },
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1
            }
          }, {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                plugins: [
                  require('autoprefixer')({
                    overrideBrowserslist: ['last 3 versions', 'ie >9']
                  })
                ]
              }
            }
          }
        ]
      },
      {
        test: /\.scss$/i,
        use: [
          //'style-loader',
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: ''
            }
          },
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1
            }
          },
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                plugins: [
                  require('autoprefixer')({
                    overrideBrowserslist: ['last 3 versions', 'ie >9']
                  })
                ]
              }
            }
          }, 'sass-loader'
        ]
      },
      {
        test: /\.(png|jpg|gif|svg)$/i,
        use: [{
            loader: 'url-loader',
            options: {
              limit: 8192,
              name: '[name].[hash:7].[ext]'
            }
          },
          {
            loader: 'image-webpack-loader'
          }
        ]
      },
      {
        test: /\.html$/,
        loader: 'html-loader'
      },
      {
        test: /\.ejs$/,
        loader: 'ejs-loader',
        options: {
          variable: 'data',
          interpolate: '\\{\\{(.+?)\\}\\}',
          evaluate: '\\[\\[(.+?)\\]\\]'
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/template.html'
    }),
    new WebpackManifestPlugin({

    }),
    new CleanWebpackPlugin(),
    new MiniCssExtractPlugin({
      filename: "[name]-[contenthash].css"
    })
  ]
}
Manifest.json {
  "application.css": "autoapplication-4a5eb857061be614f4b2.css", "application.js": "autoapplication-b35460853f853e901d54.js", "application.jpg": "autobooks.df4be51.jpg", "admin.css": "autoadmin-4a5eb857061be614f4b2.css", "admin.js": "autoadmin-00cdbe24c96699757b97.js", "admin.jpg": "autobooks.df4be51.jpg", "books.jpg": "autobooks.df4be51.jpg"
}
<!doctype html>
<html lang="en" dir="ltr">

<head>
  <meta charset="utf-8">
  <title>My Custom template</title>
  <link href="auto/application-4a5eb857061be614f4b2.css" rel="stylesheet">
  <link href="auto/admin-4a5eb857061be614f4b2.css" rel="stylesheet">
</head>

<body>
  <p style="background:white">Test Template</p>
  <script src="auto/application-b35460853f853e901d54.js"></script>
  <script src="auto/admin-00cdbe24c96699757b97.js"></script>
</body>

</html>

2 Answers

TLDR; Updating publicPath of your webpack config to "" should fix the issue.

Details: It's likely because you've migrated to webpack 5. Refer to the docs on webpack5 migration for further details: https://webpack.js.org/migrate/5/

Not all ecosystem tooling is ready for the new default automatic publicPath via output.publicPath: "auto"
Use a static output.publicPath: "" instead.

Fist, you need

postcss.config.js in /:

module.exports = {
    plugins: [
      require('autoprefixer')({
          overrideBrowserslist:
         ['last 3 versions', 'ie >9']})
    ]
  }

Remove in .css and sass :

plugins: [
require('autoprefixer')({
overrideBrowserslist: ['last 3 versions', 'ie >9']
})

And change:

devtool: "eval-cheap-module-source-map",

for :

 devtool: 'source-map',

This is a file manifest.json before execution:

{
"application.css": "autoapplication.css",
"application.js": "autoapplication.js",
"admin.css": "autoadmin.css",
  "admin.js": "autoadmin.js",
}

Run :

npm run build / or npm run prod

Now Open manifest.json:

{
  "application.css": "autoapplication.css",
  "application.js": "autoapplication.js",
  "application.css.map": "autoapplication.css.map",
  "application.js.map": "autoapplication.js.map",
  "admin.css": "autoadmin.css",
  "admin.js": "autoadmin.js",
  "admin.css.map": "autoadmin.css.map",
  "admin.js.map": "autoadmin.js.map"
}

() ==>: Source map points to the source of our message log.

Related