webpack4 mini-css-extract-plugin

在使用webpack的extract-text-webpack-plugin插件提取單獨打包css文件時,報錯,說是這個插件要依賴webpack3的版本。
webpack4得使用mini-css-extract-plugin這個插件來單獨打包css。下面是使用方法:css


將CSS提取爲獨立的文件的插件,對每一個包含css的js文件都會建立一個CSS文件,支持按需加載css和sourceMapwebpack

只能用在webpack4中,對比另外一個插件 extract-text-webpack-plugin有點:git

  • 異步加載
  • 不重複編譯,性能更好
  • 更容易使用
  • 只針對CSS

目前缺失功能,HMR。github

安裝:web

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

使用:npm

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      // 相似 webpackOptions.output裏面的配置 能夠忽略
      filename: '[name].css',
      chunkFilename: '[id].css',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              // 這裏能夠指定一個 publicPath
              // 默認使用 webpackOptions.output中的publicPath
              publicPath: '../'
            },
          },
          'css-loader',
        ],
      }
    ]
  }
}

高級配置示例:sass

這個插件應該只用在 production 配置中,而且在loaders鏈中不使用 style-loader, 特別是在開發中使用HMR,由於這個插件暫時不支持HMR異步

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const devMode = process.env.NODE_ENV !== 'production';

module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      filename: devMode ? '[name].css' : '[name].[hash].css',
      chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
    })
  ],
  module: {
    rules: [
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
          'sass-loader',
        ],
      }
    ]
  }
}

production 階段進行壓縮

webpack5可能會內置CSS 壓縮器,webpack4須要本身使用壓縮器,能夠使用 optimize-css-assets-webpack-plugin 插件。 設置 optimization.minimizer 覆蓋webpack默認提供的,確保也指定一個JS壓縮器post

const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = {
  optimization: {
    minimizer: [
      new UglifyJsPlugin({
        cache: true,
        parallel: true,
        sourcMap: true
      }),
      new OptimizeCSSAssetsPlugin({}),
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name].css",
      chunkFilename: "[id].css"
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader'
        ]
      }
    ]
  }
}

將全部的CSS提取到一個文件中性能

和 extract-text-webpack-plugin 相似,能夠使用 optimization.splitChunks.cacheGroups 將css提取到一個CSS中

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
  optimization: {
    splitChunks: {
      cacheGroups: {
        styles: {
          name: 'styles',
          test: /\.css$/,
          chunks: 'all',
          enforce: true,
        },
      },
    },
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader'
        ]
      }
    ]
  }
}

根據entry提取CSS

能夠根據webpack 的entry name來提取CSS,這對你動態引入路由,卻想依據entry保存打包的CSS的狀況十分有用。這也解決了ExtractTextPlugin中CSS重複的問題

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

function recursiveIssuer(m) {
  if (m.issuer) {
    return recursiveIssuer(m.issuer);
  } else if (m.name) {
    return m.name;
  } else {
    return false;
  }
}

module.exports = {
  entry: {
    foo: path.resolve(__dirname, 'src/foo'),
    bar: path.resolve(__dirname, 'src/bar')
  },
  optimization: {
    splitChunks: {
      cacheGroups: {
        fooStyles: {
          name: 'foo',
          test: (m,c,entry = 'foo') => m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry,
          chunks: 'all',
          enforce: true
        },
        barStyles: {
          name: 'bar',
          test: (m,c,entry = 'bar') => m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry,
          chunks: 'all',
          enforce: true
        }
      }
    }
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name].css",
    })
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          "css-loader"
        ]
      }
    ]
  }
}
相關文章
相關標籤/搜索