【问题标题】:PurgeCss Webpack Plugin doesn't output unused CSS with purged: truePurgeCss Webpack 插件不输出未使用的 CSS 清除:true
【发布时间】:2021-02-19 03:37:34
【问题描述】:

我想看看使用 PurgeCss Webpack 插件清除了哪些 CSS,但由于某种原因,purged: true 没有将其输出到compilation-stats.json,如docs 中所述。

这是我的构建命令:

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

关于如何查看清除的 CSS 的任何想法?

这是我的 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

"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"
}

【问题讨论】:

    标签: javascript css webpack sass frontend


    【解决方案1】:

    我喜欢在 StackOverflow 上找到完全相同的问题,却发现它完全没有答案...

    无论如何,在查看代码后,我认为purgecss-webpack-plugin 中可能存在错误,或者此功能可能没有正确实现,因为我似乎无法说出这些信息是如何附加到编译中的统计数据。

    但它确实以purgedStats 的形式附加到 PurgeCSSPlugin 的实例。

    考虑到这一点,我编写了一个解决方法插件,它将清除的 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)),
            );
          });
        });
      }
    }
    

    然后将 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'),
      })
    

    【讨论】:

      猜你喜欢
      • 2020-04-13
      • 2017-07-10
      • 2019-01-07
      • 2018-07-01
      • 1970-01-01
      • 2016-01-31
      • 2016-03-26
      • 2021-06-11
      • 2019-03-05
      相关资源
      最近更新 更多