feat: hmr supports linked npm packages changes#864
Conversation
crates/mako/src/watch.rs
Outdated
| })?; | ||
|
|
||
| let module_graph = compiler.context.module_graph.read().unwrap(); | ||
| let (dependencies, _) = module_graph.toposort(); |
There was a problem hiding this comment.
topsort 是必要的吗? 是不是只要遍历所有模块就够了。
|
missing 的思路是不是可以这么解解看 不添加watch 的文件路径了,添加 watch 文件所在的目录( NonRecursive) 这样的 missing 的添加回来 是不是就可以感知到了。 |
|
missing_dep 跟引入的 module不一定在一个目录。比如下面的情况, // src/a/a.js
import { b } from '../b/b';
console.log(b);
// src/b/b.js
const b = "b";
export { b }; |
|
这是对每个模块单独做 watch?所有 node_modules 下的文件都会包含吗?感觉几万个模块的项目可能会挂,找个真实项目试试?比如 yuyan_assets。 |
|
是的,对 module_graph 中的每个模块watch。open-yuyan-assets 试了下 11477 个模块,正常。其他找到的项目,模块树都比这个少。我的电脑, 通过 之前有考虑,是否可以加一个类似 extraWatchFiles 的参数,用于用户自己配置需要额外 watch 的文件或目录。这样可以避免达到最大打开数量限制的问题,也可以解决上面对于 missing deps 的 watch 问题。缺点是需要用户自己去配置 |
|
补充我的想法, 1、项目文件已经 watch 过了,再加 watch 是否重复? |
|
更新了一版:
采用这种方式更新的原因:
|
sorrycc
left a comment
There was a problem hiding this comment.
用 yuyanAssets,算一下 watch 在初始执行和增量执行的消耗分别有多少(附上测试机型),尤其是后者。
crates/mako/src/watch.rs
Outdated
| { | ||
| self.watch_dir_recursive( | ||
| dir.into(), | ||
| &[".git", "node_modules", ".DS_Store", ".node"], |
crates/mako/src/watch.rs
Outdated
| let dir = dir.dir().as_ref(); | ||
| // not in root dir or is root's parent dir | ||
| if dir.strip_prefix(self.root).is_err() | ||
| && self.root.clone().strip_prefix(dir).is_err() |
There was a problem hiding this comment.
这个 clone 看能不能省,因为每个 module 都会跑一遍,几万个 module 应该还是有消耗的。
|
@zhangpanweb 改之前的 watch 是否耗时很少? |
|
改之前,watch 跑了几次,88ms、103ms、93ms,平均90几ms |


支持 npm包 link 的热更。通过在构建后,获取所有的依赖路径并添加到watch列表中实现。
存在的一个问题是,在 link 的 npm包中,引用一个不存在的文件,dev启动后,再添加一个这个文件,此时热更会失效,不会重新 resolve 到这个新添加的文件。原因是:resolve 一个 link npm包中不存在的文件,此文件会成为一个 missing_dep, missing_dep 在 nodejs_resolver 中没办法获取可能的 resolve 路径,所以此路径不会被添加到 watch 列表中,后续此文件的添加,不会触发文件变更事件,触发hmr。考虑在替换 oxc_resolver 后解决,oxc_resolver 能够获取 resolve 过程中 missing_dep 可能 resolve 路径,获取后添加到 watch 列表中即可