【问题标题】:Is there any way how to modify file during the require?有什么方法可以在需要期间修改文件吗?
【发布时间】:2021-04-27 08:08:36
【问题描述】:

我想修改库的代码,例如在需要期间注入一些自定义“代码”。

例子:

const fs = require('fs');
const file = fs.readFileSync('./in').toString();
console.log(file)

所以,我想从fs 模块修改函数readFileSync。有什么方法可以将console.log('hi') 注入readFileSync 函数以及如何注入?

【问题讨论】:

    标签: node.js inject


    【解决方案1】:

    这通常称为Decorator pattern。简而言之,您将获取该函数并将其包装在另一个函数中,该函数执行其他操作以及原始行为。

    例子:

    const fs = require('fs');
    function myReadFileSync(...args) {
      // If you want the console.log before:
      console.log('will read file');
      fs.readFileSync.call(fs, ...args);
      // If you want a log after the real operation:
      console.log('managed to read the file');
      // (of course, you can have them both as well)
    }
    

    然后,使用myReadFileSync 代替原来的。这通常可以使用 Dependency injection 来完成 - 您可以像注入对象一样注入函数。

    如果想法是修改“真正的”fs 模块,不要。这是一种反模式,您通过更改代码所依赖的默认行为来污染全局命名空间。它可以在 Node.js 中完成,但只有在您知道代码后果的情况下才应该进行。这也是一些测试库(例如 Jest)的问题 - 它们修改全局对象,这通常是不可取的。

    话虽如此,下面是如何应用这种技术,称为monkey patching

    const fs = require('fs');
    // We need to preserve the original implementation somewhere:
    const realReadFileSync = fs.readFileSync;
    fs.readFileSync = function myReadFileSync(...args) {
      // Same as in the decorator:
      realReadFileSync.call(fs, ...args);
    };
    

    最好阅读一下,评估利弊,然后决定这是否是您想要的代码库。

    【讨论】:

    • This is an anti-pattern where you pollute the global namespace 正确完成后,全局命名空间不会被污染。 by altering default behaviors that the code relies on. 不应该这样做。
    猜你喜欢
    • 2011-12-21
    • 2022-12-30
    • 1970-01-01
    • 2013-04-18
    • 2010-09-23
    • 1970-01-01
    • 2016-06-24
    • 2011-04-16
    • 1970-01-01
    相关资源
    最近更新 更多