parcel: [Bug] HMR and PostCSS modules, styles disappear

🐛 bug report

🎛 Configuration

.babelrc

{
	"presets": [
		"react",
		["env", {
			"targets": {
				"browsers": [ "last 2 versions" ]
			},
			"debug": true
		}]
	]
}

.postcssrc.js

module.exports = {
	modules: true,
	plugins: {
		"autoprefixer": {}
	}
};

browserslist

last 2 versions

index.html

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>React App</title>
	</head>
	<body>
		<div id="app"></div>

		<script src="./index.js"></script>
	</body>
</html>

index.js

require("babel-polyfill");

const styles = require("./app.styl");

console.log("styles???", styles);

const React = require("react");
const ReactDOM = require("react-dom");

const App = () => (
	<div className={ styles.app }>Hello!!</div>
);

ReactDOM.render(<App/>, document.getElementById("app"));

app.styl

.app
	color: blue
	transform: scale(0.95)
	transition: transform 0.4s ease

CLI: ./node_modules/.bin/parcel index.html

🤔 Expected Behavior

Changing app.styl should update styles properly.

😯 Current Behavior

Styles disappear after change to app.styl. index.js (which requires app.styl) is not reloaded when the app.styl file is changed.

💻 Code Sample

Source code: parcel-postcss-modules-bug.tar.gz

🌍 Your Environment

Software Version(s)
Parcel 1.5.1 and master at 6deec80b3491dc5ac690da6550323b51deec6530
Node 9.5.0
npm 5.6.0
Operating System Linux x86_64

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 7
  • Comments: 26 (4 by maintainers)

Most upvoted comments

Finally I was able to solve this issue by adding this on plugins in .postcssrc

    "postcss-modules": {
      "generateScopedName": "[name]_[local]_[hash:base64:5]"
    }

.postcssrc now looks like

{
  "modules": true,
  "plugins": {
    "autoprefixer": {
      "grid": true
    },
    "postcss-modules": {
      "generateScopedName": "[name]_[local]_[hash:base64:5]"
    }
  }
}

@aelsv also seems to have suggested this solution. thanks @aelsv

I’ve updated parcel to the latest release on parcel-bundler-test, and now:

I am not sure if it is the PostCSS docs that need updating to include configuring generateScopedName or if this is something that should be fixed in the bundler itself being an issue with HMR.

In any case, leaving these comment as reference for others coming by with the same issue.

Fixed by #1589.

@lukebarton Exactly what @joakin described. @BipinBhandari configuration is not problematic, it is that parcel should work with the default config as in docs.

It is not a configuration problem. When a JS file depends on a CSS file that uses post-css modules, and the CSS file changes, the JS file doesn’t get recompiled.

See the parcel docs: https://parceljs.org/transforms.html#postcss With those instructions parcel doesn’t work with hmr which is the default mode.

@lukebarton I have a very simple SSCCE here: https://github.com/joakin/parcel-bundler-test

Steps to see the bug are:

  1. npm start
  2. Open localhost:1234
  3. Edit App.css and change the text color

Expected: Text color changes in the browser

Actual: class name is mangled and all styles are lost. Not even refreshing works.


I have also tried with generateScopedName in the config, and it doesn’t work for me sadly. Check out the fixed-postcss-classnames branch on that same repo: https://github.com/joakin/parcel-bundler-test/blob/fixed-postcss-classnames/.postcssrc.js


Let me know if there is anything else I could do to help diagnose. I’ve updated the repo to the latest parcel and all deps.

Whenever changes are made, stylesheet file is updated with new classname but html is not updated and old class name remains in it. If we could find a way to update classnames in html, this issue would be solved.

Same thing on my end… only thing keeping me from using Parcel atm.

@joakin When I use --no-hmr, it works perfectly. When I don’t, my CSS file and the references to its classes in my JS file are left intact. I tried your solution with generateScopedName and unfortunately, it doesn’t work any better. ☹️

This is cause by the class names being remangled. For example, a css file with

.main {
    color: blue;
}

exports the object:

{
    main: '_main_qaqe8_1'
}

Changing the original file will make the exported module to be:

{
    _main_1eufg_1: '__main_1eufg_1_1eufg_1'
}

So style.main will be undefined and the elements stop having classes.

I took a quick glance at the code, but I can’t find the problem. Maybe the issue is with postcss-modules itself.

Running parcel src/index.html --no-hmr the issue persists across reloads. The postcss modules support seems to be broken, unrelated to HMR.

I think I’ve hit this issue with a typescript + css modules repo. See https://github.com/joakin/parcel-bundler-test/ for minimal example.

Here’s a gif that shows the broken behavior:

parcel-css-modules

On reload it also shows that the styles object is broken (seems like it takes the old hashes and uses them as keys)

When doing parcel build it seems to work fine and generate the correct CSS file.

Not a misconfiguration. @BipinBhandari has managed to hack around it.

@joakin Ok. Seems like i fixed this for me. Try it. { "modules": true, "plugins": { "postcss-modules": { "generateScopedName": "[name]_[local]_[hash:base64:5]" }, "autoprefixer": { browsers: [ "> 1%", "Last 2 versions" ] } } }

Also: "node-sass": "^4.8.3", "parcel-bundler": "^1.6.2", "postcss-modules": "^1.1.0"