簡體   English   中英

nodejs require - 模塊名稱區分大小寫的問題

[英]nodejs require - module name case sensitive issue

最近我發現了一個關於 node.js 要求機制的奇怪問題

您可能會認為,由於 Windows 文件系統,所需模塊是否區分大小寫並不重要。 所以 ...

模塊 A:

require("fancyModule");

模塊 B:

require("fancymodule");

都通向同一個 fancymodule.js 文件。 但是該對象的構造函數將被調用兩次。 所以

var FancyModule = {
    var name = "unkown";
    var setName = function(val){
        name = val
    }
    return {
        setName:setName
    }
}
module.exports = FancyModule();

將產生兩個單獨的 FancyModule 實例。 所以要注意它。

我知道我總是需要關心正確的文件名——無論文件系統是否區分大小寫。

我的問題是,有沒有辦法設置或配置 nodejs 來防止這種情況 - 或者至少打印出警告?

首先,永遠不要對您正在使用的文件系統做出假設。 始終希望它區分大小寫,以防您在不同的環境中運行它。

現在解決您的問題:

當您需要 node 中的模塊時,node 將准確緩存導入以防止您想要導出單例並且不對其進行兩次初始化的情況。 雖然文件系統查找將返回完全相同的文件,因為它不區分大小寫,但 require 的緩存仍將這兩種情況視為不同的模塊。 那是因為它必須假設它在區分大小寫的環境中運行,因此實際上可能有兩個不同的模塊。

這就是為什么它初始化你的單例兩次。 它實際上將它們視為兩個不同的模塊。

你問有沒有什么辦法可以防止。 有一種非常簡單但可怕的方法來做到這一點。 您可以修補global.require以小寫您的導入:

var patchRequire = function () {
    var oldRequire = global.require;
    global.require = function (moduleName) {
        return oldRequire.call(global, moduleName.toLowerCase());
    };
};

patchRequire();
require('Foo-Bar'); // Will require 'foo-bar' instead

但請不要那樣做。 最好確保您的導入保持一致,並使用由破折號分隔的所有小寫名稱。

此功能檢查是否區分大小寫

const path = require('path');
const fs = require('fs');


const safeRequire = function (requiredPath) {
    const splitted = requiredPath.split('/');
    const upup = splitted.filter((e) => e == '..').join('/');
    let upMost = path.resolve(upup);
    let down = splitted.filter((e) => e !== '..' && e !== '.');
    if (requiredPath.startsWith('./')) {
      upMost = __dirname;
    }
    for (let each of down) {
      const dir = fs.readdirSync(upMost);
      if (!dir.includes(each) && !dir.includes(`${each}.js`)) {
        throw 'Module Not Found (check casing)';
      }
      upMost = path.join(upMost, each);
    }
  return originalRequire.apply(this, [requiredPath]);
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM