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

"Global CSS cannot be imported from within node_modules." error in Next.js #4035

Closed
vishnupriyavr opened this issue May 2, 2021 · 27 comments
Labels
wontfix This will not be worked on

Comments

@vishnupriyavr
Copy link

While using NextJS with Patternfly, this error crops up :
"Global CSS cannot be imported from within node_modules." for About-Modal CSS file import

NextJS suggests to work with the library community (patternfly in this case) to work around this.

More info here : vercel/next.js#19936

Is there some woraround to make patternfly to work with NextJS (Note : I already tried out https://github.com/vercel/next.js/tree/canary/examples/with-patternfly without much success)

@mcoker
Copy link
Contributor

mcoker commented May 5, 2021

cc @redallen

@redallen
Copy link
Contributor

redallen commented May 6, 2021

There is currently no solution since Next.js dropped support for importing CSS in JS (virtually every other bundler does). Sorry!

@dgutride
Copy link
Member

Can we take another look at this @redallen?

@dgutride dgutride reopened this May 12, 2021
@redallen
Copy link
Contributor

redallen commented May 12, 2021

I've tried the following next.config.js file to no avail:

module.exports = {
  future: {
    webpack5: true
  },
  webpack(config, { isServer }) {
    // Remove existing css rule
    config.module.rules.pop();

    // SSR doesn't care about CSS
    const cssRule = {
      test: /\.css$/,
      //include: __dirname
    };
    if (isServer) {
      cssRule.use = require.resolve('null-loader')
    }
    else {
      cssRule.use = [
        MiniCssExtractPlugin.loader,
        require.resolve('css-loader')
      ];
      config.plugins.push(
        new MiniCssExtractPlugin()
      );
    }
    // Add our cssRule
    config.module.rules.push(cssRule);

    return config;
  }
}

It gives the following error:

./node_modules/@patternfly/react-styles/css/components/AboutModalBox/about-modal-box.css
ModuleParseError: Module parse failed: Unexpected character '' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)


> Build error occurred
Error: > Build failed because of webpack errors
    at /home/thesm/src/next-app/node_modules/next/dist/build/index.js:17:924
    at async Span.traceAsyncFn (/home/thesm/src/next-app/node_modules/next/dist/telemetry/trace/trace.js:6:584)

I believe Next.js is further modifying my config despite saying "Warning: Built-in CSS support is being disabled due to custom CSS configuration being detected."

I'll pursue this issue upstream.

@redallen
Copy link
Contributor

Oops, didn't mean to close. Sorry.

@redallen redallen reopened this May 12, 2021
@fabianishere
Copy link

I managed to get it to work using a patched version of next-transpile-modules in order to enable support for global CSS imports. See the following changes fabianishere/next-transpile-modules@5f61c10.

However, at this point, you are deep inside Next.js internals, so I wouldn't consider this an ideal solution. Let's hope this functionality can be integrated into Next.js.

@fabianishere
Copy link

@redallen Sorry if this is the incorrect place to ask, but is there a reason as to why patternfly-react uses Global CSS as opposed to CSS modules?

Although we might get Global CSS imports to work natively in Next.js at some point, it cannot benefit from treeshaking: https://github.com/vercel/next.js/blob/96f9945ecb24b3cdcce58e8fb6e4311e93b7a1d2/packages/next/build/webpack/config/blocks/css/index.ts#L190

@redallen
Copy link
Contributor

redallen commented May 19, 2021

CSS modules are preferable but:

  1. Didn't have good support when this library started
  2. Aren't supported by every bundler

The initial authors of this library quite liked the idea of import styles from './button.css'; <div className={styles.someClass} /> so we wrote @patternfly/react-styles to generate classNames from CSS files for better interoperability with our CSS authors working in @patternfly/patternfly.

As for tree shaking most components use all of their* provided classes so there isn't much to gain tree-shaking individual CSS files.

@wojta
Copy link
Member

wojta commented May 20, 2021

I managed to get it to work using a patched version of next-transpile-modules in order to enable support for global CSS imports. See the following changes fabianishere/next-transpile-modules@5f61c10.

@fabianishere Do you have a sample code of using it somewhere?

@fabianishere
Copy link

@wojta With the patched version of next-transpile-modules, you should only need the following configuration in next.config.js:

const withTM = require('next-transpile-modules')(['@patternfly/react-core', '@patternfly/react-styles'])

module.exports = withTM({
  future: {
    webpack5: true,
  },
});

I am working now with the author of that package to upstream these changes.

@wojta
Copy link
Member

wojta commented May 21, 2021

@fabianishere solution seems to be working. Thanks! It's necessary to add all modules that are used with PatternFly otherwise you'll get an error.

@fabianishere
Copy link

@wojta For if you haven't seen it yet, the changes have now been integrated into next-transpile-modules: https://github.com/martpie/next-transpile-modules/releases/tag/7.2.0

@ghost
Copy link

ghost commented May 21, 2021

@fabianishere, in my case the solution you provided does not work. As a result, I had no styles at all: my own and patternfly's.
There're no other errors.
Using webpack 4 / webpack 5 option in next.config.js changes nothing.

The issue appears on latest nextjs (10.2.2).

@fabianishere
Copy link

fabianishere commented May 21, 2021

@altwarg By no styles at all, do you mean the stylesheets are not loaded for the Patternfly component you are importing?

Does this happen in development or production mode?

@ghost
Copy link

ghost commented May 21, 2021

@fabianishere

By no styles at all, do you mean the stylesheets are not loaded for the Patternfly component you are importing?

After paying some attention I realized that all my styles are not being imported.

I have these styles according to NextJS css modules system:
image

But I had something like this:
image

Here is my package.json:

{
  "name": "hotel",
  "version": "0.5.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "@patternfly/react-core": "^4.121.3",
    "@patternfly/react-icons": "^4.10.8",
    "@patternfly/react-styles": "^4.10.8",
    "@patternfly/react-table": "^4.27.9",
    "axios": "^0.21.1",
    "effector": "^21.8.11",
    "effector-react": "^21.3.2",
    "js-cookie": "^2.2.1",
    "moment": "^2.29.1",
    "next": "10.2.2",
    "nprogress": "^0.2.0",
    "react": "17.0.2",
    "react-datasheet": "^1.4.9",
    "react-dom": "17.0.2",
    "react-multi-carousel": "^2.6.3",
    "react-pdf": "^5.3.0",
    "react-quill": "^1.3.5",
    "react-sortablejs": "^6.0.0",
    "sortablejs": "^1.13.0"
  },
  "devDependencies": {
    "@types/js-cookie": "^2.2.6",
    "@types/node": "15.6.0",
    "@types/nprogress": "^0.2.0",
    "@types/react": "17.0.6",
    "@types/react-dom": "^17.0.5",
    "@types/react-pdf": "^5.0.2",
    "@types/sortablejs": "^1.10.6",
    "next-transpile-modules": "7.2.0",
    "typescript": "^4.2.4"
  }
}

And my next.config.js:

const withTM = require('next-transpile-modules')([
  '@patternfly/react-core',
  '@patternfly/react-table',
  '@patternfly/react-icons',
  '@patternfly/react-styles',
]);

module.exports = withTM({
  future: {
    webpack5: true,
  },
});

Does this happen in development or production mode?

This happen in development (next dev) and production mode (next start after next build).

@fabianishere
Copy link

I cannot reproduce the issue. Could you check whether the following example works: https://github.com/fabianishere/next.js/tree/examples/patternfly-4/examples/with-patternfly

@ghost
Copy link

ghost commented May 22, 2021

@fabianishere, I checked this example from the examples/patternfly-4 branch and noticed the same thing. Custom styles don't work.

What I've done:

  1. I've added the property canJumpTo: false to every Wizard step:

image

This option sets that we can change the steps in the Wizard only when we click the Next or Back buttons. Otherwise we could click on the step itself to move to it.

  1. canJumpTo: false option causes to disable every step button (and they are looks gray). I want to set the same styles as for canJumpTo: true. In this case I created styles directory and index.module.css file with these styles:

image

  1. After importing the styles directly in index component I expect them to be applied but they are not:

image

No idea how to fix this.

@fabianishere
Copy link

This is because you are using CSS modules, which will transform the selectors to something different to prevent name clashes with global CSS.

To get this to work, you can do the following:

.customWizard :global(.pf-c-wizard__nav-link.pf-m-current:disabled)::before {
    background-color: rgb(0, 102, 204) !important;;
    color: rgb(255, 255, 255) !important;;
}

.customWizard :global(.pf-c-wizard__nav-link:disabled)::before {
    background-color: rgb(240, 240, 240) !important;
}

.customWizard :global(button.pf-c-wizard__nav-link.pf-m-current.pf-m-disabled) {
    color: rgb(0, 102, 204) !important;
}
import { customWizard } from './index.module.css'
import { useState } from 'react'
import { Button, Wizard } from '@patternfly/react-core'
import { CogIcon } from '@patternfly/react-icons'

const steps = [
  { name: 'Step 1', component: <p>Step 1</p>, canJumpTo: false },
  { name: 'Step 2', component: <p>Step 2</p>, canJumpTo: false },
  { name: 'Step 3', component: <p>Step 3</p>, canJumpTo: false },
  { name: 'Step 4', component: <p>Step 4</p>, canJumpTo: false },
  { name: 'Review', component: <p>Review Step</p>, nextButtonText: 'Finish', canJumpTo: false },
]

export default function Home() {
  const [isOpen, setIsOpen] = useState(false)
  return (
    <>
      <Button
        variant="primary"
        onClick={() => setIsOpen(true)}
        style={{ margin: 20 }}
        icon={<CogIcon />}
      >
        Show Wizard
      </Button>
      {isOpen && (
        <Wizard
          className={customWizard}
          isOpen={isOpen}
          onClose={() => setIsOpen(false)}
          title="Simple Wizard"
          description="Simple Wizard Description"
          steps={steps}
        />
      )}
    </>
  )
}

@ghost
Copy link

ghost commented May 22, 2021

@fabianishere, your approach can be applied to customize standard patternfly styles. But my own for my own components don't work as well.

@fabianishere
Copy link

There is another way to do it in Next.js at the moment: https://nextjs.org/docs/messages/css-global
I don't think it is an issue with the example or next-transpile-modules itself.

@ghost
Copy link

ghost commented May 26, 2021

@fabianishere, well, global css can be applied, but to be honest: I found no performance improvements or behavior differences using approach you mentioned vs the approach I mentioned in patternfly/patternfly-react#5756.

Node process still requires ~1-1.2 GB of RAM and from 30-40% of CPU usage to work in development (in production mode everything is fine). No idea how to deal with it but it is really annoying.

@fabianishere
Copy link

@altwarg Does this only happen once you start using next-transpile-modules? I haven't noticed a large difference in behavior between a stock Next.js application and one that uses next-transpile-modules myself.

Of course, some additional CPU/RAM usage is expected as it needs to transpile additional source files, but those results should be cached, so it should not happen on every re-render.

@ghost
Copy link

ghost commented May 26, 2021

@fabianishere, I've used next-transpile-modules (but older version) before so I believe that my comments are not so relevant.

Now I understand why does additional CPU/RAM usage is expected. Your approach is better and requires fewer packages to be installed. Thank you!

@jaywcjlove
Copy link

I created a nextjs package next-remove-imports to solve the problem. Best solution :) @fabianishere @altwarg

Example: https://codesandbox.io/s/nextjs-example-react-md-editor-qjhn7?file=/pages/index.js

@stale
Copy link

stale bot commented Jul 27, 2021

This issue has been automatically marked as stale because it has not had activity in the last 60 days. It will be closed in 30 days if no further activity occurs.

@stale stale bot added the wontfix This will not be worked on label Jul 27, 2021
@stale stale bot closed this as completed Aug 26, 2021
@snigdha920
Copy link

snigdha920 commented Dec 22, 2022

I'm also facing the "Global CSS cannot be imported from within node_modules." error in Next.js.

When I do,

const withTM = require('next-transpile-modules')([
  '@patternfly/react-core',
  '@patternfly/react-styles',
  '@patternfly/react-log-viewer',
]);

module.exports = withTM({});

I can render the component successfully, however no CSS styles are applied.

Any idea on how to fix this? I'm aware I can import global CSS from a package in the experimental app directory in Next JS (ref: vercel/next.js#27953 (comment)) but my team hasn't taken the decision to migrate to the experimental feature.

Happy to provide more details if needed, please let me know!

@snigdha920
Copy link

I'm also facing the "Global CSS cannot be imported from within node_modules." error in Next.js.

When I do,

const withTM = require('next-transpile-modules')([
  '@patternfly/react-core',
  '@patternfly/react-styles',
  '@patternfly/react-log-viewer',
]);

module.exports = withTM({});

I can render the component successfully, however no CSS styles are applied.

Any idea on how to fix this? I'm aware I can import global CSS from a package in the experimental app directory in Next JS (ref: vercel/next.js#27953 (comment)) but my team hasn't taken the decision to migrate to the experimental feature.

Happy to provide more details if needed, please let me know!

I was able to solve the issue by adding the following imports to my _app.tsx file. I'm using the LogViewer component hence I've imported the log viewer css along with the base css.

import '@patternfly/react-core/dist/styles/base.css';
import '@patternfly/react-styles/css/components/LogViewer/log-viewer.css';

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

8 participants