antd-theme-generator|antd-theme-generator 动态主题报错(没有对应文件 @{root-entry-name}.less)

最近在开发项目时,使用了最新的antd,发现在结合动态主题更换插件 antd-theme-generator 时提示报错:

Error: ENOENT: no such file or directory, open 'xxxxx/node_modules/antd/lib/style/themes/@{root-entry-name}.less'
查看Ant Design 官网也有给出更新的提示,在动态主题(实验性)
相关变更#
为了实现 CSS Variable 并保持原始用法兼容性,我们于 dist/antd.xxx.less 文件中添加了 @root-entry-name: xxx; 入口注入以支持 less 动态加载对应的 less 文件。一般情况下,你不需要关注该变化。但是,如果你的项目中直接引用了 lib|es 目录下的 less 文件。你需要在 less 入口处配置 @root-entry-name: default; (或者 @root-entry-name: variable; )以使 less 可以找到正确的入口。
此外,我们将 lib|es/style/minxins/index.less 中的 @import 'motion' 和 @import 'reset' 迁移至了 lib|es/style/themes/xxx.less 中,因为这两个文件依赖了主题相关变量。如果你使用了相关内部方法,请自行调整。当然,我们还是建议直接使用 dist 目录下的 antd.less 文件而非调用内部文件,因为它们经常会受重构影响。
因为在没有更新到最新版本 4.17.4,antd-theme-generator 插件都没有报错,但是最新版本就是使用不了,最后在看了 antd-theme-generator 的源码后找到了问题。
问题定位:
// antd-theme-generator -> index.js 458行: // 这里将所有变量捆绑到一个文件中执行报错 let antdLess = await bundle({ src: antdStylesFile, });

寻找问题
bundle 方法是引用了 less-bundle-promise; 最后定位到 less-bundle-promise 下的 buildContents 方法获取文件报错;// 21 行: imported = line.replace(stringLiteralRegex, '$1'); 引入的的 less 文件,后续并没有将变量 @{root-entry-name} 替换,还是原始引用,造成找不到文件;

解决问题
因为动态生成主题不是生产依赖,所以可以更改源码,这里我只是为了解决项目问题,在 21 行下面直接判断替换变量。@{root-entry-name} 替换为 default;// 解决 @{root-entry-name} 报错问题; // 当然还有更好的正则替换或其他方式,这里只是解决问题直接更改 if (imported === './@{root-entry-name}.less') { imported = './default.less' }

总结 【antd-theme-generator|antd-theme-generator 动态主题报错(没有对应文件 @{root-entry-name}.less)】对于项目中的依赖升级过后,总会有一些兼容问题产生,我们在网上没有解决方案时,就需要根据现有的提示错误信息去寻找缘由,查看源码也是一份必修课,望能给给位小伙伴们提供到帮助。(^-^)

    推荐阅读