Webpack中文:
MiniCssExtractPlugin | webpack 中文文档

不打印style页面不会有样式,因为我们在package.json代码中配置过Tree Shaking(不使用的代码不会引入,而css文件没有导出,所以页面不会有效果):

  1. import style from "./index.css";
  2. console.log(style)
  1. body{
  2. background-color: gray;
  3. }

更改排除package.json文件:

  1. {
  2. "scripts": {
  3. "dev": "webpack serve --open --config ./build/webpack.dev.js",
  4. "build:stage": "webpack --config ./build/webpack.dev.js",
  5. "build:test": "webpack --json > stats.json",
  6. "build": "webpack --config ./build/webpack.prod.js"
  7. },
  8. // 排除 .css 文件
  9. "sidEffects": ["*.css"],
  10. }

image.png
image.png
以上代码js文件加载了css文件,这个时候运行npm run build后可以看到页面确实被改变了背景色,但是dist文件夹下面却没有看到css的文件,这是因为webpackcss文件都打包到了js文件中。

样式抽离

项目开发中,我们希望css文件能单独存在,我们可以使用Webpack提供的的插件MiniCssExtractPlugin

安装:

  1. $ npm install --save-dev mini-css-extract-plugin

删除对css文件和scss文件的loader

  1. const path = require("path");
  2. const HtmlWebpackPlugin = require("html-webpack-plugin");
  3. const { CleanWebpackPlugin } = require('clean-webpack-plugin');
  4. module.exports = {
  5. entry: {
  6. main: "./src/index.js",
  7. },
  8. output: {
  9. filename: "[name].js",
  10. path: path.resolve(__dirname, "../dist"),
  11. },
  12. module: {
  13. rules: [
  14. /*{
  15. test: /\.scss$/,
  16. use: ["style-loader", {
  17. loader: "css-loader",
  18. options: {
  19. importLoaders: 2,
  20. modules: true
  21. }
  22. }, "sass-loader", "postcss-loader"]
  23. },
  24. {
  25. test: /\.css$/,
  26. use: ["style-loader", "css-loader", "postcss-loader"]
  27. }, */
  28. {
  29. test: /\.jpg|.jpeg|.png$/,
  30. use: {
  31. loader: "url-loader",
  32. options: {
  33. limit: 54000,
  34. name: "[name].[ext]",
  35. outputPath: "/images",
  36. }
  37. }
  38. }, {
  39. test: /\.m?js$/,
  40. exclude: /node_modules/, // 排除node_modules下的代码
  41. use: {
  42. loader: "babel-loader"
  43. }
  44. }]
  45. },
  46. optimization: {
  47. // TreeShaking 的配置
  48. usedExports: true,
  49. // SplittingCode 的配置
  50. splitChunks: {
  51. chunks: 'all', // 分割引入代码库的方式,默认为 async 异步,可选 all:同步和异步
  52. },
  53. },
  54. plugins: [
  55. // 自动引入打包好的js文件
  56. new HtmlWebpackPlugin({
  57. template: "./src/index.html"
  58. }),
  59. // 清除dist文件夹
  60. new CleanWebpackPlugin({
  61. cleanOnceBeforeBuildPatterns: [
  62. path.resolve(__dirname, '../dist')
  63. ],
  64. }),
  65. ],
  66. }

对测试环境的配置文件增加对css文件和scss文件的loader

  1. const { merge } = require("webpack-merge");
  2. const commonConfig = require("./webpack.common.js");
  3. const devConfig = {
  4. mode: "development",
  5. devtool: "eval-cheap-module-source-map",
  6. devServer: {
  7. contentBase: "./dist",
  8. open: true,
  9. hot: true,
  10. hotOnly: true
  11. },
  12. module: {
  13. // 新增 .scss 和 .css 的 loader
  14. rules: [{
  15. test: /\.scss$/,
  16. use: ["style-loader", {
  17. loader: "css-loader",
  18. options: {
  19. importLoaders: 2,
  20. modules: true
  21. }
  22. }, "sass-loader", "postcss-loader"]
  23. },{
  24. test: /\.css$/,
  25. use: ["style-loader", "css-loader", "postcss-loader"]
  26. }]
  27. }
  28. }
  29. module.exports = merge(commonConfig, devConfig);

对生产环境的配置文件增加对css文件和scss文件的loader,使用MiniCssExtractPlugin.loader替换掉style-loader,对plugins进行配置:

  1. const { merge } = require("webpack-merge");
  2. const commonConfig = require("./webpack.common.js");
  3. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  4. const prodConfig = module.exports = {
  5. mode: "production",
  6. devtool: "cheap-module-source-map",
  7. module: {
  8. rules: [{
  9. test: /\.scss$/,
  10. // 删除 style-loader 替换为 MiniCssExtractPlugin.loader
  11. use: [MiniCssExtractPlugin.loader, {
  12. loader: "css-loader",
  13. options: {
  14. importLoaders: 2,
  15. modules: true
  16. }
  17. }, "sass-loader", "postcss-loader"]
  18. }, {
  19. test: /\.css$/,
  20. use: [MiniCssExtractPlugin.loader, "css-loader", "postcss-loader"]
  21. }]
  22. },
  23. plugins: [new MiniCssExtractPlugin()]
  24. }
  25. module.exports = merge(commonConfig, prodConfig);

更改sideEffects的配置,忽略scss文件和css文件的导出(因为这两个是样式文件,没有导出):

  1. {
  2. "sideEffects": [
  3. "*.scss",
  4. "*.css"
  5. ],
  6. // ...
  7. }

这个时候运行npm run build就能看到css文件被打包分离出来。
更多配置项:
MiniCssExtractPlugin | webpack 中文文档
更多高级用法:
MiniCssExtractPlugin | webpack 中文文档

代码压缩

MiniCssExtractPlugin是不支持代码压缩和多css文件合并的,所以还需要借助另外一个插件css-minimizer-webpack-plugin

安装:

  1. $ npm install css-minimizer-webpack-plugin -D

配置optimization.minimizer

  1. const { merge } = require("webpack-merge");
  2. const commonConfig = require("./webpack.common.js");
  3. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  4. const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
  5. const prodConfig = module.exports = {
  6. mode: "production",
  7. devtool: "cheap-module-source-map",
  8. // optimization表示优化
  9. optimization: {
  10. // 压缩css文件代码
  11. minimizer: [new CssMinimizerPlugin()]
  12. },
  13. module: {
  14. rules: [{
  15. test: /\.scss$/,
  16. use: [MiniCssExtractPlugin.loader, {
  17. loader: "css-loader",
  18. options: {
  19. importLoaders: 2,
  20. modules: true
  21. }
  22. }, "sass-loader", "postcss-loader"]
  23. }, {
  24. test: /\.css$/,
  25. use: [MiniCssExtractPlugin.loader, "css-loader", "postcss-loader"]
  26. }]
  27. },
  28. plugins: [
  29. new MiniCssExtractPlugin({
  30. // 直接被引入到 html 的link标签中被命名为 name.hash.js
  31. filename: "[name].[hash].css",
  32. // 间接被引入的css被命名为 name.chunk.hash.js
  33. chunkFilename:"[name].chunk.[hash].css"
  34. })
  35. ]
  36. }
  37. module.exports = merge(commonConfig, prodConfig);