2020-12-02 CSS 文件的代码分割(4.92)

2020-12-03  本文已影响0人  夏天的风2020

之前总结的代码分割都是针对JS代码的,
如果要对CSS代码进行代码分割,要怎么办呢?
借助MiniCssExtractPlugin插件

image image

然后运行代码会发现,样式生效了。
由此可以得知,`webpack`在打包的时候,它会把CSS文件直接打包到JS文件里。
这也就是我们常听说的`CSS IN JS`这样一个概念

但是这并不是我们希望的,
我们希望的是,在打包生成代码的时候,
如果我们引入的是CSS文件,那么把CSS文件单独打包到`dist`目录下,生成一个CSS文件,
而不是打包到`js文件里`,
这个时候,我们就要借助`MiniCssExtractPlugin`插件了;
具体的使用步骤如下:

  npm install --save-dev mini-css-extract-plugin

此版本官方文档显示这个插件有个缺陷,
TODO:
HMR support
也就是现在这个模块是不支持模块热更新的,

这就意味着在开发环境使用这个插件,
改变了css的样式,这个样式不会及时的更新到我们的项目中,
我们需要手动刷新页面,
开发效率低


所以我们一般在线上环境的打包过程中使用,

  
//dist目录下 webpack.prod.js配置如下

const MiniCssExtractPlugin = require('mini-css-extract-plugin'); //引入这个插件
const merge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');

const prodConfig = {
    mode: "production",
    devtool:'cheap-module-source-map',
    plugins: [           //使用这个插件,还需要对loader进行一些配置
      new MiniCssExtractPlugin({
        filename: '[name].css',
        chunkFilename: '[id].css',
      }),
}

module.exports = merge(commonConfig,prodConfig)

之前我们最终会通过style-loader把css样式挂载到页面上,
module: {
   rules: [
        {
            test: /\.scss$/,
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            importLoaders: 2
                        }
                    },
                    'sass-loader',
                    'postcss-loader'
                ]
        },{
            test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'postcss-loader'
                ]
        }]
    },

module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: (resourcePath, context) => {
       
              },
            },
          },
          'css-loader',
        ],
      },
    ],
  },

src目录下,webpack.common.js文件中,
rules中对应的css文件,scss文件这部分代码剪切下


const path = require('path')   
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CleanWebpackPlugin  = require('clean-webpack-plugin')

module.exports = {
    entry: {
        main: "./src/index.js"
    },  
    module: {
        rules: [
        {
            test: /\.js$/, 
            exclude: /node_modules/,  
            loader: 'babel-loader'
        },
        {
            test: /\.(jpg|png|gif)$/,
            use: {
                loader: 'url-loader',
                options: {
                    name: '[name]_[hash].[ext]',
                    outputPath: 'images/',
                    limit: 10240
                }
            }
        },
        {
            test: /\.(eot|ttf|svg|woff)$/,
            use: {
                loader: 'file-loader'
            }
        },
//剪切到,分别放入webpack.dev.js和webpack.config.js中
      //  {
     //       test: /\.scss$/,
     //           use: [
      //              'style-loader',
       //             {
      //                  loader: 'css-loader',
     //                   options: {
     //                       importLoaders: 2
     //                   }
    / /               },
    //                'sass-loader',
    //                'postcss-loader'
    //            ]
   //     },{
  //          test: /\.css$/,
   //             use: [
   //                 'style-loader',
    //                'css-loader',
     //               'postcss-loader'
   //             ]
  //      }]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template:'./src/index.html'
        }),
        new CleanWebpackPlugin()
    ],
    output: {
        path:path.resolve(__dirname,'dist'),   
        filename: '[name].js'   
    }
}

webpack.dev.js中关于css文件,scss文件如下配置:


//webpack.dev.js
const webpack = require('webpack');
const merge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');

const devConfig = {
    mode: "development",
    devtool:'cheap-module-eval-source-map',
    devServer: {
        contentBase: './dist',
        open: true,
        port: 8080,
        hot: true,  //让webpack开启  Hot Module Replace 的功能
    },
module: {
//在开发环境中还是使用style-loader
      rules:[
        {
          test: /\.scss$/,
          use:[
            'style-loader',
            {
              loader: 'css-loader',
              options: {
                            importLoaders: 2
                        }
            },            
            'sass-loader',
            'postcss-loader'
          ]
        },
        {
          test: /\.css$/,
          use: [
              'style-loader',
              'css-loader',
              'postcss-loader'
          ]
        }
      ]
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin()
    ],
    optimization: {
        usedExports: true  
    }
}

module.exports = merge(commonConfig,devConfig)

webpack.prod.js还剩下如下配置

//webpack.prod.js
const merge = require('webpack-merge');
const merge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');

const prodConfig = {
    mode: "production",
    devtool:'cheap-module-source-map',
    module: {
  //在线上环境中
      rules:[
        {
          test: /\.scss$/,
          use:[
           MiniCssExtractPlugin.loader, //使用这个插件提供给我们的loader替换掉style-loader
            {
              loader: 'css-loader',
              options: {
                            importLoaders: 2
                        }
            },            
            'sass-loader',
            'postcss-loader'
          ]
        },
        {
          test: /\.css$/,
          use: [
             MiniCssExtractPlugin.loader,
              'css-loader',
              'postcss-loader'
          ]
        }
      ]
    },
plugins: [
        new MiniCssExtractPlugin({})
    ],
}

//最终导出的是 prodConfig 和 commonConfig 结合的配置
module.exports = merge(commonConfig,prodConfig)
image image
还可以对MiniCssExtractPlugin插件进行更详细的配置
image
虽然我们实现了打包单独生成CSS文件,

但是我们可以看到,生成的文件代码并不是压缩状态的。
如果我们希望单独生成CSS文件是压缩状态的,可以用`optimize-css-assets-webpack-plugin这个插件

npm install --save-dev optimize-css-assets-webpack-plugin

//dist目录下的webpack.prod.js

const merge = require('webpack-merge');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); //引入这个插件
const merge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');

const prodConfig = {
    mode: "production",
    devtool:'cheap-module-source-map',
    module: {
  //在线上环境中
      rules:[
        {
          test: /\.scss$/,
          use:[
           MiniCssExtractPlugin.loader, //使用这个插件提供给我们的loader替换掉style-loader
            {
              loader: 'css-loader',
              options: {
                            importLoaders: 2
                        }
            },            
            'sass-loader',
            'postcss-loader'
          ]
        },
        {
          test: /\.css$/,
          use: [
             MiniCssExtractPlugin.loader,
              'css-loader',
              'postcss-loader'
          ]
        }
      ]
    },
optimization: {
    minimizer: [new OptimizeCSSAssetsPlugin({})], //创建的时候,参数为空,空对象
  },
plugins: [
        new MiniCssExtractPlugin({})
    ],
}

//最终导出的是 prodConfig 和 commonConfig 结合的配置
module.exports = merge(commonConfig,prodConfig)

然后我们再运行打包npm run build,
发现它不单单帮我们把样式做了合并,
还把代码做了压缩显示在了一行

image
更高级的用法
如果我们想根据入口文件的不同,把CSS文件打包到不同的CSS文件里边去,该怎么办?
image

链接:https://www.jianshu.com/p/440b97da2262

上一篇下一篇

猜你喜欢

热点阅读