【问题标题】:Better way to require.extensions with Node.js使用 Node.js 更好的方式来 require.extensions
【发布时间】:2015-05-07 04:58:51
【问题描述】:

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

还有一些类似解决方案的链接...

可以从这里派生一个解决方案: https://github.com/danvk/mocha-react

【问题讨论】:

标签: node.js reactjs mocha.js


【解决方案1】:

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

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

希望这就是你要找的。​​p>

【讨论】:

    【解决方案2】:

    没有其他方法可以做到这一点,这就是每个人都进行编译的方式(babel 等)。 @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,如果他们这样做,他们可能会为同一问题提供另一种解决方案。我会毫不犹豫地使用它!

    【讨论】:

    【解决方案3】:

    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 并使其性能更高。

    【讨论】:

      【解决方案4】:

      我认为你应该使用pirates

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

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

      希望这就是您想要的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多