meteor-css-modules icon indicating copy to clipboard operation
meteor-css-modules copied to clipboard

import from './Foo' reads from Foo.scss rather than Foo.jsx

Open yched opened this issue 6 years ago • 5 comments

(Seeing this with Meteor 1.6.0.1, did not check with 1.5)

Say I have :

  • ComponentA.js : some react component
import ComponentB from './ComponentB'; // relies on implicit .js extension
export default function () => <ComponentB>foobar</ComponentB>;
  • ComponentB.js : some component

The moment I add a ComponentB.(s)css file next to ComponentB.js to hold its local styles, then the import ComponentB from './ComponentB' line in ComponentA.js appears to read from the css file rather than the js file.

(The app crashes with the following message in the browser console : "React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. Check the render method of 'ComponentA'" Adding a console.log(ComponentB) within ComponentA.js shows that the imported value is indeed the { styles : { .. } } object from the css file)

For now, I'm naming all my local style files something like MyComponent_.(s)css so that the filename differ from the js component file even without the extension.

Not sure if that behavior is controlled by meteor-css-modules, or if that is something that should be fixed upstream in the Meteor bundler ?

yched avatar Dec 28 '17 17:12 yched

[removed, more up-to-date findings in next comment]

yched avatar Dec 29 '17 13:12 yched

Running some more tests, I actually narrowed it down to an issue with .scss and .jsx files specifically: (for some reason, when initially developping the app, we adopted the convention to use the *.jsx extension for our react component files - might not be such a great idea in retrospect...)

  • foo.js + foo.css --> OK: import foo from './foo' imports from foo.js

  • foo.js + foo.scss --> OK: import foo from './foo' imports from foo.js

  • foo.jsx + foo.css --> OK: import foo from './foo' imports from foo.jsx

  • foo.jsx + foo.scss --> KO: import foo from './foo' imports from foo.scss

yched avatar Dec 29 '17 13:12 yched

Can you provide a simple reproduction repo? This plugin should be outputting a foo.scss.js, not a foo.js file, so I'm not sure why they'd conflict. You can also try adjusting the (currently undocumented) outputJsFilePath option in your package.json. The default value is '{dirname}/{basename}{extname}', and .js will automatically be appended to the end of whatever you specify.

Thanks!

akanix42 avatar Jan 08 '18 15:01 akanix42

Yeah, sorry if I wasn't clear, took me a couple iterations to exactly identify the symptoms.

This is not a conflict with the files the plugin generates, but a conflict striclty between the files present in my app, and the way 'import' imports them when meteor-css-modules is present :

  • For some reason, we chose to use the *.jsx extension for all our react components (helps figuring which is which between react components and plain js helpers)
  • import MyComponent from './MyComponent' (without specifying the extension) correctly finds the MyComponent.jsx file
  • But when meteor-css-modules is present with sass compilation, and a MyComponent.scss file exists next to MyComponent.jsx, then import MyComponent from './MyComponent' targets the scss file rather than the jsx file. (See my previous comment for a more detailed breakdown of the combinations that work or not.)

As I wrote above, maybe it's not an actual bug, but a non-officially-supported (?) combination on our side (*.jsx files + imports with implicit extension), that meteor-css-modules happens to break.

Anyway, here's a reproduction repo : https://github.com/yched/demo-meteor-css-modules-bug-114

yched avatar Jan 08 '18 17:01 yched

This doesn't seem exclusive to meteor-css-modules. It happens for me when using the less package and having a MyComponent.jsx and MyComponent.less in the same directory. Any import with implicit extension prefers the .less file. Still looking for a solution to prioritize .jsx over .less.

btorresgil avatar Jan 09 '18 17:01 btorresgil