Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSS Module does not work #70

Closed
micooz opened this issue Dec 7, 2017 · 23 comments
Closed

CSS Module does not work #70

micooz opened this issue Dec 7, 2017 · 23 comments

Comments

@micooz
Copy link

micooz commented Dec 7, 2017

Thanks for your awesome tool.

parcel document gives a brief introduction to CSS Modules but I stuck at my first try to use it:

// Import a CSS file with CSS modules
import classNames from './test.css';

I quickly cloned a demo project, add node-sass, import index.scss as CSS Modules and want to see how it works but unfortunately it doesn't work.

Minimal example to reproduce: micooz/react-parcel-example@44e8c2b

2017-12-07 10-06-01

Why

I guess require does a wrong thing when interpret scss or css file as CSS Modules, it just returns an empty object here:

// bundle.js
var _index = require("./index.scss"); // {}

var _index2 = _interopRequireDefault(_index); // {default: {}}

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var App = function App() {
  return _react2.default.createElement(
    "div",
    { className: _index2.default.app },
    "Hello Parcel x React"
  );
};
@devongovett
Copy link
Member

Currently, you need to install postcss-modules in your app, and add this to your .postcssrc file:

{
  "modules": true
}

This is documented briefly at https://parceljs.org/transforms.html#postcss. It's necessary to do this because we don't want to include the classes in the JS bundle by default for people that aren't using CSS modules.

Perhaps there is a better way we could detect CSS modules so we don't need to require that configuration (e.g. based on import statements maybe), so open to suggestions there.

@micooz
Copy link
Author

micooz commented Dec 7, 2017

Thanks for your help, problem resolved.

@meiriko
Copy link

meiriko commented Dec 7, 2017

@micooz I tried it too but it didn't work, even after cloning your repo and adding the postCss. Do you mind creating a commit with the working version and post here the hash so I can clone it and see it working? Thx

@micooz
Copy link
Author

micooz commented Dec 8, 2017

@meiriko Here it is: micooz/react-parcel-example@77d4959

You may need to upgrade parcel-bundler to v1.0.3 to make it work.

@Jayphen
Copy link

Jayphen commented Dec 13, 2017

Using the example provided by @micooz (and in my own testing), the styles seem to be removed as soon as the module hot reloads, and are not re-applied even on refresh.

@thomasfortes
Copy link

thomasfortes commented Dec 15, 2017

Almost the same as @Jayphen here, global styles are applied when the module hot-reloads, local ones do not, but when I refresh the page they are applied normally.

@jrop
Copy link

jrop commented Jan 5, 2018

I am getting the same results as @Jayphen and @thomasfortes, except I am using Stylus.

postcss.config.js

module.exports = {
	modules: true,
}

index.js

import React from 'react'
import {render} from 'react-dom'

import styles from './index.styl'

console.log(styles)

const App = () => <div className={styles.app}>Hello from React!</div>
render(<App />, document.getElementById('root'))

index.styl

.app {
	font-family: sans-serif;
}

When I run parcel src/index.html, the app logs an empty object: {}. However when I produce the production bundle with parcel bundle src/index.html, it loads the styles correctly.

I am using parcle-bundler@1.4.1.

@azzgo
Copy link

azzgo commented Jan 13, 2018

Hi, I meet @jrop same problem here but seems it is a problem with hot reload. When I start with parcel --no-hmr src/index.html, it works as expected.

@g33kChris
Copy link

I've noticed that when the --no-hmr flag is set that the css classes are transpiled correctly, and without the flag, the class names are the same as they are in source.

With hot modules: .root
WIthout: hot modules ._root_17swk_1

@aventide
Copy link

Thanks @g33kChris. That piece of knowledge did it for me. Just use the name of the class itself, not the imported classname. That confused me a bit, especially since my IDE was complaining about the unused import statement for the css file.

@embiem
Copy link

embiem commented Feb 1, 2018

Is there a way to tell postcss to only transform ".css" files to css modules and not e.g. ".scss" files? Like an "input": "src/**/*.css" property in the .postcssrc file?

@jimzhan
Copy link

jimzhan commented Feb 23, 2018

@devongovett not sure it's the same. But I'm still getting similar error saying:

screen shot 2018-02-23 at 4 26 36 pm

even after adding "postcss-modules" along with suggested postcss settings, everything things worked before with the same setup (without postcss-modules & relative settings).

node v9.5.0
parcel v1.6.2

@jimzhan
Copy link

jimzhan commented Feb 23, 2018

It turned out its caused by less, getting back to v2 from v3 help solved the issue.

@pcattori
Copy link
Contributor

pcattori commented Mar 1, 2018

Is there a way to tell the Bundler to disable HMR? Trying to use the fix @azzgo suggested, but I'm using Parcel as middleware with express so that I can proxy API calls.

In the long term, I assume fixing HMR mode so that it respects CSS Modules naming is the fix...

UPDATE:

The API docs for Bundler don't seem to show it, but it looks like there is an hmr parameter within options that does the trick:

import ParcelBundler from 'parcel-bundler'
import express from 'express'
import proxy from 'http-proxy-middleware'

const parcel = new ParcelBundler('./static/index.html', { hmr: false })
const app = express()

app.use('/api', proxy({ target: 'http://localhost:8000' }))
app.use(parcel.middleware())
app.listen(Number(process.env.UI_PORT || 1234))

Again, this is a temporary fix until HMR with CSS Modules is fixed.

@mateja176
Copy link

Currently, you need to install postcss-modules in your app, and add this to your .postcssrc file:

{
  "modules": true
}

This is documented briefly at https://parceljs.org/transforms.html#postcss. It's necessary to do this because we don't want to include the classes in the JS bundle by default for people that aren't using CSS modules.

Perhaps there is a better way we could detect CSS modules so we don't need to require that configuration (e.g. based on import statements maybe), so open to suggestions there.

It seems like you are implying that there's a significant overhead when importing classNames, in terms of bundle size and processing time. What other reason might be there not to make it a default? I love Parcel it offers great defaults and I'm sure I'm not the only one. CSS Modules are great default imo.

@cj
Copy link

cj commented Nov 12, 2018

@devongovett

Perhaps there is a better way we could detect CSS modules so we don't need to require that configuration (e.g. based on import statements maybe), so open to suggestions there.

You could do it the way https://poi.js.org/ does it, *.module.(css|scss|less). That way it's not an all or nothing approach.

@ColrBlnd
Copy link

ColrBlnd commented Jan 7, 2019

Parcel just works... unless you use something basic like CSS, then it requires complex configurations

@clottman
Copy link

I landed on this question too after thinking that CSS Modules was broken somehow. I think my confusion stemmed from the fact that on the docs page for CSS, it says up top that:

CSS assets can be imported from a JavaScript or HTML file:

import './index.css';

But then it's clarified below that you need to install PostCSS if you want it to work.

On my first read-through, it seemed like I only needed to install PostCSS if I wanted to use plugins like autoprefixer. I assumed based on the info at the top that if I just wanted to import a plain CSS file in Javascript, it would 'just work'.

@clottman
Copy link

clottman commented Jan 26, 2019

Also, even after installing PostCSS and creating a postcssrc file, my modules didn't work. I had to find another closed Github issue which told me to clear the .cache directory, and then it worked. Can we clarify the documentation a bit to make that step more explicit?

@mischnic
Copy link
Member

@DeMoorJasper Is .postcssrc even being handled like .babelrc regarding cache invalidation?

@mightyiam
Copy link

Not to undermine the purpose of this issue... I recommend a css-in-js solution instead of a style sheet. I use typestyle but there are others. Just a friendly tip. For most new app development cases.

@v1vendi
Copy link

v1vendi commented Feb 25, 2019

Managed to succeed thanks to @micooz
Guys, css modules in parcel for some reason don't work without autoprefixer installed and added to .postcssrc

@isitgeorge
Copy link

isitgeorge commented Oct 17, 2019

is using the --no-hmr flag still the only way to make css modules behave correctly?

My bad, installing autoprefixer and postcss-modules into the correct package.json does indeed resolve it, even with hot reload

AGawrys pushed a commit that referenced this issue Dec 7, 2020
remove webpack logic from sync-dynamic-import plugin

Approved-by: Maia Teegarden
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests