Mini-css-extract-plugin 没有将我的 css 与 sass 捆绑到一个文件中

Mini-css-extract-plugin doesn't bundle my css into one single file with sass

当我尝试添加 sass-loader 和 运行 webpack 时,dist 文件夹中有多个 chunck .css 文件,而不仅仅是名为 [=25 的捆绑文件=].

我的 dist 输出文件夹如下所示:

0.e749007119be51de03e4.js  1.e749007119be51de03e4.js  bundle.e749007119be51de03e4.js
0.style.css                1.style.css

我想这是因为 Mini-css-extract-plugin 但我不知道如何修复它。

这是我的 webpack 文件:

const webpack = require('webpack');
const { resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

const ROOT = resolve(__dirname);
const SRC = resolve(ROOT, 'src');

module.exports = {
  mode: 'development',
  devtool: 'cheap-module-eval-source-map',
  entry: {
    bundle: [
      'react-hot-loader/patch',
      'webpack-hot-middleware/client?reload=true',
      resolve(SRC, 'client', 'index.js'),
    ]
  },
  output: {
    path: resolve(ROOT, 'dist', 'client'),
    filename: '[name].[hash].js',
    publicPath: '/'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: 'babel-loader',
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        include: resolve(__dirname, 'node_modules', 'react-toolbox'),
        use: [
          MiniCssExtractPlugin.loader,
          // 'style-loader',
          {
            loader: 'css-loader',
            options: {
              modules: true,
              sourceMap: true,
              importLoaders: 1,
              localIdentName: '[name]_[local]_[hash:base64:5]'
            }
          },
          // 'postcss-loader'
        ]
      },
      {
        test: /\.scss$/,
        use: ['style-loader', MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
      },
      {
        test: /\.css$/,
        exclude: resolve(__dirname, 'node_modules', 'react-toolbox'),
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.(jpe?g|svg|png|gif)$/,
        use: ['file-loader']
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        use: ['file-loader']
      }
    ]
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new MiniCssExtractPlugin({
      filename: 'style.css',
    }),
  ]
};

有什么想法吗?

从文档中查看这段代码

module: {
  rules: [
    {
      test: /\.(sa|sc|c)ss$/,
      use: [
        devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
        'css-loader',
        'postcss-loader',
        'sass-loader',
      ],
    }
  ]
}

如果仔细观察,您会发现它在开发模式下使用 style-loader,在生产模式下使用 MiniCssExtractPlugin.loader。所以在生产中它会为 css.

生成另一个文件

你需要做的是:

在脚本部分的 package.json 文件中,您需要像这样传递一个环境变量 devMode

"scripts": {
  "webpack": "webpack",
  "start": "npm run webpack -- --env.mode=development"
}

然后在您的 webpack.config.js 文件中您需要这样做

module.exports = (env) => {
  const devMode = env.mode === 'development'
  return {
    mode: env.mode, // will be development
    devtool: ...,
    entry: { ... },
    output: { ... },
    module: {
      rules: [
        {
          test: /\.scss$/,
          use: [devMode ? 'style-loader' : MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
        }          
      ]
    }
  }
}

应该没问题,希望对你有帮助。

There is two problems coming with this way. If i wanna use a plugin like html-webpack-plugin the index.html file is not filled with the anymore. Secondly the normal behavior of MiniCssExtractPlugin shouldn't be to create a file style.css like i precised in the constructor ?

不,因为你有异步块,它将为从那些异步块中删除的每个样式创建一个 style.css。

我向您保证,如果您使用的是 html-webpack-plugin,它将会正常工作。它只是没有添加到那里,因为那些 css 不是来自其中一个入口点。这就是它不直接插入 html 的原因。我有一个类似的项目,而且效果很好。

如果这些块不是从入口点发出的,一旦请求这些块,webpack 就会动态加载这些块。

大文件伤害用户。代码拆分永远是一切的答案!!