mini-css-extract-plugin

mini-css-extract-pluginwebpack4中代替extract-text-webpack-plugin,此插件是将 CSS 样式提取到单独的文件中。 它为每个包含 CSS 的 JS 文件创建一个 CSS 文件。即通过 JS 文件中import进来的样式文件。它支持CSSSourceMaps的按需加载。

是建立在新的webpack v4功能(模块类型)之上,并且需要在webpack 4版本才能工作。

相比extract-text-webpack-plugin

  • 异步加载
  • 没有重复的编译(性能)
  • 更容易使用
  • 特定于CSS

基本配置如下(webpack.config.js):

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      filename:  '[name].css',
      chunkFilename: '[id].css'
    }),
  ],
  module: {
    rules: [
      {
          test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              // 公共路径
              // 默认情况下,使用的是webpackOptions.output中publicPath
              publicPath: '../',
              //开发环境配置热更新
              hmr: process.env.NODE_ENV === 'development',
            },
          },
          'css-loader',
      }
    ]
  }
}

高级配置如下(既可以在开发中使用 HMR,也可以在生成版本的文件中提取样式):

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

module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      filename: devMode ? '[name].js' : '[name].[hash].css',
      chunkFilename: devMode ? '[id].css' : '[name].[hash].css',
    });
  ],
  module: {
    rules: [
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              hmr: process.env.NODE_ENV === ‘development’
            }
          },
          'css-loader',
          'postcss-loader',
          'sass-loader'
        ]
      }
    ]
  }
}

生产环境优化压缩(production)
缩小输出,要使用像optimize-css-assets-webpack-plugin这样的插件。 设置optimization.minimizer会覆盖 webpack 提供的默认值,因此确保要指定JS minimalizer

//webpack.config.js
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({
      include: /\/src/,
      exclude: /\/excludes/,
      cache: true,
      sourceMap: true,
      parallel: true,//多进程并行运行
      comments: false, //禁止构建注释
    }), 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

//webpack.config.js
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'],
      },
    ],
  },
};

还可以根据 webpack 的 entry name 来提取CSS,这对你动态引入路由,却想依据 entry 保存打包的 CSS 的情况十分有用。这也解决了 ExtractTextPlugin 中 CSS 重复的问题。

//webpack.config.js
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'],
      },
    ],
  },
};

特别注意

For long term caching use filename: "[contenthash].css". Optionally add [name].
需要使用长缓存的,命名要使用 contenthash,如果直接使用 hash 的话,在 js 有改动,样式没有变动的情况下,css 会被重新打包生成新的 hash 值,这显然不是我们想要的,所以这里生产环境用 contenthash,确保 css 文件在没有改动的情况下,使用缓存文件。
参考:
https://www.npmjs.com/package/mini-css-extract-plugin

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容