我正在尝试为我的反应项目创建一个脚手架,并在此过程中学习webpack。我一直在尝试将我的css模块化在他们自己的组件文件夹中,并将它们解压缩到build文件夹中的一个styles.css文件中。
问题在于,在每个模块化.css文件中,我都有媒体查询,有时它们在相同宽度断点的特定规则方面重叠。这会在我提取的styles.css文件中产生一堆重复的@media all和(min-width:400px)-esque语句。
所以为了解决这个问题,我发现这个csso插件似乎在他们的在线工具中起到了作用。它将所有重复的@media语句合并(通过重组)到一个并将不同的规则放在那里。问题是,在我的项目中,只有当重复的@media语句来自同一个文件时才会这样做(这不应该发生)。如果它们来自不同的文件(这是我试图解决的问题),它们就不会合并。
现在,我不确定这些插件是如何在后台运行的,但我想csso-webpack-plugin正在解析所有文件,然后将结果添加到bundle中,然后提取到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}}
答案 0 :(得分:1)
CssoWebpackPlugin 将处理已提取的捆绑包,不需要 csso-loader
。
对于重组,您应该将plugins
部分中的 CssoWebpackPlugin 应用到您的网络包配置中,例如 - 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}}
答案 1 :(得分:0)
由于我的问题的解决方案不是所有情况下的安全解决方案,但无论如何这是我需要的东西,我尝试寻找不同的解决方案,并首先使用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"}