开发者问题收集

当有多个 CSS 输出时,如何让 webpack 生成具有相同名称“index”的单独 CSS 和 JS,例如“index.js”和“index.css”?

2022-01-13
2533

我能够生成单独的 CSS 和 Js,如: 我可以使用 webpack 分别生成 CSS 和 JS 吗?

下面的工作基线代码生成名为的文件:

dist/index.js
dist/main.css
dist/main.js
dist/notmain.css
dist/notmain.js

请注意,不需要的 main.jsnotmain.js 虚拟文件 没有人知道如何很好地修复 ,但这对我来说无关紧要在这种情况下。

我的问题是,我怎样才能让 Webpack 生成:

dist/index.css
dist/index.js
dist/notmain.css

即将 main.css 重命名为 index.css

天真地,我想要的只是将工作基线修改为:

  entry: {
    index: ['./index.js'],
    index: ['./index.scss'],
  },

但那样就没有任何意义了,因为 entry 字典现在有两个 index 键,第二个键会删除第一个。

此外,如果我只有一个 CSS 输出,我可以硬编码:

    new MiniCssExtractPlugin({
      filename: 'index.css',
    }),

但由于我有多个,这行不通,我需要那个 [name] 占位符以某种方式工作。

我已经在 https://webpack.js.org/configuration/entry-context/#output-filename 它记录了类似以下内容的内容:

    main: {
      import: './main.scss',
      filename: 'index.css',
    },

可以工作,但如果我尝试,它会失败:

ERROR in index.css
index.css from Css Minimizer
/home/ciro/bak/git/cirosantilli.github.io/webpack/tmp/index.css:1:10: Unknown word [index.css:1,10]

有关此错误消息的类似问题可以在以下位置看到: webpack 使用 webpack.config.js 文件失败“模块构建失败:未知单词” 发生的事情是,由于某种原因 dist/index.css 包含一个 JavaScript 文件,然后 CSS 压缩器失败来解析它。不过,对 index.js 的类似更改确实适用于 JavaScript,它是特定于此 CSS 设置的内容。

工作基准代码

index.html

<!doctype html>
<html lang=en>
<head>
<meta charset=utf-8>
<title>Sass import</title>
<link rel="stylesheet" href="dist/main.css">
<link rel="stylesheet" href="dist/notmain.css">
</head>
<body>
<p>Hello</p>
<script src="dist/index.js"></script>
</body>
</html>

index.js

document.getElementsByTagName('body')[0].innerHTML += '<p>js works</p>'

main.scss

body {
  background-color: red;
}

notmain.scss

body {
  color: blue;
}

webpack.config.js

const path = require('path');

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

const nodeModulesPath = path.resolve(__dirname, 'node_modules');

module.exports = {
  entry: {
    index: ['./index.js'],
    main: ['./main.scss'],
    notmain: ['./notmain.scss'],
  },
  mode: 'none',
  module: {
    rules: [
      {
        test: /\.(scss|css)$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'sass-loader',
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css',
    }),
  ],
  optimization: {
    minimizer: [
      new CssMinimizerPlugin(),
    ],
    minimize: true,
  },
  output: {
    filename: '[name].js',
  },
};

package.json

{
  "name": "webpack-cheat",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "build": "webpack",
    "sass": "rm -f dist/main.css && sass -I node_modules main.scss dist/main.css"
  },
  "author": "Ciro Santilli",
  "license": "MIT",
  "devDependencies": {
    "css-loader": "5.2.4",
    "css-minimizer-webpack-plugin": "3.0.2",
    "mini-css-extract-plugin": "2.1.0",
    "normalize.css": "8.0.1",
    "sass": "1.32.11",
    "sass-loader": "11.0.1",
    "style-loader": "2.0.0",
    "webpack": "5.36.1",
    "webpack-cli": "4.6.0",
    "webpack-dev-server": "3.11.2"
  }
}

编译并运行:

npm install
npm run build
xdg-open index.html

另请咨询: https://github.com/webpack/webpack/discussions/15163

2个回答

您想要类似的东西,以下是我自己使用 webpack v5 的配置中的一些摘录:

module.exports = {
 // other stuff omitted
 output: {
    // other stuff omitted
    filename: '[name].js',
    chunkFilename: '[name].js'
  },
  entry: {
    index: [
      './src/index.js'
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css',
      ignoreOrder: true
    }),
  ]
} 

可以使用 [name] 替换来映射回磁盘上的名称。

请参阅

了解更多信息

random-forest-cat
2022-01-13

出色的 Webpack 开发人员 Alexander Akait 刚刚回复了我 并提供了一个可行的解决方法:

  plugins: [
    new MiniCssExtractPlugin({
      filename: (pathData) => {
        if (pathData.chunk.name === "main") {
          return 'index.css'
        }

        return '[name].css'
      },
    }),
  ],

因此我们看到 filename 可以采用任意函数而不仅仅是字符串,然后我们能够以更大的灵活性解决问题。

他还提到:

I see, yep, it is limitation, we are working on built-in CSS support (it will resolve the problem), currently please use:

因此看来 Webpack 历来更专注于“使用 Js 方法注入 CSS”,但现在这种方法正在被推广。

谢谢 Alexander!

Ciro Santilli OurBigBook.com
2022-01-13