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

Update Ant Design Examples for New CSS Support (9.2) #9830

Closed
poyiding opened this issue Dec 26, 2019 · 74 comments · Fixed by #11837
Closed

Update Ant Design Examples for New CSS Support (9.2) #9830

poyiding opened this issue Dec 26, 2019 · 74 comments · Fixed by #11837
Labels
good first issue Easy to fix issues, good for newcomers

Comments

@poyiding
Copy link

poyiding commented Dec 26, 2019

import ant-design library throw error

can you provide an example import ant-design use [RFC] css support? thanks.
when i use [RFC] css support and import ant-design library, it throw error :

./node_modules/antd/lib/button/style/index.css
Global CSS cannot be imported from files other than your Custom <App>. Please move all global CSS imports to pages/_app.js.

here is my next-config.js

module.exports = {
    experimental: {
      css: true
    },
  }
@yufengwang
Copy link
Contributor

Maybe not support css from node_modules, I guess.

@poyiding
Copy link
Author

Maybe not support css from node_modules, I guess.

if you don't use [RFC] css support , you can support css from node_modules with-css plugin.

@timneutkens
Copy link
Member

Linking to #8626

@kachkaev
Copy link
Contributor

kachkaev commented Dec 26, 2019

I’d be also interested in seeing this. Our teams use antd with next-css/next-less and some hacks on top from the Next.js examples folder. That setup is quite clumsy and fragile. I’m looking forward to switching to the build-in css support, but have no clue how to deal with less in this case.

antd is a pretty popular ui framework, so I guess quite a lot of devs will benefit from a new example.

@stephankaag
Copy link

stephankaag commented Jan 20, 2020

Has anyone got ant-design working with Next 9.2 yet? (without @zeit/next-css)

@jonahfang
Copy link

@stephankaag, I have used withLess to use antd v4.0.0.rc1, it works!

@ChuckJonas
Copy link

I'm still seeing issues with antd 4.0.

Configuration is similar to [https://levelup.gitconnected.com/lets-create-a-project-with-nextjs-antd-and-deploy-with-now-sh-e38772348312|this guide]

@stephankaag
Copy link

stephankaag commented Jan 24, 2020

@stephankaag, I have used withLess to use antd v4.0.0.rc1, it works!

Of course, because that combination always worked. I am trying to make things work WITHOUT @zeit/next-css or @zeit/next-less.

@dpyzo0o
Copy link

dpyzo0o commented Feb 4, 2020

Anyone has successfully integrated next 9.2 with ant design? (without next-css plugin)

@chemicalkosek
Copy link
Contributor

@stephankaag The combination works very well (I'm using withCss combined with withLess and custom less variables), but how is your bundle size?
I have migrated to antd4. Seems like the tree shaking doesn't work as expected from v4. I'm having more than 1,3mb bundle size, where most of it are the antd icons.
According to this umijs/babel-plugin-import#402 the "libraryDirectory": "es" is necessary (the official with-ant-less example doesn't have it).
But adding this gives me the following error:

[ error ] /home/maciek/Dokumenty/websites/bookingapp/frontend/node_modules/antd/es/notification/index.js:3
import * as React from 'react';
       ^

SyntaxError: Unexpected token *
    at Module._compile (internal/modules/cjs/loader.js:723:23)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at Object.antd/es/notification (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:10975:18)
    at __webpack_require__ (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:23:31)
    at Module../lib/withData.js (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:8200:78)
    at __webpack_require__ (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:23:31)
    at Module../pages/_app.js (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:10614:71)
    at __webpack_require__ (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:23:31)
    at Object.0 (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:10754:18)
    at __webpack_require__ (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:23:31)
    at /home/maciek/Dokument

@DuncanAForbes
Copy link

@stephankaag The combination works very well (I'm using withCss combined with withLess and custom less variables), but how is your bundle size?
I have migrated to antd4. Seems like the tree shaking doesn't work as expected from v4. I'm having more than 1,3mb bundle size, where most of it are the antd icons.
According to this ant-design/babel-plugin-import#402 the "libraryDirectory": "es" is necessary (the official with-ant-less example doesn't have it).
But adding this gives me the following error:

[ error ] /home/maciek/Dokumenty/websites/bookingapp/frontend/node_modules/antd/es/notification/index.js:3
import * as React from 'react';
       ^

SyntaxError: Unexpected token *
    at Module._compile (internal/modules/cjs/loader.js:723:23)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at Object.antd/es/notification (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:10975:18)
    at __webpack_require__ (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:23:31)
    at Module../lib/withData.js (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:8200:78)
    at __webpack_require__ (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:23:31)
    at Module../pages/_app.js (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:10614:71)
    at __webpack_require__ (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:23:31)
    at Object.0 (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:10754:18)
    at __webpack_require__ (/home/maciek/Dokumenty/websites/bookingapp/frontend/.next/server/static/development/pages/_app.js:23:31)
    at /home/maciek/Dokument

@chemicalkosek did you manage to resolve this? I've been running into the exact same issue on Nextjs 9.2.1

@jeromemmiranda
Copy link

Anyone manage to resolve this issue?

@gjvpaet
Copy link

gjvpaet commented Feb 6, 2020

Any updates to this issue?

@i-tengfei
Copy link

My solution:

yarn add esm
"scripts": {
    "dev": "NODE_OPTIONS=\"-r esm\" next",
    "build": "NODE_OPTIONS=\"-r esm\" next build",
    "start": "NODE_OPTIONS=\"-r esm\" next start"
}

@chemicalkosek
Copy link
Contributor

@i-tengfei Wow, it's working! Thank you very much!

@ChuckJonas
Copy link

@i-tengfei are you using the same configuration as the example?

If not, mind posting your next.config & babelrc?

@chemicalkosek
Copy link
Contributor

chemicalkosek commented Feb 12, 2020

Btw I'm not using the new CSS support. What's working is next with antd4 tree shaked (tree shaking never worked with antd in the official example, because of the lack of "libraryDirectory":"es"). Bundle size cut about 700-800kb I believe. I'm still using withCss and withLess tho.

@mattcarlotta
Copy link
Contributor

@sebas-deedee There isn't any way forward until next supports loading CSS from node_modules
and that likely won't be supported because it currently may result in unordered CSS imports -- for example, loading an overrides.css file first, then a node_module/antd/component/style.css second -- which results in an inconsistent UI/UX. Until then, you have two options:

Option 1.) Use a custom babel and next configuration to load CSS from node_modules/antd/lib or from node_modules/antd/es folders on the client. The advantage is that you'll only import what's needed. The disadvantage is that you have to very granular in your imports. Meaning, you have to manually import the styles required for each component because on the initial page load, the server will not handle the CSS imports; therefore, the CSS must be imported inside the _app.js file. For example:

in your _app.js file:

import "antd/(lib|es)/radio/style/css.js" // antd component css
import "antd/(lib|es)/table/style/css.js" // antd component css
...etc
import "../styles/globals.css" // global css
import "../styles/overrides.css" // overrides css

and in a page or component file

import { Radio, Table } from "antd" // this will pick from "ant/lib" or "ant/es"

The result is that the style imports are consistently loaded in order by their import position and your production build is smaller because you're cherry-picking the components and CSS.

or

Option 2.) Copy/paste the entire ant.min.css from the node_modules/dist/ant.min.css into a global.css file. Then import that file into an _app.js file. The advantage is that you don't need a custom next config to import from node_modules; however, you'll still need to import the entire ant-design CSS library. Therefore, the disadvantage is that your production build will have a rather large CSS file that will only be utilized by whatever components you've imported -- the rest will just be dead-weight CSS.

in your _app.js file:

import "../styles/globals.css" // antd.min.css (global) css
import "../styles/overrides.css" // overrides css

and in a page or component file

import { Table } from "antd"

The result is that the style imports are consistently loaded in order by their import position, but the production build is larger because of the unutilized CSS.


Neither option is particularly developer-friendly/zero-config, as such, I'd hesitate to pull this into the official with-ant-design example.

That said, here's a working example of both options above utilizing next: ^9.3.5 with antd: ^4.1.4:
1.) Clone the example: git@github.com:mattcarlotta/next-antd-v4.git
2.) Install dependencies: yarn
3.) Run the first option by running: yarn dev
4.) Once done, terminate the process and type: git checkout globals
5.) Run the second option by running: yarn dev

@pahaz
Copy link

pahaz commented Apr 24, 2020

In my opinion, one of the best way to use antd with @ant-design/pro-layout is just to rename all your .css files to .less. LESS is backward compatible with CSS. In this way, you don't need to hack your babel config. It's an easy and less hackable way.

If you need NextJS + antd + @ant-design/pro-layout example, you can check this: https://github.com/8iq/nodejs-hackathon-boilerplate-starter-kit/tree/master/apps/_example04antpro (but, you should use .less extension for your .css files)

@mattcarlotta
Copy link
Contributor

@pahaz Your example fails to build for production.

@pahaz
Copy link

pahaz commented Apr 24, 2020

@mattcarlotta could you please explain your setup.
I've added CI action to test the build. CI test for node v10 and node v12
https://github.com/8iq/nodejs-hackathon-boilerplate-starter-kit/runs/615670863

@mattcarlotta
Copy link
Contributor

@pahaz Apologies, it was an user error. While this approach works, unfortunately, it's not very flexible for pre-existing projects using Sass. That said, encouraging developers to adopt less over css imports is just another workaround to the original problem: not being able to import CSS from node_modules.

On that note, there is the official with-ant-design-less example that accomplishes a similar result to your example.

Perhaps you may want to submit an example to Vercel that utilizes the @ant-design/pro-layout package.

@pahaz
Copy link

pahaz commented Apr 24, 2020

If anyone from Vercel interested in the example I'll create a PR.

@thiagoteles
Copy link

If anyone from Vercel interested in the example I'll create a PR.

Please, I want.

@mit123suki
Copy link
Contributor

mit123suki commented Apr 26, 2020

In my opinion, one of the best way to use antd with @ant-design/pro-layout is just to rename all your .css files to .less. LESS is backward compatible with CSS. In this way, you don't need to hack your babel config. It's an easy and less hackable way.

If you need NextJS + antd + @ant-design/pro-layout example, you can check this: https://github.com/8iq/nodejs-hackathon-boilerplate-starter-kit/tree/master/apps/_example04antpro (but, you should use .less extension for your .css files)

If you use less for everything it modifies the global styles for same class names, so to avoid that you can enable css modules and write css files.

I've prepared the repo for less here, https://github.com/mit123suki/next-ant-less.git

@mit123suki
Copy link
Contributor

For anyone who's still interested, checkout the following repos

Next with Ant-LESS
https://github.com/mit123suki/next-ant-less

Next with Ant-CSS
https://github.com/mit123suki/next-ant-css

@pahaz
Copy link

pahaz commented Apr 26, 2020

@mit123suki Coul you please explain, what the difference between your example and official examples?

https://github.com/zeit/next.js/tree/canary/examples/with-ant-design-less -- less
https://github.com/zeit/next.js/tree/canary/examples/with-ant-design -- css

@mit123suki
Copy link
Contributor

@mit123suki Coul you please explain, what the difference between your example and official examples?

https://github.com/zeit/next.js/tree/canary/examples/with-ant-design-less -- less
https://github.com/zeit/next.js/tree/canary/examples/with-ant-design -- css

  • Tree shaking using esm,
  • granular imports using babel-plugin-import
  • Ant locales replacement, when using Date-Picker using dayjs plugin reducing antd bundle furthur
  • Enabled local modules with overloaded cssvars.css file so the variables are directly available in css modules.

Overall it leads to reduction in app bundle size and styles are loaded correctly. You can do yarn analyze and compare the results.

@judewang
Copy link

judewang commented Apr 27, 2020

@mit123suki Does this line import all styles? Tree shaking using esm only for javascripts?

@mit123suki
Copy link
Contributor

@mit123suki Does this line import all styles? Tree shaking using esm only for javascripts?

you could remove that line and change the babelrc import antd style to true. It works the same except we now have a conflict order b/w component styles

yes only for javascript files, you can go for purgecss but that's breaking styles

@2huBrulee
Copy link

@mit123suki Coul you please explain, what the difference between your example and official examples?
https://github.com/zeit/next.js/tree/canary/examples/with-ant-design-less -- less
https://github.com/zeit/next.js/tree/canary/examples/with-ant-design -- css

  • Tree shaking using esm,
  • granular imports using babel-plugin-import
  • Ant locales replacement, when using Date-Picker using dayjs plugin reducing antd bundle furthur
  • Enabled local modules with overloaded cssvars.css file so the variables are directly available in css modules.

Overall it leads to reduction in app bundle size and styles are loaded correctly. You can do yarn analyze and compare the results.

Can't build from your less repo. It gaves me the following error:
10:16:18.845 import { Row } from '../grid'; 10:16:18.845 ^^^^^^ 10:16:18.845 SyntaxError: Cannot use import statement outside a module

@mit123suki
Copy link
Contributor

mit123suki commented Apr 30, 2020

@2huBrulee i forgot add to esm to start script. Pull the latest code. That should fix the error, if not file an issue. Thanks

@2huBrulee
Copy link

@2huBrulee which repo is that? " import { Row } from '../grid';" -what is this? Is it antd library? If so, it should be import { Row } from 'antd'. Check my github for my repos.

From your 'less' repo, i did:
yarn
yarn build

And got that error

@kachkaev
Copy link
Contributor

kachkaev commented May 2, 2020

@Timer, #11837 seems to be using css and not less. This issue is probably broader.

@RiatIO
Copy link

RiatIO commented May 10, 2020

> For anyone who's still interested, checkout the following repos

Next with Ant-LESS
https://github.com/mit123suki/next-ant-less

Next with Ant-CSS
https://github.com/mit123suki/next-ant-css

@mit123suki Hey, this works perfectly at localhost, thanks! But when I try to deploy it to Vercent i get the following error message:

16:47:15.971
Using external babel configuration
16:47:15.971
Location: "/zeit/68a93b6e/.babelrc"
16:47:33.622
Failed to compile.
16:47:33.623
./pages/signin.js
16:47:33.623
Module not found: Can't resolve '../components/Signin' in '/zeit/68a93b6e/pages'
16:47:33.623
Build error occurred
16:47:33.623
Error: > Build failed because of webpack errors
16:47:33.623
at build (/zeit/68a93b6e/node_modules/next/dist/build/index.js:13:900)
16:47:33.733
error Command failed with exit code 1.
16:47:33.733
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
16:47:33.743
Error: Command "yarn run build" exited with 1
16:47:35.695
Done with "package.json"

Edit:
@mit123suki Thanks for response. Yeah, bad of me. I noticed that I had typos in the import. Weird that it worked on localhost.

@mit123suki
Copy link
Contributor

mit123suki commented May 10, 2020

@RiatIO please open an issue at my repo. Btw I updated the repos recently. So pull the latest code if you haven't already and see if the issue still occurs. Thanks. For anyone who is having problems with the repos, please file an issue there, not here please. Keep this thread clean, Thanks.

@mcyleung
Copy link

My solution:

yarn add esm
"scripts": {
    "dev": "NODE_OPTIONS=\"-r esm\" next",
    "build": "NODE_OPTIONS=\"-r esm\" next build",
    "start": "NODE_OPTIONS=\"-r esm\" next start"
}

this works!!

@xedef
Copy link

xedef commented May 20, 2020

@mcyleung mind sharing your config?
I'm using with-ant-design-less example config and @i-tengfei solution but I still have the same problem

@chemicalkosek
Copy link
Contributor

@xedef which problem?

@raindecastro
Copy link

raindecastro commented May 31, 2020

I've tried the https://github.com/vercel/next.js/tree/canary/examples/with-ant-design-less as a boilerplate and pushed it to Heroku. I got some pretty low Lighthouse scores and two of the recommended solutions were pretty much leading to the CSS.

Recommended solutions:

  • Removed Unused CSS (which i think comes from the fact that the whole CSS of antd was imported)
  • Minify CSS (Here's what i'm unsure about)

Could anyone help me out?

@mattcarlotta
Copy link
Contributor

mattcarlotta commented May 31, 2020

@raindecastro Ant-design works by importing all necessary CSS when importing the component. Therefore, if you pass in an option that alters its appearance -- like adding the mode="multiple" option to Select -- then the CSS will already be included. Unfortunately, this has the sideEffect of importing other CSS that may not be in use.

The larger problem is that ant-design isn't a small library (48.3 MB unpacked and about 1.5MB+ packed) and with it are a lot of dependencies. Therefore, lower lighthouse scores are kind of expected when using it. This is one of the main reasons why I've slowly migrated away from ant-design to either directly using their react component (rc) dependencies or more recently designing my own UI components.


Take a look at these chunk graphs of with-ant-design-less out-of-the-box:
Ant-design makes up 2.13MB of 3.11MB (parsed)


However... there are two things you can do to reduce the bundle size:

1.) Remove moment locales:
config.plugins.push(new IgnorePlugin(/^\.\/locale$/, /moment$/));

2.) Only export icons from @ant-design/icons/dist that you need:

config.resolve.alias = {
  ...config.resolve.alias,
  "@ant-design/icons/lib/dist$": path.resolve(`./icons/index.js`),
};

icons/index.js (if you import other components that require icons, then they'll need to be manually added to this file)

/**
 * Exports only required ant-design icons (otherwise the entire 500kb library is included)
 *
 */
export { default as CalendarOutline } from "@ant-design/icons/lib/outline/CalendarOutline";
export { default as CloseCircleFill } from "@ant-design/icons/lib/fill/CloseCircleFill";
export { default as DownOutline } from "@ant-design/icons/lib/outline/DownOutline";
export { default as LeftOutline } from "@ant-design/icons/lib/outline/LeftOutline";
export { default as RightOutline } from "@ant-design/icons/lib/outline/RightOutline";

next.config.js

/* eslint-disable */
const { IgnorePlugin } = require("webpack");
const withLess = require("@zeit/next-less");
const lessToJS = require("less-vars-to-js");
const fs = require("fs");
const path = require("path");

// Where your antd-custom.less file lives
const themeVariables = lessToJS(
  fs.readFileSync(path.resolve(__dirname, "./assets/antd-custom.less"), "utf8")
);

module.exports = withLess({
  lessLoaderOptions: {
    javascriptEnabled: true,
    modifyVars: themeVariables, // make your antd custom effective
  },
  webpack: (config, { isServer }) => {
    if (isServer) {
      const antStyles = /antd\/.*?\/style.*?/;
      const origExternals = [...config.externals];
      config.externals = [
        (context, request, callback) => {
          if (request.match(antStyles)) return callback();
          if (typeof origExternals[0] === "function") {
            origExternals[0](context, request, callback);
          } else {
            callback();
          }
        },
        ...(typeof origExternals[0] === "function" ? [] : origExternals),
      ];

      config.module.rules.unshift({
        test: antStyles,
        use: "null-loader",
      });
    } else {
      /* aliases ant icon imports to user-defined icons folder */
      config.resolve.alias = {
        ...config.resolve.alias,
        "@ant-design/icons/lib/dist$": path.resolve(`./icons/index.js`),
      };
      /* strips out moment locales */
      config.plugins.push(new IgnorePlugin(/^\.\/locale$/, /moment$/));
    }
    return config;
  },
});

Take a look at these chunk graphs:
Ant-design still makes up 1.2MB of 2.11MB (parsed)

@raindecastro
Copy link

@mattcarlotta First of all, thank you! That was one of the most in-depth answers i've ever gotten from issues like this! With that being said, even though antd is one of my favourite component libraries, optimizations out of the box seem to be a pretty big downside. I'll first try out two of your recos to reduce bundle size then check out the performance scores from there hoping it would budge a little. Though if it still feels pretty slow, I guess it's time to look for another option. Do you mind if I send you an email? There's something I want to verify and I don't want to overuse this thread.

@coderdix
Copy link

coderdix commented Oct 30, 2020

i just use rsuite now

@Timer Timer removed this from the 10.x.x milestone Nov 16, 2020
@balazsorban44
Copy link
Member

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@vercel vercel locked as resolved and limited conversation to collaborators Jan 29, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
good first issue Easy to fix issues, good for newcomers
Projects
None yet
Development

Successfully merging a pull request may close this issue.