【问题标题】:Unable To Strip Unused Bootstrap CSS Using Webpack Config无法使用 Webpack 配置剥离未使用的引导 CSS
【发布时间】:2020-04-16 15:58:23
【问题描述】:

使用下面的配置,我可以创建一个 HTML 文件,其中包含正确的所有代码,但其中包含许多未使用的引导类。

请注意,我通过将 SCSS 文件从 node_modules 导入代码中的 main.scss 文件来自定义 Bootstrap。

我哪里错了?

const path = require('path');
const {
  CleanWebpackPlugin
} = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const {
  scss
} = require('svelte-preprocess');
const Dotenv = require('dotenv-webpack');
const PurgecssPlugin = require('purgecss-webpack-plugin');
const glob = require('glob');

const prod = process.env.NODE_ENV === 'production';

module.exports = {
  module: {
    rules: [{
        test: /\.svelte$/,
        exclude: /node_modules/,
        loader: 'svelte-loader',
        options: {
          emitCss: true,
          hotReload: false,
          preprocess: require('svelte-preprocess')([scss()]),
        },
      },
      {
        test: /\.(sa|sc|c)ss$/,
        exclude: /node_modules/,
        use: [{
            loader: prod ? MiniCssExtractPlugin.loader : 'style-loader', // inject CSS to page
          },
          {
            loader: 'css-loader', // translates CSS into CommonJS modules
          },
          {
            loader: 'postcss-loader', // Run post css actions
            options: {
              plugins: function() {
                // post css plugins, can be exported to postcss.config.js
                return [require('precss'), require('autoprefixer')];
              },
            },
          },
          {
            loader: 'sass-loader', // compiles Sass to CSS
          },
        ],
      },
    ],
  },
  resolve: {
    alias: {
      svelte: path.resolve('../../node_modules', 'svelte'),
    },
    extensions: ['.mjs', '.js', '.svelte'],
    mainFields: ['svelte', 'browser', 'module', 'main'],
  },
  optimization: {
    minimizer: [
      new OptimizeCssAssetsPlugin({
        cssProcessorOptions: {
          map: {
            inline: false
          }
        },
      }),
      new TerserPlugin(),
    ],
  },
  plugins: [
    new Dotenv(),
    new MiniCssExtractPlugin({
      filename: '[name].css',
    }),
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      minify: prod ?
        {
          collapseWhitespace: true,
          removeComments: true,
          removeRedundantAttributes: true,
          removeScriptTypeAttributes: true,
          removeStyleLinkTypeAttributes: true,
          useShortDoctype: true,
        } :
        false,
      template: 'index.html',
      inlineSource: '.(js|css)$', // embed all javascript and css inline
    }),
    new HtmlWebpackInlineSourcePlugin(HtmlWebpackPlugin),
    new PurgecssPlugin({
      paths: glob.sync(`${path.join(__dirname, 'src')}/**/*`, {
        nodir: true
      }),
    }),
  ],
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

这是我在项目中使用的唯一且唯一的 SCSS 文件;它在 index.js 中导入,并作为整个项目的唯一样式源:

//colors
$primary: #123099;

//body
$body-bg: #3123b7;

// Required
@import '~bootstrap/scss/functions';
@import '~bootstrap/scss/variables';
@import '~bootstrap/scss/mixins/border-radius';
@import '~bootstrap/scss/mixins/buttons';
@import '~bootstrap/scss/mixins/gradients';
@import '~bootstrap/scss/mixins/list-group';
@import '~bootstrap/scss/mixins/background-variant';
@import '~bootstrap/scss/mixins/forms';
@import '~bootstrap/scss/mixins/grid';
@import '~bootstrap/scss/mixins/grid-framework';
@import '~bootstrap/scss/mixins/box-shadow';
@import '~bootstrap/scss/mixins/transition';
@import '~bootstrap/scss/mixins/hover';
@import '~bootstrap/scss/mixins/size';
@import '~bootstrap/scss/mixins/breakpoints';
@import '~bootstrap/scss/mixins/text-truncate';
@import '~bootstrap/scss/mixins/deprecate';
@import '~bootstrap/scss/mixins/text-hide';
@import '~bootstrap/scss/mixins/text-emphasis';
@import '~bootstrap/scss/vendor/rfs';
@import '~bootstrap/scss/reboot';

// Optional
@import '~bootstrap/scss/utilities/spacing';
@import '~bootstrap/scss/utilities/sizing';
@import '~bootstrap/scss/utilities/flex';
@import '~bootstrap/scss/utilities/borders';
@import '~bootstrap/scss/utilities/text';
@import '~bootstrap/scss/utilities/background';
@import '~bootstrap/scss/utilities/shadows';
@import '~bootstrap/scss/utilities/display';
@import '~bootstrap/scss/utilities/position';
@import '~bootstrap/scss/grid';
@import '~bootstrap/scss/card';
@import '~bootstrap/scss/forms';
@import '~bootstrap/scss/buttons';
@import '~bootstrap/scss/list-group';
@import '~bootstrap/scss/custom-forms';
@import '~bootstrap/scss/spinners';

【问题讨论】:

    标签: webpack bootstrap-4 webpack-4 svelte css-purge


    【解决方案1】:

    您必须使用 purgecss-whitelister Purgecss 插件将 Bootstrap CSS 文件列入白名单。

    使用npm i -D purgecss-whitelister 安装purgecss-whitelister,然后在您通常导入的引导CSS 文件上使用whitelister bootstrap/dist/css/bootstrap.css

    const whitelister = require('purgecss-whitelister');
    ...
    
    module.exports = {
      ...
      plugins: [
        ...
        new PurgecssPlugin({
          keyframes: false,
          paths: glob.sync(`${path.join(__dirname, 'src')}/**/*`, {
            nodir: true
          }),
          whitelist: whitelister('bootstrap/dist/css/bootstrap.css')
        }),
      ],
    }
    

    然后构建,您将拥有一个 bundle.css,其中仅包含您实际使用的 Bootstrap CSS 类。例如,仅使用containerbtnbtn-primary Bootstrap 类,我的bundle.css 大小在使用purgecss-webpack-pluginpurgecss-whitelister 之前下降到4.84 KiB 而不是193 KiB

    【讨论】:

    • 谢谢,但我实际上并没有那样使用 Bootstrap CSS 文件; CSS 是从自定义的 Bootstrap SCSS 创建的。
    • 您在问题中没有提到任何地方(也没有标题)这是关于 自定义引导 SCSS。试图帮助您的人没有这个线索,您应该相应地更新有关此信息的问题。即便如此,您是否尝试使用 purgecss-whitelister 将该文件列入白名单?您尝试从哪个位置导入该文件?是来自node_modules 内部还是您的应用程序src 路径?
    • 对此我感到非常抱歉。事实上,我认为它是隐式理解的,因为我包含了 SCSS 配置代码。我的错,我会相应地更新问题,并尝试将其列入白名单并报告。谢谢。
    • 规则test: /\.(sa|sc|c)ss$/包括CSS作为SASS和SCSS与每个特定的加载器;你有一个关于你的问题的自定义引导文件一点也不明显。还请更新 scss 引导文件路径以及您如何自定义它(例如更改类名前缀)。
    • 完成。我希望现在很清楚。从您的回答中我不明白的是,在这种情况下,哪个文件要准确列入白名单;我的main.scss 文件?
    猜你喜欢
    • 2016-03-25
    • 2016-12-11
    • 2017-04-12
    • 2022-07-15
    • 2012-12-26
    • 2017-03-26
    • 1970-01-01
    • 1970-01-01
    • 2019-08-21
    相关资源
    最近更新 更多