【问题标题】:How to configure Next.js with Antd / Less and Sass / CSS modules如何使用 Antd / Less 和 Sass / CSS 模块配置 Next.js
【发布时间】:2020-07-29 02:56:16
【问题描述】:

我想将 Next.js 与 Sass 和 CSS 模块一起使用,但也想使用 Ant Design 并希望使用 Less 样式来缩小建筑尺寸。

我可以启用 CSS 模块或 Less 加载器,但不能同时启用两者。 Next.js 中的示例并没有帮助我解决这个问题。

【问题讨论】:

    标签: sass less next.js antd css-modules


    【解决方案1】:

    编辑:对于当前版本的 next.js,此答案肯定已经过时,请查看下面的其他答案。

    经过几个小时的研究,我终于找到了正确的解决方案并想分享它:

    .babelrc(这里没有魔法)

    {
      "presets": ["next/babel"],
      "plugins": [
        [
          "import",
          {
            "libraryName": "antd",
            "style": true
          }
        ]
      ]
    }
    

    next.config.js:

    /* eslint-disable */
    const withLess = require('@zeit/next-less');
    const withSass = require('@zeit/next-sass');
    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 = withSass({
      cssModules: true,
      ...withLess({
        lessLoaderOptions: {
          javascriptEnabled: true,
          modifyVars: themeVariables, // make your antd custom effective
          importLoaders: 0
        },
        cssLoaderOptions: {
          importLoaders: 3,
          localIdentName: '[local]___[hash:base64:5]'
        },
        webpack: (config, { isServer }) => {
          //Make Ant styles work with less
          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'
            });
          }
          return config;
        }
      })
    });
    

    关于如何编写withSasswithLess 使用以及将cssModules: true 放在外部对象中的最终提示来自这条评论here

    虽然我已经在尝试从之前的示例中派生出不同的组合: next+ant+less next+sass

    在这里完成我的package.json中的依赖项:

    ...
    "dependencies": {
        "@zeit/next-less": "^1.0.1",
        "@zeit/next-sass": "^1.0.1",
        "antd": "^4.1.3",
        "babel-plugin-import": "^1.13.0",
        "less": "^3.11.1",
        "less-vars-to-js": "^1.3.0",
        "next": "^9.3.4",
        "node-sass": "^4.13.1",
        "null-loader": "^3.0.0",
        "react": "^16.13.1",
        "react-dom": "^16.13.1",
        "sass": "^1.26.3"
      }
    ...
    

    我希望这可以帮助其他人更快地找到此解决方案。 :)

    【讨论】:

    • 我们可以使用“sass”代替“@zeit/next-sass”。我想使用 NextJs 9.3 自带的内置 sass 支持,也少用 antd。当我们在 webpack 配置中使用外部 css 加载器时,内置的 sass 支持被禁用。
    • 我试过但没有找到解决方案。如果你找到了,请告诉我/张贴。
    • 终于找到了我需要的解决方案 - 也适用于我,非常感谢!
    • @Holly 是的,只需在 _app.js 中导入 scss 并在其中编写全局样式::global{ ... }
    • @JustTB,我已经在我的项目中尝试过您的配置,但 CSS 模块 功能不起作用。 [Next.js 支持使用 [name].module.css 文件命名约定的 CSS 模块](nextjs.org/docs/basic-features/built-in-css-support)。你对这个案子有什么建议吗?你能为我检查和纠正配置吗? Here is my test project。谢谢!
    【解决方案2】:

    @zeit/next-less 已弃用并禁用 Next 的内置 CSS 支持。它还使用了非常旧的lessless-loader 版本。

    我创建了一个包,通过复制 SASS 规则并将它们设置为 Less 文件和 less-loader,为 Next.js 注入了 Less 支持。它适用于webpack5 标志。

    https://github.com/elado/next-with-less

    https://www.npmjs.com/package/next-with-less

    【讨论】:

    • 感谢您的包裹。另一种选择是使用next-plugin-antd-less,但似乎在 21/04/2021 他们还不支持 webpack5。
    • 这就是我写我的包的主要原因(webpack5 支持)。此外,它维护 Next 的错误和文件加载器的确切行为。它也不是 Ant 特定的。
    • @elado 太棒了!您能否在自述文件中添加一个示例,在其中覆盖一些 antd 变量?我尝试将 lessVarsFilePath 添加到 next.config.js (就像我们需要为 next-plugin-antd-less 做的那样),但它没有效果。
    • 我为@elado 的插件创建了一个PR,用于添加自定义antd 变量的选项。我们会看看情况如何! :)
    • 此解决方案与 next.js 11.1.2 和节点 14 完美配合。
    【解决方案3】:

    虽然上述答案可能适用于低于 11 的 NextJS 版本,但它们不适用于 11+。我发现以下插件非常成功...

    https://github.com/SolidZORO/next-plugin-antd-less

    【讨论】:

      【解决方案4】:

      我正在使用 elado 的包,它是 - https://github.com/elado/next-with-less

      您将需要 lessless-loader 作为依赖项。 之后在styles 文件夹上创建一个global.less 文件。所以就像 ,root> style > global.less 并粘贴此代码

      @import '~antd/lib/style/themes/default.less';
      @import '~antd/dist/antd.less'; 
      @primary-color: #ff9b18; 
      @border-radius-base: 20px;
      

      并在您将在根文件夹中创建的next.config.js 文件中添加以下代码。

         // next.config.js
      const withLess = require("next-with-less");
      
      module.exports = withLess({
          lessLoaderOptions: {
              /* ... */
          },
      });
      

      【讨论】:

        【解决方案5】:

        在我们的项目中,有旧的 scss 和 css 文件。他们没有为 CSS 模块使用 Next js 指南。所以我不得不重写 webpack.config.js。所以效果很好。但是当我们将文件移动到 monorepo 共享包时,babel 并没有转译它们。我使用了下面的东西,但这些不适用于没有 .module 扩展名的 SCSS 模块。

        • 下一个转换模块。
        • 实验性:{ externalDir: true, } 在带有根 babel.cofig.json 的下一个 Js 配置中

        符号链接黑客终于对外部共享文件起作用了

        通过更新 next.config.js 为共享文件夹使用符号链接

        module.exports = {
          //...
          resolve: {
            symlinks: false,
          },
        };
        

        【讨论】:

          猜你喜欢
          • 2021-02-21
          • 1970-01-01
          • 2021-06-26
          • 2020-06-19
          • 2013-01-20
          • 1970-01-01
          • 2019-12-01
          • 1970-01-01
          • 2021-10-10
          相关资源
          最近更新 更多