简体   繁体   English

PurgeCss Webpack Plugin 不输出未使用的 CSS,带有 purged: true

[英]PurgeCss Webpack Plugin doesn't output unused CSS with purged: true

I want to see what CSS has been purged with PurgeCss Webpack plugin, but for some reason the purged: true doesn't output it to the compilation-stats.json as described in the docs .我想看看用 PurgeCss Webpack 插件清除了哪些 CSS,但由于某种原因, purged purged: true没有将其输出到docs 中所述compilation-stats.json

Here is my build command:这是我的构建命令:

./node_modules/.bin/webpack --mode=production --progress --profile --color --config webpack.config.js  --json > compilation-stats.json

Any ideas on how to see the purged CSS?关于如何查看已清除的 CSS 的任何想法?

Here is my webpack config:这是我的 webpack 配置:

var webpack = require("webpack");
const path = require("path");
const glob = require("glob");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require("copy-webpack-plugin");
const PurgeCSSPlugin = require("purgecss-webpack-plugin");

const customExtractor = (content) => {
  const res = content.match(/[A-z0-9-:/]+/g) || [];
  return res;
};

const PATHS = {
  src: path.join(__dirname, "views"),
};

const devMode = process.env.NODE_ENV !== "production";
var plugins = [];

plugins.push(
  new MiniCssExtractPlugin({
    filename: devMode ? "styles/[name].css" : "styles/[name].css",
    chunkFilename: devMode ? "styles/[name].css" : "styles/[name].css",
    ignoreOrder: false, // Enable to remove warnings about conflicting order
  }),
  new CopyPlugin({
    patterns: [
      { from: "src/scripts", to: "src/admin" }
    ],
  }),
  new PurgeCSSPlugin({
    paths: glob.sync(`${PATHS.src}/**/*`, { nodir: true }),
    safelist: ['open', 'open-mobile'],
    extractors: [
      {
        extractor: customExtractor,
        extensions: ["html", "js"],
      },
    ],
    rejected: true
  })
);

if (devMode) {
  console.log("Development mode!");
}

module.exports = {
  stats: "normal",
  entry: [__dirname + "/src/scripts.js"],
  output: {
    path: __dirname + "/dist",
    filename: "scripts/[name].js",
    sourceMapFilename: "scripts/[name].min.map",
  },
  watchOptions: {
    poll: 1000, // Check for changes every second
  },
  devtool: process.env.NODE_ENV === "dev" ? "eval" : false,
  module: {
    rules: [
      {
        test: require.resolve("jquery"),
        loader: "expose-loader",
        options: {
          exposes: ["$", "jQuery"],
        },
      },
      {
        test: /\.s?[ac]ss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              url: true,
              sourceMap: false,
            },
          },
          {
            loader: "sass-loader",
            options: {
              sourceMap: false,
            },
          },
        ],
      },
      {
        test: /\.(png|jpe?g|gif|svg)$/,
        use: [
          {
            loader: "file-loader",
            options: {
              name: "[name].[ext]",
              publicPath: "../images",
              outputPath: "images",
            },
          },
        ],
      },
      {
        test: /\.(woff|woff2|ttf|otf|eot)$/,
        use: [
          {
            loader: "file-loader",
            options: {
              name: "[name].[ext]",
              publicPath: "../fonts",
              outputPath: "fonts",
            },
          },
        ],
      },
    ],
  },
  optimization: {
    runtimeChunk: {
      name: "manifest",
    },
    splitChunks: {
      cacheGroups: {
        styles: {
          name: "styles",
          test: /\.css$/,
          chunks: "all",
          enforce: true,
        },
      },
    },
  },
  plugins: plugins,
};

package.jason包.jason

"devDependencies": {
    "@babel/core": "^7.12.3",
    "autoprefixer-loader": "^3.1.0",
    "babel-core": "^6.26.3",
    "babel-loader": "^8.1.0",
    "babel-preset-es2015": "^6.3.13",
    "babel-preset-stage-0": "^6.3.13",
    "copy-webpack-plugin": "^6.3.0",
    "css-loader": "^5.0.1",
    "expose-loader": "^1.0.1",
    "file-loader": "^6.2.0",
    "html-webpack-plugin": "^4.5.0",
    "http-server": "^0.12.3",
    "imagemin": "^7.0.1",
    "img-loader": "^3.0.2",
    "jquery": "^3.5.1",
    "lodash": "^4.17.20",
    "mini-css-extract-plugin": "^1.2.1",
    "node-sass": "^5.0.0",
    "postcss-loader": "^4.0.4",
    "purgecss-webpack-plugin": "^3.0.0",
    "sass-loader": "^10.0.5",
    "select2": "^4.0.13",
    "source-map-loader": "^1.1.2",
    "style-loader": "^2.0.0",
    "svgo": "^1.3.2",
    "svgo-loader": "^2.2.1",
    "uglify-loader": "^3.0.0",
    "url-loader": "^4.1.1",
    "webpack": "^5.4.0",
    "webpack-cli": "^4.2.0",
    "webpack-dev-server": "^3.11.0"
}

I love finding the exact same issue I have on StackOverflow only to see it has absolutely no answers...我喜欢找到我在 StackOverflow 上遇到的完全相同的问题,却发现它完全没有答案......

In any case, after looking at the code I believe there may be a bug in purgecss-webpack-plugin , or maybe this feature is just not implemented correctly, because I can't seem to tell how this information gets attached to the compilation stats at all.在任何情况下,在查看代码后,我相信purgecss-webpack-plugin可能存在错误,或者该功能可能没有正确实现,因为我似乎无法说出这些信息如何附加到编译统计信息中根本。

It does however get attached to the instance of the PurgeCSSPlugin as purgedStats .然而,它确实作为purgedStats附加到 PurgeCSSPlugin 的实例。

With that in mind, I wrote a workaround plugin that outputs the purged css to a separate file and can be used as a drop-in replacement until the issue, if there is one, is fixed.考虑到这一点,我编写了一个解决方法插件,将清​​除的 css 输出到一个单独的文件,并且可以用作替代品,直到问题得到解决(如果有的话)。

const fs = require('fs');
const PurgeCSSPlugin = require("purgecss-webpack-plugin");

class PurgeCSSWriterPlugin {
  constructor({output = './purged-css.json', ...purgeCSSPluginOpts}) {
    this.output = output;
    this.rejected = purgeCSSPluginOpts.rejected;
    this.purgeCSSPlugin = new PurgeCSSPlugin(purgeCSSPluginOpts);
  }

  apply(compiler, ...args) {
    this.purgeCSSPlugin.apply(compiler, ...args);
    if(!this.rejected) {
      return;
    }
    compiler.hooks.done.tapPromise('PurgeCSSWriterPlugin', () => {
      // Write rejected css to output path
      return new Promise((res, rej) => {
        fs.writeFile(
          this.output,
          JSON.stringify(this.purgeCSSPlugin.purgedStats),
          (err, data) => (err ? rej(err) : res(data)),
        );
      });
    });
  }
}

Then replace PurgeCSSPlugin in your webpack config with this:然后将你的 webpack 配置中的 PurgeCSSPlugin 替换为:

  new PurgeCSSWriterPlugin({
    paths: glob.sync(`${PATHS.src}/**/*`, { nodir: true }),
    safelist: ['open', 'open-mobile'],
    extractors: [
      {
        extractor: customExtractor,
        extensions: ["html", "js"],
      },
    ],
    rejected: true,
    output: path.resolve(__dirname, 'wherever/you/want.json'),
  })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM