【问题标题】:CSSO + ExtractTextPlugin in webpack not restructuring extracted pagewebpack中的CSSO + ExtractTextPlugin不重构提取页面
【发布时间】:2018-02-02 20:23:04
【问题描述】:

我正在尝试为我的 react 项目创建一个脚手架,并在此过程中学习 webpack。我一直在尝试将我的 css 模块化在他们自己的组件文件夹中,并将它们提取到构建文件夹中的单个 styles.css 文件中。

问题在于,在每个模块化的 .css 文件中,我都有媒体查询,有时它们在相同宽度断点的特定规则方面重叠。这导致在我提取的 styles.css 文件中出现一堆重复的 @media all 和 (min-width: 400px)-esque 语句。

为了补救,我发现了这个似乎在他们的在线工具中起作用的 csso 插件。它将所有这些重复的@media 语句合并(通过重组)为一个,并将不同的规则放入其中。问题是在我的项目中,只有当重复的 @media 语句来自同一个文件时(这不应该发生),它才会这样做。如果它们来自不同的文件(这是我要解决的问题),它们不会被合并。

现在,我不确定这些插件如何在后台工作,但我想 csso-webpack-plugin 正在解析所有文件,然后将结果添加到包中,然后提取到 styles.css,并且不直接解析styles.css。谁能想到这个问题的解决方案?

我的生产配置如下:

const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require('webpack');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const CssoWebpackPlugin = require('csso-webpack-plugin').default;

module.exports = {
  entry: {
    app: './src/index.js'
  },
  module:{
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      },
      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [
            'css-loader',
            'csso-loader'
          ]
        })
      }
    ]
  },
  plugins:[
    new CleanWebpackPlugin(['build']),
    new HtmlWebPackPlugin(),
    new ExtractTextPlugin('styles.css'),
    new webpack.optimize.UglifyJsPlugin({
      beautify: false,
      mangle: {
        screw_ie8: true,
        keep_fnames: true
      },
      compress: {
        screw_ie8: true
      },
      comments: false
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks(module){
        var context = module.context;
        return context && (context.indexOf('node_modules') > 0);
      }
    })
  ],
  output: {
    filename: '[name].bundle.min.js',
    path: path.resolve(__dirname, 'build')
  }
} 

我的 index.css 看起来像这样:

@media all and (max-width: 100px){
  .lorelei{
    font-size: 50px;
  }
}

我的 App.css:

@media all and (max-width: 100px){
  .loboto{
    font-size: 30px;
  }
}


@media all and (max-width: 100px){
  .jonas{
    font-size: 30px;
  }
}

以及生成的styles.css

@media all and (max-width:100px){.lorelei{font-size:50px}}@media all and (max-width:100px){.jonas,.loboto{font-size:30px}}

【问题讨论】:

    标签: webpack webpack-2 extract-text-plugin csso


    【解决方案1】:

    由于我的问题的解决方案并不是对所有情况都是安全的解决方案,但无论如何我都需要它,我尝试寻找不同的解决方案,并通过首先使用 group-media-queries-plugin 在首先提取 styles.css 文件,然后使用 csso 缩小结果。我发现它是一个 CLI 插件,所以我最终通过 npm 脚本同时使用了它和 CSSO CLI。

    我的 npm 脚本最终变得相当冗长,但它完成了工作:

      "scripts": { "build:prod": "webpack --env=prod --progress --profile --colors && group-css-media-queries ./build/styles.css ./build/styles.css && csso ./build/styles.css ./build/styles.min.css"}
    

    【讨论】:

      【解决方案2】:

      CssoWebpackPlugin 将处理已提取的包,并且不需要csso-loader。

      对于重组,您应该将 plugins 部分中的 CssoWebpackPlugin 应用到您的 webpack 配置中,例如 — new CssoWebpackPlugin()。

      部分规则:

      {
          test: /\.css$/,
          use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: 'css-loader'
      }
      

      部分插件:

      plugins: [
          /* ... */
          new ExtractTextPlugin('styles.css'),
          new CssoWebpackPlugin(), // <==== it's very important!
          /* ... */
      ]
      

      您的完整配置应如下所示:

      const path = require('path');
      const CleanWebpackPlugin = require('clean-webpack-plugin');
      const webpack = require('webpack');
      const HtmlWebPackPlugin = require('html-webpack-plugin');
      const ExtractTextPlugin = require("extract-text-webpack-plugin");
      const CssoWebpackPlugin = require('csso-webpack-plugin').default;
      
      module.exports = {
        entry: {
          app: './src/index.js'
        },
        module:{
          rules: [
            {
              test: /\.js$/,
              exclude: /node_modules/,
              loader: 'babel-loader'
            },
            {
              test: /\.css$/,
              use: ExtractTextPlugin.extract({
                fallback: 'style-loader',
                use: 'css-loader'
              })
            }
          ]
        },
        plugins:[
          new CleanWebpackPlugin(['build']),
          new HtmlWebPackPlugin(),
          new ExtractTextPlugin('styles.css'),
          new CssoWebpackPlugin(),
          new webpack.optimize.UglifyJsPlugin({
            beautify: false,
            mangle: {
              screw_ie8: true,
              keep_fnames: true
            },
            compress: {
              screw_ie8: true
            },
            comments: false
          }),
          new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor',
            minChunks(module){
              var context = module.context;
              return context && (context.indexOf('node_modules') > 0);
            }
          })
        ],
        output: {
          filename: '[name].bundle.min.js',
          path: path.resolve(__dirname, 'build')
        }
      }
      

      修改后的结果会合并好:

      @media all and (max-width:100px){.lorelei{font-size:50px}.jonas,.loboto{font-size:30px}}
      

      【讨论】:

      • 我为你添加了这个案例的例子:github.com/zoobestik/stackoverflow-45870309
      • 这就是我原来的样子。我切换到 csso-loader 看看是否会有任何不同。以防万一我按照您的代码再次尝试了 CssoWebackPlugin,但它与我之前的相同,它仍然会产生重复的结果。只是为了检查一下,我在我的 styles.css(未缩小)上运行了 csso 的 CLI 版本,缩小导致了相同的重复内容!当我手动将第一个媒体查询语句移动到其他 2 个媒体查询上方并再次运行 cli 工具时,它正确地进行了重复数据删除。这是一个特点吗?感觉不对。
      • 如果您有 font-size 的其他 css 规则,这是可能的。是否存在重组将不安全。 :( 很遗憾,但您应该为 csso 提供更多信息以进行更好的优化。它被命名为scopes,最简单的方法是使用localIdentName 或getLocalIdent 和this solution。它将是在CssoWebackPlugin 中提供作为未来预设。但是没有scopes csso + 重组仍然是最好的css minifer。
      • 感谢您的回复,zoobestik 以及您为解决我的问题所付出的努力。最后,我发现从不同的角度解决问题会更容易。我最终解决了这个问题,并结合使用 CSSO 和不同的插件来获得我想要的结果。再次感谢您的回复!
      猜你喜欢
      • 2017-06-09
      • 2018-07-11
      • 2017-07-24
      • 2017-05-19
      • 2017-07-15
      • 2015-06-26
      • 2018-05-25
      • 2017-08-22
      • 1970-01-01
      相关资源
      最近更新 更多