vercel / next.js

The React Framework
https://nextjs.org
MIT License
125.02k stars 26.71k forks source link

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

Closed poyiding closed 4 years ago

poyiding commented 4 years ago

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
    },
  }
pahaz commented 4 years ago

@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 commented 4 years ago

@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 commented 4 years ago

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

thiagoteles commented 4 years ago

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

Please, I want.

mit123suki commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

@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 commented 4 years ago

@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

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

judewang commented 4 years ago

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

mit123suki commented 4 years ago

@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 commented 4 years ago

@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 commented 4 years ago

@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 commented 4 years ago

@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 commented 4 years ago

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

RiatIO commented 4 years ago

> 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 commented 4 years ago

@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 commented 4 years ago

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 commented 4 years ago

@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 commented 4 years ago

@xedef which problem?

raindecastro commented 4 years ago

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:

Could anyone help me out?

mattcarlotta commented 4 years ago

@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 commented 4 years ago

@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 commented 3 years ago

i just use rsuite now

balazsorban44 commented 2 years ago

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.