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. #6

Open
JesperWe opened this issue May 2, 2021 · 11 comments
Open

Global CSS cannot be imported from within node_modules. #6

JesperWe opened this issue May 2, 2021 · 11 comments

Comments

@JesperWe
Copy link

JesperWe commented May 2, 2021

Hi!

Thanks for trying to contibute to solving the Next 10 / Webpack 5 / Ant Design mess ;-)

I am trying you solution, but ending up with

info  - Creating an optimized production build  
Failed to compile.

./node_modules/antd/lib/affix/style/index.less
Global CSS cannot be imported from within node_modules.
Read more: https://nextjs.org/docs/messages/css-npm
Location: node_modules/antd/lib/affix/style/index.js
...
Error: > Build failed because of webpack errors

This does not happen if I try to add the component to your example code.
I cannot quite figure what the difference is though.
Any tips?

@elado
Copy link
Owner

elado commented May 2, 2021

See #5

@JesperWe
Copy link
Author

JesperWe commented May 2, 2021

The solution is to import the .less files in your pages/_app instead of importing a JS file that imports them:

Not quite understanding this. You are saying that the normal way, like

import { Affix, Button, Col, Row } from "antd"

doesn't work, because it is importing a JS file that imports a Less file.

And that I need to import ALL less files of the components used across the app in _app.js to fix this?

Seems I am in for a bit of work... :-)

@elado
Copy link
Owner

elado commented May 2, 2021

Can you share some more code? I'll take a look later

@JesperWe
Copy link
Author

JesperWe commented May 2, 2021

Sure, I'll try to show the relevant pieces. The project is huge ;-)

next.config.js:

const lessToJS = require( 'less-vars-to-js' )
const fs = require( 'fs' )
const path = require( 'path' )
const withLess = require("next-with-less");
const MomentLocalesPlugin = require( 'moment-locales-webpack-plugin' )

// Where your antd-custom.less file lives
const theme = lessToJS(
	fs.readFileSync( path.resolve( __dirname, './antd-custom.less' ), 'utf8' )
)

const withBundleAnalyzer = require( '@next/bundle-analyzer' )( {
	enabled: process.env.ANALYZE === 'true',
} )

module.exports = withBundleAnalyzer( withLess( {
	lessLoaderOptions: {
		lessOptions: {
			javascriptEnabled: true,
			modifyVars: theme,
		}
	},
	productionBrowserSourceMaps: false,
	publicRuntimeConfig: { theme },
	webpack: ( config, { buildId, dev, isServer, defaultLoaders, webpack } ) => {
		config.resolve.modules.push( path.resolve( './' ) )

		config.plugins.push(
			new MomentLocalesPlugin( {
				localesToKeep: [ 'sv' ]
			} ) )

		return config
	},
	i18n: {
		locales: [ 'en', 'sv' ],
		defaultLocale: 'sv'
	},
	future: {
		webpack5: true
	}
} ) )

antd-custom.less just has a set of theme variable overrides:

@text-color: #151716;
@component-background: #fff;
.... etc

Then there is a root app.less file that gets imported to _app.js. This is the only Ant css related import in the .js components. For the rest of the app we just import the ant components as shown in my post above.

app.less imports the default theme, then our theme customization and then some overrides to the default theme that is not exposed through the Less variables:

app.less:

@import "node_modules/antd/lib/style/themes/default.less";
@import "antd-custom.less";
@import "antd-overrides.less";

... and then lots of ordinary global (non component specific) css/less ...

This setup has served us fine since Next 9.2 or so but since the Next team seems inclined to drop the ball on Less support I found your "let's mimic their Sass setup" approach interesting ;-)

@elado
Copy link
Owner

elado commented May 3, 2021

I'm not quite sure where it's coming from. Can you try converting

@import "node_modules/antd/lib/style/themes/default.less";

into

@import "~antd/lib/style/themes/default.less";

?

~ prefix is the common way of importing CSS with @import from node_modules.

If this still fails, try replicating the issue in the examples dir in a fork.

@akornato
Copy link

akornato commented May 4, 2021

@JesperWe removing .babelrc that I had from Next.js example fixed this for me.

@JesperWe
Copy link
Author

JesperWe commented May 4, 2021

Good catch @akornato !
I could not remove .babelrc completely since it uses other (non-Ant) stuff, but removing the Ant plugin made the above error go away.

build runs a bit longer with this....however it now fails at

info  - Creating an optimized production build  
Failed to compile.

./app.less

// https://github.com/ant-design/ant-motion/issues/44
.bezierEasingMixin();
^
Inline JavaScript is not enabled. Is it set in your options?
      in /...../node_modules/antd/lib/style/color/bezierEasing.less (line 110, column 0)
    at runMicrotasks (<anonymous>)

even though I can see in the source line 51 has javascriptEnabled: true,

@akornato
Copy link

akornato commented May 4, 2021

@JesperWe hmm not sure why, I no longer even have javascriptEnabled: true - my next.config.js is pretty much just as in this repo's example.

@JesperWe
Copy link
Author

JesperWe commented May 4, 2021

Yes, this plugin seems to always enable javascript but it somehow it is not working for me.
Maybe we are using components that you are not...

@joelbqz
Copy link

joelbqz commented May 10, 2021

@JesperWe removing .babelrc that I had from Next.js example fixed this for me.

This issue was happening to me as well, did what @JesperWe suggested and it worked! Thanks!

@jaywcjlove
Copy link

I created a nextjs package next-remove-imports to solve the problem.

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

// next.config.js
const removeImports = require("next-remove-imports")();

module.exports = removeImports({});
// pages/index.js

import Head from 'next/head'
import MDEditor from '@uiw/react-md-editor';
import "@uiw/react-md-editor/dist/markdown-editor.css";
import "@uiw/react-markdown-preview/dist/markdown.css";

export default function Home() {
  return (
    <div>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <MDEditor value="**Hello world!!!**" />
    </div>
  )
}

@JesperWe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants