如果你遇到了构建相关的问题,可以参考当前文档进行排查。
Modern.js 内部基于 Rsbuild 封装了自身的构建工具,因此你可以直接参考 Rsbuild 的 FAQ 文档:
默认情况下,Modern.js 的 webpack 编译缓存生成在 ./node_modules/.cache/webpack 目录下。
如果需要清空本地的编译缓存,可以执行以下命令:
rm -rf ./node_modules/.cacheModern.js 提供 inspect 命令 用于查看项目最终生成的 Modern.js 配置以及 webpack / Rspack 配置。
➜ npx modern inspect
Inspect config succeed, open following files to view the content:
- Rsbuild Config: /root/my-project/dist/rsbuild.config.mjs
- Rspack Config (web): /root/my-project/dist/rspack.config.web.mjs出于编译性能的考虑,默认情况下,Modern.js 不会编译 node_modules 下的文件,也不会编译当前工程目录外部的文件。
因此,当你引用其他子项目的源代码时,可能会遇到类似 You may need an additional loader to handle the result of these loaders. 的报错。
这个问题有以下解决方法:
source.include 配置项,指定需要额外进行编译的目录或模块,参考 source.include 用法介绍。如果编译正常,但是打开页面后出现 exports is not defined 报错,通常是因为在项目中使用 Babel 编译了一个 CommonJS 模块,导致 Babel 出现异常。
在正常情况下,Modern.js 是不会使用 Babel 来编译 CommonJS 模块的。如果项目中使用了 source.include 配置项,则可能会把一些 CommonJS 模块加入到 Babel 编译中。
该问题有两种解决方法:
sourceType 配置项设置为 unambiguous,示例如下:export default {
tools: {
babel(config) {
config.sourceType = 'unambiguous';
},
},
};将 sourceType 设置为 unambiguous 可能会产生一些其他影响,请参考 Babel 官方文档。
如果编译时出现以下报错,通常也是因为在项目中使用 Babel 编译了一个 CommonJS 模块,解决方法与上述的 exports is not defined 问题一致。
Error: ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: 581更多信息请参考 issue:babel#12731。
当编译进度条卡死,但终端无 Error 日志时,通常是因为编译过程中出现了异常。在某些情况下,当 Error 被 webpack 或其他模块捕获后,错误日志不会被正确输出。最为常见的场景是 Babel 配置出现异常,抛出 Error 后被 webpack 捕获,而 webpack 在个别情况下吞掉了 Error。
解决方法:
如果你修改 Babel 配置后出现此问题,建议检查是否有以下错误用法:
// 错误示例
export default {
tools: {
babel(config, { addPlugins }) {
// 该插件名称错误,或者未安装
addPlugins('babel-plugin-not-exists');
},
},
};// 错误示例
export default {
tools: {
babel(config, { addPlugins }) {
addPlugins([
[
'babel-plugin-import',
{ libraryName: 'antd', libraryDirectory: 'es' },
],
[
'babel-plugin-import',
{ libraryName: 'antd-mobile', libraryDirectory: 'es' },
],
]);
},
},
};// 正确示例
export default {
tools: {
babel(config, { addPlugins }) {
addPlugins([
[
'babel-plugin-import',
{ libraryName: 'antd', libraryDirectory: 'es' },
'antd',
],
[
'babel-plugin-import',
{ libraryName: 'antd-mobile', libraryDirectory: 'es' },
'antd-mobile',
],
]);
},
},
};Modern.js 默认开启了 webpack 的持久化缓存。
首次编译完成后,会自动生成缓存文件,并输出到 ./node_modules/.cache/webpack 目录下。执行第二次编译时,会命中缓存,并大幅度提高编译速度。
当 package.json 等配置文件被修改时,缓存会自动失效。
如果项目中 webpack 编译缓存一直未生效,可以添加以下配置进行排查:
export default {
tools: {
webpack(config) {
config.infrastructureLogging = {
...config.infrastructureLogging,
debug: /webpack\.cache/,
};
},
},
};添加以上配置后,webpack 会输出日志用于 debug,请参考 PackFileCacheStrategy 相关的日志来了解缓存失效的原因。
当你的项目中安装了 @types/lodash 包时,你可能会从 lodash 中引用一些类型,比如引用 DebouncedFunc 类型:
import { debounce, DebouncedFunc } from 'lodash';上述代码会在编译后产生如下报错:
SyntaxError: /project/src/index.ts: The 'lodash' method `DebouncedFunc` is not a known module.
Please report bugs to https://github.com/lodash/babel-plugin-lodash/issues.这个问题的原因是 Modern.js 默认开启了 babel-plugin-lodash 插件来优化 lodash 产物体积,但 Babel 无法区别「值」和「类型」,导致编译后的代码出现异常。
解决方法是使用 TypeScript 的 import type 语法,对 DebouncedFunc 类型进行显式声明:
import { debounce } from 'lodash';
import type { DebouncedFunc } from 'lodash';
在任意情况下,我们都推荐使用 import type 来引用类型,这对于编译器识别类型会有很大帮助。
从 2.47.0 版本开始,Modern.js 优化了 Type Checker 的检查范围。在之前的版本中,Type Checker 只输出 src 目录的类型错误,导致其他目录的类型错误无法被正确输出。
在新版本中,Modern.js 的 Type Checker 对齐了原生 tsc 的类型检查范围(即 tsconfig.json 的 include 和 exclude 字段定义的范围),能够完整输出项目中的类型错误。
如果你希望保持之前的行为,只输出 src 目录的类型错误,可以添加以下配置:
export default {
tools: {
tsChecker: {
issue: {
include: [{ file: '**/src/**/*' }],
},
},
},
};