├── examples └── with-ant-design-less │ ├── assets │ └── antd-custom.less │ ├── .babelrc │ ├── package.json │ ├── README.md │ ├── next.config.js │ └── pages │ ├── index.less │ └── index.js ├── package.json ├── LICENSE ├── README.md ├── .gitignore └── index.js /examples/with-ant-design-less/assets/antd-custom.less: -------------------------------------------------------------------------------- 1 | @primary-color: #52c41a; 2 | 3 | @layout-header-height: 40px; 4 | @border-radius-base: 2px; 5 | -------------------------------------------------------------------------------- /examples/with-ant-design-less/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["next/babel"], 3 | "plugins": [ 4 | [ 5 | "import", { 6 | "libraryName": "antd", 7 | "style": true 8 | } 9 | ] 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /examples/with-ant-design-less/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "with-ant-design-less", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "dev": "next", 6 | "build": "next build", 7 | "start": "next start" 8 | }, 9 | "dependencies": { 10 | "antd": "^4.4.2", 11 | "less": "3.0.4", 12 | "less-vars-to-js": "1.3.0", 13 | "next": "latest", 14 | "next-plugin-antd": "^0.2.0", 15 | "react": "^16.7.0", 16 | "react-dom": "^16.7.0" 17 | }, 18 | "license": "MIT" 19 | } 20 | -------------------------------------------------------------------------------- /examples/with-ant-design-less/README.md: -------------------------------------------------------------------------------- 1 | # Ant Design with less and css module example 2 | 3 | This example shows how to use next-plugin-antd to build a Next.js project along with Ant Design, Less and CSS modules. 4 | 5 | ## How to use 6 | 7 | ### Using create-next-app 8 | 9 | Execute create-next-app with npm or Yarn to bootstrap the example: 10 | 11 | ```bash 12 | npm init next-app -e https://github.com/ye-will/next-plugin-antd/tree/master/examples/with-ant-design-less with-ant-design-less 13 | # or 14 | yarn create next-app -e https://github.com/ye-will/next-plugin-antd/tree/master/examples/with-ant-design-less with-ant-design-less 15 | ``` 16 | -------------------------------------------------------------------------------- /examples/with-ant-design-less/next.config.js: -------------------------------------------------------------------------------- 1 | const withPluginAntd = require("next-plugin-antd") 2 | const lessToJS = require('less-vars-to-js') 3 | const fs = require('fs') 4 | const path = require('path') 5 | 6 | // Where your antd-custom.less file lives 7 | const themeVariables = lessToJS( 8 | fs.readFileSync(path.resolve(__dirname, './assets/antd-custom.less'), 'utf8') 9 | ) 10 | 11 | module.exports = withPluginAntd({ 12 | // loading custom ant design theme vars 13 | antdThemeVariables: themeVariables, 14 | // any options for @zeit/next-less 15 | cssModules: true, 16 | cssLoaderOptions: { 17 | importLoaders: 1, 18 | localIdentName: "[local]___[hash:base64:5]", 19 | }, 20 | }) 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-plugin-antd", 3 | "version": "0.2.0", 4 | "main": "index.js", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/ye-will/next-plugin-antd.git" 8 | }, 9 | "license": "MIT", 10 | "files":[ 11 | "index.js", 12 | "LICENSE", 13 | "README.md" 14 | ], 15 | "bugs": { 16 | "url": "https://github.com/ye-will/next-plugin-antd/issues" 17 | }, 18 | "homepage": "https://github.com/ye-will/next-plugin-antd#readme", 19 | "dependencies": { 20 | "@zeit/next-less": "^1.0.1", 21 | "babel-plugin-import": "^1.13.0", 22 | "less-loader": "^6.0.0", 23 | "null-loader": "^4.0.0" 24 | }, 25 | "peerDependencies": { 26 | "less": "^3.11.1", 27 | "antd": "^4.0.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/with-ant-design-less/pages/index.less: -------------------------------------------------------------------------------- 1 | .container { 2 | min-height: 20vh; 3 | padding: 0 0.5rem; 4 | display: flex; 5 | flex-direction: column; 6 | justify-content: center; 7 | align-items: center; 8 | } 9 | 10 | .title a { 11 | color: #0070f3; 12 | text-decoration: none; 13 | } 14 | 15 | .title a:hover, 16 | .title a:focus, 17 | .title a:active { 18 | text-decoration: underline; 19 | } 20 | 21 | .title { 22 | margin: 0; 23 | line-height: 1.15; 24 | font-size: 4rem; 25 | } 26 | 27 | .title, 28 | .description { 29 | text-align: center; 30 | } 31 | 32 | .description { 33 | line-height: 1.5; 34 | font-size: 1.5rem; 35 | } 36 | 37 | @media (max-width: 600px) { 38 | .grid { 39 | width: 100%; 40 | flex-direction: column; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Will Ye 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Next.js & Ant Design (& Less) Made Easy 2 | 3 | A [@zeit/next-less][next-less] patch with full support for Ant Design, Less and CSS modules 4 | 5 | ## Version compatibility 6 | 7 | - for `antd: <4.0.0`, use `next-plugin-antd: ~0.1.3` 8 | - for `antd: >=4.0.0`, use `next-plugin-antd: ^0.2.0` 9 | 10 | ## `create-next-app` example 11 | 12 | ```bash 13 | npm init next-app -e https://github.com/ye-will/next-plugin-antd/tree/master/examples/with-ant-design-less with-ant-design-less 14 | ``` 15 | 16 | or 17 | 18 | ``` 19 | yarn create next-app -e https://github.com/ye-will/next-plugin-antd/tree/master/examples/with-ant-design-less with-ant-design-less 20 | ``` 21 | 22 | ## Installation 23 | 24 | ```bash 25 | npm install --save next-plugin-antd less antd 26 | ``` 27 | 28 | ## Configuring 29 | 30 | Create/Edit `next.config.js` in your project 31 | 32 | ```javascript 33 | // next.config.js 34 | const withPluginAntd = require("next-plugin-antd") 35 | module.exports = withPluginAntd({ 36 | /* config options here */ 37 | }) 38 | ``` 39 | 40 | Add a `.babelrc` 41 | 42 | ```json 43 | { 44 | "presets": ["next/babel"], 45 | "plugins": [ 46 | [ 47 | "import", { 48 | "libraryName": "antd", 49 | "style": true 50 | } 51 | ] 52 | ] 53 | } 54 | ``` 55 | 56 | Congratulations 🎉🎉🎉 57 | 58 | ### Options 59 | 60 | `antdThemeVariables`: [less-vars-to-js](https://github.com/michaeltaranto/less-vars-to-js) config to customize ant design theme 61 | 62 | All @zeit/next-less [options][next-less] are supported, such as `cssModules`, `cssLoaderOptions`, `lessLoaderOptions`, `postcssLoaderOptions` 63 | 64 | [next-less]: https://github.com/zeit/next-plugins/tree/master/packages/next-less 65 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | 106 | package-lock.json 107 | -------------------------------------------------------------------------------- /examples/with-ant-design-less/pages/index.js: -------------------------------------------------------------------------------- 1 | import { Fragment } from 'react' 2 | import Head from 'next/head' 3 | import { 4 | Form, 5 | Select, 6 | InputNumber, 7 | DatePicker, 8 | Switch, 9 | Slider, 10 | Button, 11 | } from 'antd' 12 | 13 | import css from './index.less' 14 | 15 | const FormItem = Form.Item 16 | const Option = Select.Option 17 | 18 | export default () => ( 19 | 20 | 21 | Create Next App 22 | 23 | 24 |
25 |

26 | Welcome to Next.js! & Ant Design 27 |

28 |
29 |

30 | Get started by editing pages/index.js 31 |

32 |
33 |
34 |
35 | 40 | 48 | Link 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 73 | 74 | 75 | 80 | 81 | 82 | 83 | 86 | 89 | 90 |
91 |
92 | ) 93 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const cssLoaderConfig = require('@zeit/next-css/css-loader-config') 2 | const withLess = require('@zeit/next-less') 3 | const MiniCssExtractPlugin = require('mini-css-extract-plugin') 4 | 5 | module.exports = (nextConfig = {}) => { 6 | return Object.assign({}, nextConfig, { 7 | webpack(config, options) { 8 | const lessConfig = withLess({ ...nextConfig, webpack: undefined }).webpack(config, options) 9 | const { dev, isServer } = options 10 | // prevent Node.js loading less files in SSR mode 11 | if (isServer) { 12 | const antStyles = /antd\/.*?\/style.*?/ 13 | const origExternals = [...lessConfig.externals] 14 | lessConfig.externals = [ 15 | (context, request, callback) => { 16 | if (request.match(antStyles)) return callback() 17 | if (typeof origExternals[0] === 'function') { 18 | origExternals[0](context, request, callback) 19 | } else { 20 | callback() 21 | } 22 | }, 23 | ...(typeof origExternals[0] === 'function' ? [] : origExternals), 24 | ] 25 | lessConfig.module.rules.unshift({ 26 | test: antStyles, 27 | use: 'null-loader', 28 | }) 29 | } 30 | // hack MiniCssExtractPlugin to mute `Conflicting order...` 31 | // https://github.com/webpack-contrib/mini-css-extract-plugin/issues/250 32 | // TO BE OPTIMIZED 33 | for (let i = 0; i < lessConfig.plugins.length; i++) { 34 | const p = config.plugins[i] 35 | if (p.constructor && p.constructor.name === MiniCssExtractPlugin.name) { 36 | config.plugins[i] = new MiniCssExtractPlugin({ 37 | ...p.options, 38 | ignoreOrder: true 39 | }) 40 | break 41 | } 42 | } 43 | // hack the next-less, exclude ant design less filess 44 | const lessConf = { 45 | exclude: /node_modules\/antd/, 46 | ...lessConfig.module.rules.pop() 47 | } 48 | lessConfig.module.rules.push(lessConf) 49 | // load ant design less files 50 | lessConfig.module.rules.push({ 51 | test: /\.less$/, 52 | include: /node_modules\/antd/, 53 | use: cssLoaderConfig(lessConfig, { 54 | extensions: ['less'], 55 | cssModules: false, 56 | cssLoaderOptions: {}, 57 | dev, 58 | isServer, 59 | loaders: [ 60 | { 61 | loader: 'less-loader', 62 | options: { 63 | lessOptions: { 64 | javascriptEnabled: true, 65 | modifyVars: nextConfig.antdThemeVariables 66 | } 67 | } 68 | } 69 | ] 70 | }) 71 | }) 72 | if (typeof nextConfig.webpack === 'function') { 73 | return nextConfig.webpack(config, options) 74 | } 75 | return lessConfig 76 | } 77 | }) 78 | } 79 | --------------------------------------------------------------------------------