Rmwc: Incompatible with next.js?

Created on 21 Jul 2020  ยท  7Comments  ยท  Source: jamesmfriedman/rmwc

  • Javascript Sandbox https://codesandbox.io/s/rmwc-sandbox-o0s0d
    Repro: https://codesandbox.io/s/clever-river-u40p1

  • What RMWC Version are you using [major.minor.patch]:
    โ””โ”€โ”€โ”€ [email protected]

  • Name your build system [Webpack, Rollup...]:
    โ””โ”€ [email protected]
    โ””โ”€โ”€[email protected]

  • Describe the bug with as much detail as possible:
    Fails to compile. See linked repro above.

  • What happened, and what was supposed to happen:
    What happened:

    remy example $ npx create-next-app
    remy example $ npm i rmwc
    remy example $ npm run build

    [email protected] build /Users/shaun.gaisie/Dev/temp/example
    next build

    Creating an optimized production build

    Failed to compile.

    ./node_modules/@material/button/dist/mdc.button.css
    Global CSS cannot be imported from within node_modules.
    Read more: https://err.sh/next.js/css-npm
    Location: node_modules/@rmwc/button/styles.js

    Build error occurred
    Error: > Build failed because of webpack errors
    at build (/Users/shaun.gaisie/Dev/temp/example/node_modules/next/dist/build/index.js:13:917)
    npm ERR! code ELIFECYCLE
    npm ERR! errno 1
    npm ERR! [email protected] build: next build
    npm ERR! Exit status 1
    npm ERR!
    npm ERR! Failed at the [email protected] build script.
    npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

What was expected:

npm run build
[email protected] build /remy/Dev/temp/example
next build

Creating an optimized production build

Compiled successfully.

Automatically optimizing pages

Page Size First Load JS
โ”Œ โ—‹ / 7.08 kB 65.8 kB
โ”œ โ—‹ /404 3.25 kB 61.9 kB
โ”” ฮป /api/hello

  • First Load JS shared by all 58.7 kB
    โ”œ static/pages/_app.js 983 B
    โ”œ static/pages/rmwc.js 983 B <-------
    โ”œ chunks/f794becb71e164155e177a3d31340dd5119954d8.36a881.js 10.7 kB
    โ”œ chunks/framework.c6faae.js 40 kB
    โ”œ runtime/main.5ff741.js 6.28 kB
    โ”” runtime/webpack.c21266.js 746 B

ฮป (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
โ—‹ (Static) automatically rendered as static HTML (uses no initial props)
โ— (SSG) automatically generated as static HTML + JSON (uses getStaticProps)

The suggestion from next.js (found here: https://github.com/vercel/next.js/blob/master/errors/css-npm.md):
CSS Imported by a Dependency
Why This Error Occurred
One of your dependencies (node_modules) imports a CSS file.

This normally happens when a package's source files are accidentally consumed, instead of the built package.

Possible Ways to Fix It
Reach out to the maintainer and ask for them to publish a compiled version of their dependency.

Compiled dependencies do not have references to CSS files, or any other files that require bundler-specific integrations.

The dependency should also provide instructions about what CSS needs to be imported by you, in your application.

Importing CSS files within node_modules cannot be supported because we cannot know the correct behavior:

Should the file be consumed as Global CSS or CSS Modules?
If Global, in what order does the file need to be injected?
If Modules, what are the emitted class names? As-is, camel-case, snake case?
Etc...

Most helpful comment

I'm currently doing the same thing as @4cm4k1 and am just importing all of those styles into one global.scss file which is then imported by _app.tsx.

It'd definitely be nice to be able to use SCSS modules to scope those styles to each RMWC component in the future. And @4cm4k1 I think the MWC version that @jamesmfriedman is using right now doesn't actually have the core-styles mixins.

All 7 comments

Hey @remy90,

I was browsing issues in this repo and saw this one. I use Next.js and RMWC like so here: https://github.com/4cm4k1/personal-website/blob/master/src/pages/_app.tsx#L9-L16

So, you'll need to update import "@rmwc/button/styles"; in pages/rmwc.js to:

import "@material/button/dist/mdc.button.css";
import "@rmwc/icon/icon.css";
import "@material/ripple/dist/mdc.ripple.css";

_OR_

You can do those imports in a custom pages/_app.js file instead, which is what I did, because many of the styles are needed globally.

I would recommend the pages/_app.js approach because RMWC's and Material Web Components' implementation currently do not allow for CSS or Sass Modules, which Next.js supports, and therefore the component-based code-splitting does not work. I am excited for whenever that is supported, though!

Hope this helps!

@4cm4k1 can you elaborate? I use CSS modules exclusively in projects with RMWC.

@jamesmfriedman As I have looked around more, I noticed CSS and Sass modules in use with RMWC. So I think what I'm trying to say is Next.js currently doesn't play nice with importing third-party styles (even if they're properly scoped to components), but it appears to be on the radar for the maintainers: https://github.com/vercel/next.js/issues/12079

Ever since I first implemented MWC-React and then RMWC I've been using the cumbersome, unperformant workaround of putting the CSS imports in my pages/_app.tsx, which concatenates all the global CSS into one file.

Hopefully, with the feature request pending, the third-party styling and components integration story will improve a lot.

I am now wondering (but can't try at the moment on my phone) whether something like this would work in the meantime (more of a Next.js question)?

  • pages/index.tsx:
import Button from '../components/Button';

const IndexPage = () => (
  <>
    <Button/>
  </>
);

export default IndexPage;
  • components/Button.tsx:
import { Button } from '@rmwc/button';

import styles from './Button.module.scss';

export default const Button = ({children}) => (
  <Button className={styles.myButton}>
    {children}
  </Button>
);
  • components/Button.module.scss:
@use "@material/button";

@include button.core-styles;

.myButton {
  @include button.someOtherMixin;
}

just hit this same issue

  • using correct imports at _app.js breaks my app with the error:

next-dev.js?53bc:48 Error was not caught TypeError: Cannot read property 'parentNode' of null

I'm currently doing the same thing as @4cm4k1 and am just importing all of those styles into one global.scss file which is then imported by _app.tsx.

It'd definitely be nice to be able to use SCSS modules to scope those styles to each RMWC component in the future. And @4cm4k1 I think the MWC version that @jamesmfriedman is using right now doesn't actually have the core-styles mixins.

FYI, support for importing global third-party CSS anywhere was just added on the canary release channel in Next.js. This may be useful to you. ๐Ÿ˜„

Sorry if the question is too simple but, could you show an example in practice. I am using the import into _app.js approach right now but would like to use RMWC in a better way. Thanks

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jordoh picture jordoh  ยท  3Comments

rboei picture rboei  ยท  4Comments

kctang picture kctang  ยท  7Comments

darrencruse picture darrencruse  ยท  6Comments

jamesmfriedman picture jamesmfriedman  ยท  6Comments