From 418ec5c7a57153af00cc7632fbbc21b5a8b1e7e9 Mon Sep 17 00:00:00 2001 From: Jason Feng Date: Sun, 4 Apr 2021 22:23:24 +0800 Subject: [PATCH] feat: supports both Next.js and CRA-Co --- README.md | 44 ++++++++++++++++++++++++++- overrideWebpackConfig.js | 66 +++++++++++++++++++++++++++------------- 2 files changed, 88 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index ca9f0e0..1381816 100755 --- a/README.md +++ b/README.md @@ -8,7 +8,14 @@ Use [Antd] (with Less) with [Next.js], Zero Dependency on other Next-Plugins. -📌 [Demo w/ Next.js v10](https://mkn.vercel.app/) +## Demo + +📌 [Demo 1 - w/ Next.js v10](https://mkn.vercel.app/) + +📌 [Demo 2 - w/ CRA-Co v4](https://mkr.vercel.app/) + +Yep! this plugin supports both Next.js and [CRA-Co] since v1.0. + ## Introduction @@ -50,6 +57,8 @@ yarn add next-plugin-antd-less ## Usage +### for Next.js + ```js // next.config.js const withAntdLess = require('next-plugin-antd-less'); @@ -70,6 +79,10 @@ module.exports = withAntdLess({ }); ``` +more code example see [here](https://github.com/SolidZORO/mkn/blob/master/next.config.js). + + + Add a `.babelrc.js` ```js @@ -80,6 +93,33 @@ module.exports = { }; ``` +Detailed config can be found in [`next.config.js`](https://github.com/SolidZORO/mkn/blob/master/next.config.js) file. + +### for CRA-Co + +```js +const cracoPluginLess = require('next-plugin-antd-less/overrideWebpackConfig'); + +module.exports = { + babel: cracoBabel, + plugins: [ + cracoPluginAnalyze, + { + plugin: cracoPluginLess, + options: { + modifyVars: { + '@THEME--DARK': 'theme-dark', + }, + lessVarsFilePath: './src/styles/variables.less', + }, + }, + ], +}; +``` + +Detailed config can be found in [`craco.config.js`](https://github.com/SolidZORO/mkr/blob/master/craco.config.js) file. + + ## Tips - If you need to import the global CSS (e.g. styles.css), you can write @@ -108,6 +148,8 @@ require('./styles.less'); [Antd]: https://github.com/ant-design/ant-design/ +[CRA-Co]: https://github.com/gsoft-inc/craco + [mit-img]: https://img.shields.io/badge/License-MIT-blue.svg diff --git a/overrideWebpackConfig.js b/overrideWebpackConfig.js index 3817029..f5e84aa 100644 --- a/overrideWebpackConfig.js +++ b/overrideWebpackConfig.js @@ -1,31 +1,34 @@ /* eslint-disable no-param-reassign, consistent-return, no-restricted-syntax */ const clone = require('clone'); const fs = require('fs'); -const lessToJS = require('less-vars-to-js'); +const path = require('path'); // fix: prevents error when .less files are required by node if (typeof require !== 'undefined') require.extensions['.less'] = () => { }; -// function overrideWebpackConfig(webpackConfig, nextConfig, pluginOptions) { -function overrideWebpackConfig({ webpackConfig, nextConfig, pluginOptions }) { - const lessVarsByFile = pluginOptions.lessVarsFilePath - ? lessToJS(fs.readFileSync(pluginOptions.lessVarsFilePath, 'utf8')) - : {}; +function checkNextJs(webpackConfig) { + return Boolean(webpackConfig.resolveLoader && webpackConfig.resolveLoader.alias && webpackConfig.resolveLoaderalias['next-babel-loader']); +} - const modifyVars = { - ...lessVarsByFile, - ...pluginOptions.modifyVars, - }; +function overrideWebpackConfig({ webpackConfig, nextConfig, pluginOptions }) { + const isNextJs = checkNextJs(webpackConfig); - if (nextConfig && !nextConfig.defaultLoaders) { + if (isNextJs && !nextConfig.defaultLoaders) { throw new Error( // eslint-disable-next-line max-len 'This plugin is not compatible with Next.js versions below 5.0.0 https://err.sh/next-plugins/upgrade', ); } - const { dev } = nextConfig; + let dev; + + if (isNextJs) { + dev = nextConfig.dev; + } else { + dev = webpackConfig.mode !== 'production'; + } + const { rules } = webpackConfig.module; // compatible w/ webpack 4 and 5 @@ -52,13 +55,31 @@ function overrideWebpackConfig({ webpackConfig, nextConfig, pluginOptions }) { const lessModuleIndex = lessModule.use.findIndex((item) => `${item.loader}`.includes('sass-loader'), ); + lessModule.use.splice(lessModuleIndex, 1, { // https://github.com/webpack-contrib/less-loader#options loader: 'less-loader', options: { lessOptions: { javascriptEnabled: true, - modifyVars, + // + // Tips: Read the CONSTANTS e.g. `{ '@THEME--DARK': 'theme-dark' }` + // Hot Reload is **NOT Supported** + // but is useful for some constant constants + modifyVars: pluginOptions.modifyVars, + }, + // + // Tips: Read the variables e.g. `./styles/antd.less` + // Hot Reload is **Supported** + // but some var are not supported, e.g. `:global(.@{THEME--DARK})` + additionalData: (content) => { + const lessVarsFile = path.resolve(pluginOptions.lessVarsFilePath); + + if (fs.existsSync(lessVarsFile)) { + return `@import '${lessVarsFile}'; \n ${content}`; + } + + return content; }, ...pluginOptions.lessLoaderOptions, }, @@ -113,8 +134,8 @@ function overrideWebpackConfig({ webpackConfig, nextConfig, pluginOptions }) { rule.oneOf.splice(sassModuleIndex, 0, lessModule); webpackConfig.module.rules[ruleIndex] = rule; - // ONLY for next.js server - if (nextConfig) { + // ONLY for next.js + if (isNextJs) { webpackConfig = handleAntdInServer(webpackConfig, nextConfig); if (typeof pluginOptions.webpack === 'function') @@ -124,13 +145,13 @@ function overrideWebpackConfig({ webpackConfig, nextConfig, pluginOptions }) { return webpackConfig; } -function handleAntdInServer(config, options) { - if (!options.isServer) return config; +function handleAntdInServer(webpackConfig, nextConfig) { + if (!nextConfig.isServer) return webpackConfig; const ANTD_STYLE_REGX = /antd\/.*?\/style.*?/; - const rawExternals = [...config.externals]; + const rawExternals = [...webpackConfig.externals]; - config.externals = [ + webpackConfig.externals = [ (context, request, callback) => { if (request.match(ANTD_STYLE_REGX)) return callback(); @@ -141,9 +162,12 @@ function handleAntdInServer(config, options) { ...(typeof rawExternals[0] === 'function' ? [] : rawExternals), ]; - config.module.rules.unshift({ test: ANTD_STYLE_REGX, use: 'null-loader' }); + webpackConfig.module.rules.unshift({ + test: ANTD_STYLE_REGX, + use: 'null-loader' + }); - return config; + return webpackConfig; } module.exports = {