ShakaCode | ShakaCode Blog | Rails On Maui Blog | Rails | ReactJs | JavaScript | Webpack | Productivity |

CSS Modules with React on Rails


#1

I’m trying to add React to a Rails 5.1.4 using react-on-rails 10.1.1. The part that I haven’t been able to figure out is how to use the CSS Modules approach advocated by the tutorial.

I have a component:

app/javascript/bundles/Workflow/components/Preview.jsx

with style:

app/javascript/bundles/Workflow/components/Preview.scss

In Preview.jsx:

import css from ‘./Preview.scss’;
console.log(‘css:’, css);

In Preview.scss:

.foo {
background-color: blue;
}

This fails with errors in the console that indicate something is trying to import Preview.scss as Javascript (see below).

So I just rename Preview.scss to Previewx.scss and adjust the import. That gets me a little farther, but the console.log is showing that the imported css is an empty object.

I’m trying to not get too far from what the generator does:

rails generate react_on_rails:install

It seems like I’m close. But I’m not even sure how to ask the question(s) intelligently. I’ll try though:

  1. What is responsible for turning the .scss file into something other than an empty object?
  2. Why does naming it to match the component being styled (different extension, of course) fail in that way?

Thanks!

Error processing Preview.scss before renaming it

warning.js:33 Warning: React.createElement: type is invalid – expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it’s defined in, or you might have mixed up default and named imports.
printWarning @ warning.js:33
warning @ warning.js:57
createElementWithValidation @ react.development.js:1243
createReactElement @ createReactElement.js:48
render @ clientStartup.js:143
forEach @ clientStartup.js:64
forEachComponent @ clientStartup.js:76
reactOnRailsPageLoaded @ clientStartup.js:177
(anonymous) @ clientStartup.js:232
invariant.js:42 Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it’s defined in, or you might have mixed up default and named imports.
at invariant (invariant.js:42)
at createFiberFromElement (react-dom.development.js:5753)
at reconcileSingleElement (react-dom.development.js:7531)
at reconcileChildFibers (react-dom.development.js:7635)
at reconcileChildrenAtExpirationTime (react-dom.development.js:7764)
at reconcileChildren (react-dom.development.js:7747)
at updateHostRoot (react-dom.development.js:7940)
at beginWork (react-dom.development.js:8227)
at performUnitOfWork (react-dom.development.js:10224)
at workLoop (react-dom.development.js:10288)
invariant @ invariant.js:42
createFiberFromElement @ react-dom.development.js:5753
reconcileSingleElement @ react-dom.development.js:7531
reconcileChildFibers @ react-dom.development.js:7635
reconcileChildrenAtExpirationTime @ react-dom.development.js:7764
reconcileChildren @ react-dom.development.js:7747
updateHostRoot @ react-dom.development.js:7940
beginWork @ react-dom.development.js:8227
performUnitOfWork @ react-dom.development.js:10224
workLoop @ react-dom.development.js:10288
callCallback @ react-dom.development.js:542
invokeGuardedCallbackDev @ react-dom.development.js:581
invokeGuardedCallback @ react-dom.development.js:438
renderRoot @ react-dom.development.js:10366
performWorkOnRoot @ react-dom.development.js:11014
performWork @ react-dom.development.js:10967
requestWork @ react-dom.development.js:10878
scheduleWorkImpl @ react-dom.development.js:10732
scheduleWork @ react-dom.development.js:10689
scheduleTopLevelUpdate @ react-dom.development.js:11193
updateContainer @ react-dom.development.js:11231
(anonymous) @ react-dom.development.js:15226
unbatchedUpdates @ react-dom.development.js:11102
renderSubtreeIntoContainer @ react-dom.development.js:15225
render @ react-dom.development.js:15290
render @ clientStartup.js:154
forEach @ clientStartup.js:64
forEachComponent @ clientStartup.js:76
reactOnRailsPageLoaded @ clientStartup.js:177
(anonymous) @ clientStartup.js:232
react-dom.development.js:9747 The above error occurred in one of your React components:

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://fb.me/react-error-boundaries to learn more about error boundaries.
logCapturedError @ react-dom.development.js:9747
captureError @ react-dom.development.js:10540
renderRoot @ react-dom.development.js:10391
performWorkOnRoot @ react-dom.development.js:11014
performWork @ react-dom.development.js:10967
requestWork @ react-dom.development.js:10878
scheduleWorkImpl @ react-dom.development.js:10732
scheduleWork @ react-dom.development.js:10689
scheduleTopLevelUpdate @ react-dom.development.js:11193
updateContainer @ react-dom.development.js:11231
(anonymous) @ react-dom.development.js:15226
unbatchedUpdates @ react-dom.development.js:11102
renderSubtreeIntoContainer @ react-dom.development.js:15225
render @ react-dom.development.js:15290
render @ clientStartup.js:154
forEach @ clientStartup.js:64
forEachComponent @ clientStartup.js:76
reactOnRailsPageLoaded @ clientStartup.js:177
(anonymous) @ clientStartup.js:232
invariant.js:42 Uncaught Error: ReactOnRails encountered an error while rendering component: Preview.
Original message: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it’s defined in, or you might have mixed up default and named imports.
at invariant (invariant.js:42)
at createFiberFromElement (react-dom.development.js:5753)
at reconcileSingleElement (react-dom.development.js:7531)
at reconcileChildFibers (react-dom.development.js:7635)
at reconcileChildrenAtExpirationTime (react-dom.development.js:7764)
at reconcileChildren (react-dom.development.js:7747)
at updateHostRoot (react-dom.development.js:7940)
at beginWork (react-dom.development.js:8227)
at performUnitOfWork (react-dom.development.js:10224)
at workLoop (react-dom.development.js:10288)
invariant @ invariant.js:42
createFiberFromElement @ react-dom.development.js:5753
reconcileSingleElement @ react-dom.development.js:7531
reconcileChildFibers @ react-dom.development.js:7635
reconcileChildrenAtExpirationTime @ react-dom.development.js:7764
reconcileChildren @ react-dom.development.js:7747
updateHostRoot @ react-dom.development.js:7940
beginWork @ react-dom.development.js:8227
performUnitOfWork @ react-dom.development.js:10224
workLoop @ react-dom.development.js:10288
callCallback @ react-dom.development.js:542
invokeGuardedCallbackDev @ react-dom.development.js:581
invokeGuardedCallback @ react-dom.development.js:438
renderRoot @ react-dom.development.js:10366
performWorkOnRoot @ react-dom.development.js:11014
performWork @ react-dom.development.js:10967
requestWork @ react-dom.development.js:10878
scheduleWorkImpl @ react-dom.development.js:10732
scheduleWork @ react-dom.development.js:10689
scheduleTopLevelUpdate @ react-dom.development.js:11193
updateContainer @ react-dom.development.js:11231
(anonymous) @ react-dom.development.js:15226
unbatchedUpdates @ react-dom.development.js:11102
renderSubtreeIntoContainer @ react-dom.development.js:15225
render @ react-dom.development.js:15290
render @ clientStartup.js:154
forEach @ clientStartup.js:64
forEachComponent @ clientStartup.js:76
reactOnRailsPageLoaded @ clientStartup.js:177
(anonymous) @ clientStartup.js:232


#2

A different way to ask my question(s):

What are the steps to take after installing react-on-rails as described on the the gem’s home page so that one can use the CSS Modules approach as shown in the tutorial?


#3

Take a look at https://github.com/shakacode/react-webpack-rails-tutorial.

That shows how to do it.