Open just-boris opened 2 years ago
🚨 Bumping up this bug 🐛
As far as I know, Next doesn't handle any internal dependency stylesheet imports regardless if they're global or local.
In this case, the stylesheet naming convention that cloudscape-design is using ([name].scoped.css
) is not common, which is why Next assumes it's global CSS -- a more common use case of local CSS would be [name].module.css
, which Next adopted from the Create React App. The reason Next decided not to support any dependency stylesheets is that they couldn't guarantee their import order: If you have a component-level stylesheet that overrides a 3rd party stylesheet, their order couldn't be consistently determined; therefore, you'd end up with inconsistent styles per page and per page load. Instead, they recommend package maintainers separate their stylesheets imports so that developers can import them within the _app.js/component file, which allows the developer to set stylesheet import hierarchy (guaranteeing stylesheet overrides).
Stylesheets aside, the larger roadblock that you're running into is that @cloudscape-design/components
ships esmodules (ESM). Therefore, you won't be able to use server-side rendering for these components -- on the server, it tries to require
the JavaScript dependency which uses the import
/export
syntax. Node doesn't support a commonjs (CJS) file that require
s an ESM file -- Node expects all CJS JavaScript files to adhere to the require(id)/module.exports syntax. That said, in an ESM Javascript file, you technically can import
a CJS JavaScript file! Unfortunately, Next v12.x.x support for ESM is still experimental.
What next-transpile-modules does to make it work is that it extends babel transpiling to node_module packages AND, by default, adds support for node_module stylesheet imports (which isn't recommended, as explained above). On that note, I believe TM is actually treating all of the [name].scoped.css
stylesheets as a global since it doesn't follow the [name].module.css
naming convention!
TLDR: Next currently doesn't support importing stylesheets nor ESM in node_modules
.
A little bit context on why [name].scoped.css
was chosen. Originally we started with .module.css
but quickly figured out that tools like CRA automatically pick it up and attempt to modify already scoped class names, breaking the styles. So, we changed the name to avoid side effects on the tools. The current setup works great across all tools, except next.js restriction.
As a request for Next.js team here would be to rephrase the error message, because it confuses users about actual content of our module. Saying something like "Arbitrary CSS cannot be imported from within node_modules" would be more accurate.
@jaywcjlove the plugin would remove the imported css ? if removed css, the component can not work correctly.
@zackshen Copy the css from the package and import into the project
Or directly import the css in the package in the project
+import "@uiw/react-markdown-preview/markdown.css";
import dynamic from "next/dynamic";
import { useState } from "react";
+ const MDEditor = dynamic(
+ () => import("@uiw/react-md-editor").then((mod) => mod.default),
+ { ssr: false }
+ );
@jaywcjlove your solution is helpful, but I has to modify top level business code and the user should known the implementation detail of the dependencies,finally the package next-transpile-modules
can resolve the css problem.
Hi @zackshen , i was also facing similar issue can you share what steps have you done to resolve this issue.
@chaitanya71998
example code in next.config.js
const withTM = require('next-transpile-modules')(['react-shadow-picker'])
module.exports = withTM(config)
in business code
import { ShadowPicker } from 'react-shadow-picker';
import styled from 'styled-components';
const StyledShadowPicker = styled(ShadowPicker)`
// bla bla bla
// custom style here
`
Thank you very much for the solution, it helped me a lot.
Verify canary release
Provide environment information
What browser are you using? (if relevant)
n/a
How are you deploying your application? (if relevant)
n/a
Describe the Bug
Our components library (https://github.com/cloudscape-design/components) exports scoped styles, but we still get the warning:
We use zero-config CSS scoping (e.g. the files published on npm are already scoped), but next.js still claims we are doing something wrong (do we?)
Expected Behavior
The project starts successfully with the default next config
Link to reproduction
https://github.com/just-boris/cloudscape-nextjs
To Reproduce
Currently
next.config.js
contains a workaround: https://github.com/just-boris/cloudscape-nextjs/blob/main/next.config.js#L8To reproduce the issue, you need to replace
module.exports = withTM(nextConfig);
withmodule.exports = nextConfig;