使用Node.js请求e.extensions的更好方法



我正在测试一堆React JSX组件。它们都需要用React、Babel或其他什么工具进行转换,但我们对存根需求有特殊需求,所以我试图用Mocha运行的特殊编译器来覆盖需求。下面的解决方案运行良好,但您会注意到,我们使用require.extensions[]来捕获所有.jsx文件。我担心的是require.extensions已被锁定并且已弃用。有更好的方法吗?

// Install the compiler.
require.extensions['.jsx'] = function(module, filename) {
    return module._compile(transform(filename), filename);
};

以下是整个运输车供参考:

// Based on https://github.com/Khan/react-components/blob/master/test/compiler.js
var fs = require('fs'),
    ReactTools = require('react-tools');
// A module that exports a single, stubbed-out React Component.
var reactStub = 'module.exports = require("react").createClass({render:function(){return null;}});';
// Should this file be stubbed out for testing?
function shouldStub(filename) {
    if (!global.reactModulesToStub) return false;
    // Check if the file name ends with any stub path.
    var stubs = global.reactModulesToStub;
    for (var i = 0; i < stubs.length; i++) {
        if (filename.substr(-stubs[i].length) == stubs[i]) {
            console.log('should stub', filename);
            return true;
        }
    }
    return false;
}
// Transform a file via JSX/Harmony or stubbing.
function transform(filename) {
    if (shouldStub(filename)) {
        delete require.cache[filename];
        return reactStub;
    } else {
        var content = fs.readFileSync(filename, 'utf8');
        return ReactTools.transform(content, {harmony: true});
    }
}
// Install the compiler.
require.extensions['.jsx'] = function(module, filename) {
    return module._compile(transform(filename), filename);
};

以及simalar解决方案的一些链接。。。

  • https://github.com/danvk/mocha-react/issues/1
  • https://github.com/Automattic/jsx-require-extension
  • https://www.npmjs.com/package/node-jsx
  • https://github.com/olalonde/better-require
  • http://mochajs.org/#usage
  • http://nodejs.org/api/globals.html#globals_require_extensions

解决方案可以从这里分叉:https://github.com/danvk/mocha-react

API被弃用的原因有两个。首先,节点模块解析算法非常复杂,它必须查看指定的文件,如果它不存在,它会在require.extensions的键中查找该文件和所有可能的扩展名,如果它是一个目录,则会查找package.json或index.js。哦,别忘了,如果一开始没有./,它会查找node_modules目录,如果在CCD_ 5中找不到父目录,则查看该父目录。Ryan Dahl表示,他后悔在JsConf 2018的演讲中把它弄得如此复杂,并在他的deno项目中使用了一种简单得多的模块解析算法。第二,如果require.extensions中有更多的扩展,它需要更多的文件系统调用,因为它必须匹配无扩展名的文件。

第二个问题的解决方案是需要扩展。我自己没有使用过,但它抽象了require.extensions API,使其性能更高。

没有其他方法可以做到这一点,每个人都是这样做的(babel等)@uni_nake的答案——使用节点钩子——是可以的,因为它向您隐藏了这一点,但它本质上使用了相同的机制:从它的代码中可以看出它使用了Module_extensions,但这与require.extensions相同,正如我写的一个测试所示:https://github.com/giltayar/playing/blob/1f04f6ddc1a0028974b403b4d1974afa872edba4/javascript/node/test/is-module-extensions-same-as-require-extensions.test.js

所以最后的答案是——我假设Node中没有人会破坏Babel,如果他们这样做了,他们可能会为同样的问题提供另一个解决方案。我会毫不犹豫地使用它!

我使用节点挂钩来存根测试中的所有.scss调用。

你会从文档中看到,当需要一个匹配的文件时,它会执行包含的字符串,并且非常强大,因为它还向你传递原始源。

希望这就是你想要的。

我认为您应该使用pirates

我认为将babel-register中使用的require.extensions替换为pirates时的PR会有所帮助。

https://github.com/babel/babel/pull/3670/files#diff-75a0292ed78043766c2d5564dd84ad2L85-L93

希望这就是你想要的。

最新更新