I was able to produce separate CSS and Js as mentioned at: Can I use webpack to generate CSS and JS separately?
The working baseline code below produces files named:
dist/index.js
dist/main.css
dist/main.js
dist/notmain.css
dist/notmain.js
Note that undesired main.js
and notmain.js
dummy files which no ones knows how to nicely fix, but it doesn't matter to me in this case.
My question is, how can I get Webpack to instead generate:
dist/index.css
dist/index.js
dist/notmain.css
i.e., rename main.css
to index.css
?
?
Naively, what I wanted would be to just modify the working baseline to:
entry: {
index: ['./index.js'],
index: ['./index.scss'],
},
but then that wouldn't make any sense, since the entry
dict now has two index
keys, and the second one would erase the first.
Also, if I had just a single CSS output, I could just hardcode:
new MiniCssExtractPlugin({
filename: 'index.css',
}),
but since I have multiple ones, that won't cut it, I need that [name]
placeholder to work somehow.
I've seen at https://webpack.js.org/configuration/entry-context/#output-filename that it documents that something like:
main: {
import: './main.scss',
filename: 'index.css',
},
could work, but if I try that it fails with:
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]
A similar question about this error message can be seen at: webpack fails "module build failed: unknown word" with webpack.config.js file What happens is that for some reason dist/index.css
contains a JavaScript file, and the then CSS minifier fails to parse it. An analogous change for index.js
did work for JavaScript though, it's something specific to this CSS setup.
Working baseline code
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"
}
}
Compile and run:
npm install
npm run build
xdg-open index.html
Also asking at: https://github.com/webpack/webpack/discussions/15163