使用Node.js进行require.extensions的更好方法

问题描述 投票:19回答:3

我正在测试一堆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

node.js reactjs mocha
3个回答
2
投票

API已被弃用有两个原因。一,节点模块解析算法非常复杂,它必须查看指定的文件,如果它不存在,它会在require.extensions的键中查找该文件和所有可能的扩展名,如果它是一个目录,则查找一个package.json或index.js。哦,不要忘记,如果开头没有./,它会在node_modules目录中查找,如果在node_modules中找不到它,则查看父目录。 Ryan Dahl说他很遗憾在his talk at JsConf 2018中使它变得如此复杂,并且在他的deno项目中使用了更简单的模块分辨率算法。第二,如果require.extensions中有更多扩展,它需要更多的文件系统调用,因为它必须匹配无扩展名文件。

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


1
投票

我在测试中使用node-hook来存根所有.scss调用。

您将从文档中看到,当需要匹配文件时,它将执行包含字符串而非常强大,因为它还会传递原始源。

希望这就是你要找的东西。


1
投票

没有其他方法可以做到这一点,这就是每个人都在做的事情(巴贝尔等)。 @ uni_nake的答案 - 使用node-hook - 是好的,因为它隐藏了你,但它本质上使用相同的机制:看看它的代码显示它使用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,如果他们这样做,他们可能会为同样的问题提供另一种解决方案。我会毫不犹豫地使用它!

© www.soinside.com 2019 - 2024. All rights reserved.