Heim  >  Artikel  >  Web-Frontend  >  Die Geschichte zwischen node.js und macOS

Die Geschichte zwischen node.js und macOS

小云云
小云云Original
2017-12-18 11:22:141351Durchsuche

Dieser Artikel verwendet eine kurze Geschichte, um Ihnen die Geschichte zwischen node.js und macOS zu erzählen. Ich hoffe, dass es allen helfen kann.

George G hat einen kleinen Test auf seinem Computer durchgeführt, aber die Ergebnisse waren ganz anders als erwartet.

Dann werfen wir zunächst einen Blick auf das, was in diesem kleinen Test geschrieben steht:

Es gibt insgesamt drei Dateien, und Der Gesamtcode überschreitet nicht 15 Zeilen

<span style="font-size: 14px;">parent.js</span>

<span style="font-size: 14px;">class Parent {}<br><br>module.exports = Parent<br></span>

<span style="font-size: 14px;">son.js</span>

<span style="font-size: 14px;">//加载时把模块文件名首字母大写了(不正确的)<br/>const Parent = require(&#39;./Parent&#39;)<br/><br/>class Son extends Parent {}<br/><br/>module.exports = Son<br/></span>

test.js

<span style="font-size: 14px;">//加载时把模块名首字母大写(不正确的)<br/>const ParentIncorrect = require(&#39;./Parent&#39;)<br/>//通过正确的模块文件名加载(正确)<br/>const Parent = require(&#39;./parent&#39;)<br/><br/>const Son = require(&#39;./son&#39;)<br/><br/>const ss = new Son()<br/><br/>//测试结果<br/>console.log(ss instanceof Parent) // false<br/>console.log(ss instanceof ParentIncorrect) // true<br/></span>

Student George G hat die folgenden Fragen:

  1. <code><span style="font-size: 14px;">son.js</span>son.js als auch <code><span style="font-size: 14px;">test.js</span>test.js weisen falsche Dateinamenverweise auf (Fallprobleme). Warum wird kein Fehler gemeldet?

  2. Testergebnis, warum <span style="font-size: 14px;">ss instanceof ParentIncorrect === true</span><span style="font-size: 14px;">ss caseof ParentIncorrect === true</span>

    ? Ich habe es toleriert, keinen Fehler zu melden, aber warum dachte ich trotzdem, ich sei die Instanz des Moduls, das mit einem falschen Namen geladen wurde?

Wenn Sie, Klassenkamerad, die oben genannten Probleme bereits klar verstanden haben, herzlichen Glückwunsch, Sie können mit einem Stift schreiben, um den Himmel zu beruhigen, und Ihre Kampfkünste können es Besteigen Sie ein Pferd, um die Welt zu bestimmen; Sie können Ihre Mutter auf dem Kang kennenlernen. Steigen wir auf den Kang und lernen Sie etwas über Schuhe!

Aber wenn Sie nicht wissen, warum? Okay, dann werden einige von mir es sagen und einige von euch werden es sich ansehen.

Tatsächlich ähnelt die Diagnosemethode (Debugging im prätentiösen Stil) der der traditionellen chinesischen Medizin. Sie können eine oder zwei der vier Methoden des Schauens, Riechens und Erkennens wählen. fragen und abtasten, um die Antwort zu finden.

Hoffnung

Nach einer Weile des Lesens glaube ich, dass vorsichtige Schüler es finden werden die echte Datei. Wenn es bei der Einführung eine Diskrepanz zwischen dem Namen und dem Code gibt, muss hier ein Problem vorliegen. Lassen Sie uns fortfahren

hören

Auch wenn ich nichts im Code riechen kann

Fragen

Komm schon, a Ein sehr wichtiger Teil der Softwareentwicklung ist die Kommunikation, die nicht unbedingt mit Kollegen stattfindet, die auf Fehler stoßen. Es kann sich um Sie selbst handeln, es kann sich um die Qualitätssicherung handeln, und natürlich kann es sich um den PM oder Ihren Chef handeln. Sie haben nicht die Frage gestellt, die Sie wissen wollten; er hat nicht deutlich gemacht, was er antworten wollte; . . .

Was möchte ich also wissen? Die folgenden zwei Dinge sind als Einstieg zum Debuggen sinnvoller:
  1. Betriebssystem
  2. Run Environment + Version
  3. Wie haben Sie es getestet, Befehlszeile oder auf andere Weise

<span style="font-size: 14px;">node.js > 8.0</span> Antwort: macOS; node.js > 8.0<span style="font-size: 14px;">node test.js</span>

; Befehlszeile

<span style="font-size: 14px;">node test.js</span>

Schnitt<span style="font-size: 14px;">debug</span>Der aufregende und tiefgreifende Moment ist gekommen und ich werde handeln. (Um den

<p>Debug<span style="font-size: 14px;"></span></p>-Prozess vollständig zu beschreiben, werde ich im Folgenden so tun, als wüsste ich nicht alles im Voraus)

Bereiten Sie den Computer vor, abgeschlossen<span style="font-size: 14px;">node.js > 9.3.0</span>

Bereiten Sie die Laufumgebung vor

<span style="font-size: 14px;">node.js > 9.3.0</span>

, Abgeschlossen

Kopieren Sie den Code, Abgeschlossen

<code><span style="font-size: 14px;">test.js</span> Führen Sie es aus, es ist erstaunlich, es wurde kein Fehler gemeldet und das laufende Ergebnis ist was George G so gesagt hat. <span style="font-size: 14px;">require</span>Um zu beweisen, dass ich nicht blind bin, habe ich es noch einmal in <code><span style="font-size: 14px;">require('./nidayede')</span>test.js

require hat eine Datei erstellt, die überhaupt nicht existiert <span style="font-size: 14px;">Error: Cannot find module './nidayede'</span><code><span style="font-size: 14px;">require('./nidayede')</span>

, Führen Sie den Code aus.

Glücklicherweise wurde dieses Mal ein Fehler gemeldet Fehler: Modul './nidayede' konnte nicht gefunden werden, Also ich bin nicht verrückt. Das ist eine wahre Freude. Da ist also die erste Frage

Warum hat der Modulname von Gouri die falsche Groß- und Kleinschreibung und kann dennoch geladen werden?

Hängt es mit dem Betriebssystem zusammen? Kommen Sie und lassen Sie uns ein weiteres <code><span style="font-size: 14px;">windows</span>Windows zum Ausprobieren finden. Tatsächlich sind wir bei <code><span style="font-size: 14px;">windows</span><span style="font-size: 14px;">Windows</span>angekommen ><span style="font-size: 14px;">Error: Cannot find module './Parent'</span>, Großschreibung ist ein Problem, Fehler: Modul './Parent' kann nicht gefunden werden

. <span style="font-size: 14px;">macOS</span>Was macht also <code><span style="font-size: 14px;">google</span>macOS? Können Sie den Unterschied zwischen Groß- und Kleinschreibung nicht erkennen? Also schnell

<p>google<img src="https://img2./UZb2Ebq.png!web" class="alignCenter" alt="Die Geschichte zwischen node.js und macOS" ></p> (frag mich nicht, warum nicht Baidu)

<span style="font-size: 14px;">OS X</span> <span style="font-size: 14px;">case-insensitive</span>Es stellt sich heraus, dass das großartige OS Dateisystem (ausführliche Dokumentation).

aber warum? Was ist der Zweck eines solchen menschenfeindlichen Designs?

Die Geschichte zwischen node.js und macOS

Weitere Erklärungen, kommen und gehen

Das ist also der Grund, warum Sie es nicht tun einen Fehler melden? (gibt <span style="font-size: 14px;">node.js</span><span style="font-size: 14px;">node.js</span>

die Schuld) Aber das ist die ganze Wahrheit.

Aber die Sache ist noch nicht vorbei

Wie zum Teufel ist es, einen Dieb als Vater zu haben?

<span style="font-size: 14px;">node.js</span>Ich habe vage davon gehört. Gibt es einen Cache in node.js<span style="font-size: 14px;">const ParentIncorrect = require('./Parent')</span>? durch das Ding? In der Stimmung, es auszuprobieren, habe ich <code><span style="font-size: 14px;">const Parent = require('./parent')</span>const ParentIncorrect = require('./Parent') und

const Parent = require('./parent')<p></p> Ich habe die Position geändert und dachte, wäre es richtig, sie zuerst mit dem richtigen Namen zu laden? Natürlich

es ist immer noch falsch. Sie können das Problem nicht wirklich lösen, indem Sie raten und so tun, als ob<span style="font-size: 14px;">ParentIncorrect</span>Na Bibi<span style="font-size: 14px;">Parent</span><span style="font-size: 14px;">ParentIncorrect</span><span style="font-size: 14px;">console.log(ParentIncorrect === Parent)</span> und Elternteil<span style="font-size: 14px;">false</span>? Also habe ich

console.log(ParentIncorrect === Parent)

geschrieben und das Ergebnis war <span style="font-size: 14px;">node.js</span>false . Sie sind also wirklich nicht dasselbe, das Problem könnte also im Einleitungsteil liegen? <span style="font-size: 14px;">clone</span><span style="font-size: 14px;">node.js</span>So entstand die Idee, so zu tun, als würde man sich den Quellcode von node.js

ansehen (Eigentlich schaue ich es mir nicht an, das Problem kann ich endlich herausfinden). Nach einem langen Tag, mit einem Gefühl der Beklommenheit, klonen<span style="font-size: 14px;">node.js</span> <span style="font-size: 14px;">require</span>node.js Quellcode (es hat lange gedauert, so langsam)<span style="font-size: 14px;">require</span>

Komm, lass uns den mysteriösen

<code><span style="font-size: 14px;">src/node_main.cc => src/node.cc => lib/internal/bootstrap_node.js => lib/module.js</span>node.js

eingeben

Quellcode-Welt. Da es bei unserer Frage um require<span style="font-size: 14px;">lib/module.js</span> geht, fangen wir mit ihr an, finden aber

require

Der Definitionsprozess erfordert etwas Geduld, ich werde hier nicht auf Details eingehen, sondern nur auf die Suchreihenfolge

src/node_main.cc => cc => lib/internal/bootstrap_node.js => lib/module.js Gefunden, das ist es lib/module.js, kommen Sie auf den Punkt: lib/module.js => require
<span style="font-size: 14px;">Module.prototype.require = function(path) {<br/>  assert(path, &#39;missing path&#39;);<br/>  assert(typeof path === &#39;string&#39;, &#39;path must be a string&#39;);<br/>  return Module._load(path, this, /* isMain */ false);<br/>};<br/></span>

好像没什么卵用,对不对?她就调用了另一个方法 <span style="font-size: 14px;">_load</span> ,永不放弃,继续

lib/module.js => _load

<span style="font-size: 14px;">Module._load = function(request, parent, isMain) {<br/>  //debug代码,么卵用,跳过<br/>  if (parent) {<br/>    debug(&#39;Module._load REQUEST %s parent: %s&#39;, request, parent.id);<br/>  }<br/><br/>  if (isMain && experimentalModules) {<br/>    //...<br/>    //...<br/>    //这段是给ES module用的,不看了啊<br/>  }<br/><br/>  //获取模块的完整路径<br/>  var filename = Module._resolveFilename(request, parent, isMain);<br/><br/>  //缓存在这里啊?好激动有没有?!?终于见到她老人家了<br/>  //原来这是这样的,简单的一批,毫无神秘感啊有木有<br/>  var cachedModule = Module._cache[filename];<br/>  if (cachedModule) {<br/>    updateChildren(parent, cachedModule, true);<br/>    return cachedModule.exports;<br/>  }<br/><br/>  //加载native但非内部module的,不看<br/>  if (NativeModule.nonInternalExists(filename)) {<br/>    debug(&#39;load native module %s&#39;, request);<br/>    return NativeModule.require(filename);<br/>  }<br/><br/>  //构造全新Module实例了<br/>  var module = new Module(filename, parent);<br/><br/>  if (isMain) {<br/>    process.mainModule = module;<br/>    module.id = &#39;.&#39;;<br/>  }<br/><br/>  //先把实例引用加缓存里<br/>  Module._cache[filename] = module;<br/><br/>  //尝试加载模块了<br/>  tryModuleLoad(module, filename);<br/><br/>  return module.exports;<br/>};<br/></span>

似乎到这里差不多了,不过我们再深入看看 <span style="font-size: 14px;">tryModuleLoad</span>

lib/module.js => tryModuleLoad

<span style="font-size: 14px;">function tryModuleLoad(module, filename) {<br/>  var threw = true;<br/>  try {<br/>    //加载模块<br/>    module.load(filename);<br/>    threw = false;<br/>  } finally {<br/>    //要是加载失败,从缓存里删除<br/>    if (threw) {<br/>      delete Module._cache[filename];<br/>    }<br/>  }<br/>}<br/></span>

接下来就是真正的 <span style="font-size: 14px;">load</span> 了,要不我们先停一停?

好了,分析问题的关键在于不忘初心,虽然到目前为止我们前进的比较顺利,也很爽对不对?。但我们的此行的目的并不是爽,好像是有个什么疑惑哦!于是,我们再次梳理下问题:

  1. <span style="font-size: 14px;">son.js</span> 里用首字母大写(不正确)的模块名引用了 <span style="font-size: 14px;">parent.js</span>

  2. <code><span style="font-size: 14px;">test.js</span> 里,引用了两次 <span style="font-size: 14px;">parent.js</span> ,一次用完全一致的模块名;一次用首字母大写的模块名。结果发现 <span style="font-size: 14px;">son instanceof require('./parent') === false</span>

既然没报错的问题前面已经解决了,那么,现在看起来就是加载模块这个部分可能出问题了,那么问题到底是什么?我们怎么验证呢?

这个时候我看到了这么一句话 <span style="font-size: 14px;">var cachedModule = Module._cache[filename];</span> ,文件名是作为缓存的 <span style="font-size: 14px;">key</span> ,来吧,是时候看看 <span style="font-size: 14px;">Module._cache</span> 里存的模块 <span style="font-size: 14px;">key</span> 都是什么牛鬼蛇神了,打出来看看吧,于是我在 <code><span style="font-size: 14px;">test.js</span> 里最后面加了一句 <span style="font-size: 14px;">console.log(Object.keys(require.cache))</span> ,我们看看打出了什么结果

<span style="font-size: 14px;">false<br/>true<br/>[ &#39;/Users/admin/codes/test/index.js&#39;,<br/>  &#39;/Users/admin/codes/test/Parent.js&#39;,<br/>  &#39;/Users/admin/codes/test/parent.js&#39;,<br/>  &#39;/Users/admin/codes/test/son.js&#39; ]<br/></span>

真相已经呼之欲出了, <span style="font-size: 14px;">Module._cache</span> 里真的出现了两个 <span style="font-size: 14px;">[p|P]arent</span><span style="font-size: 14px;">macOS</span> 默认不区分大小写,所以她找到的其实是同一个文件;但 <span style="font-size: 14px;">node.js</span> 当真了,一看文件名不一样,就当成不同模块了),所以最后问题的关键就在于 <span style="font-size: 14px;">son.js</span> 里到底引用时用了哪个名字(上面我们用了首字母大写的 <span style="font-size: 14px;">require('./Parent.js')</span> ),这才导致了 <code><span style="font-size: 14px;">test.js</span> 认贼作父的梗。

如果我们改改 <span style="font-size: 14px;">son.js</span> ,把引用换成 <span style="font-size: 14px;">require('./parEND.js')</span> ,再次执行下 <code><span style="font-size: 14px;">test.js</span> 看看结果如何呢?

<span style="font-size: 14px;">false<br/>false<br/>[ &#39;/Users/haozuo/codes/test/index.js&#39;,<br/>  &#39;/Users/haozuo/codes/test/Parent.js&#39;,<br/>  &#39;/Users/haozuo/codes/test/parent.js&#39;,<br/>  &#39;/Users/haozuo/codes/test/son.js&#39;,<br/>  &#39;/Users/haozuo/codes/test/parENT.js&#39; ]<br/></span>

没有认贼作父了对不对?再看 <span style="font-size: 14px;">Module._cache</span> 里,原来是 <span style="font-size: 14px;">parENT.js</span> 也被当成一个单独的模块了。

Angenommen, Ihr Moduldateiname hat theoretisch <code><span style="font-size: 14px;">n</span>n Zeichen in <span style="font-size: 14px;">macOS</span><span style="font-size: 14px;">macOS</span><span style="font-size: 14px;">node.js</span> In einem Dateisystem, bei dem die Groß-/Kleinschreibung nicht beachtet wird, können Sie node.js<span style="font-size: 14px;">2</span> verwenden, um das Maximum herauszuholen <code><span style="font-size: 14px;">n</span>2 von

<p>n<span style="font-size: 14px;"></span></p> versorgt Caches mit <span style="font-size: 14px;">macOS</span> Ist es nicht elend! ? Glücklicherweise kann

<span style="font-size: 14px;">macOS</span>

immer noch auf Groß-/Kleinschreibung umgestellt, das System auf einer Grid-Festplatte neu installiert oder eine neue Partition erstellt werden.

Obwohl das Problem nicht schwierig ist, sind die Entschlossenheit und die Ideen zur Erforschung des Problems dennoch wichtig.

Verwandte Empfehlungen:

Lernen Sie, wie Sie mit node.js einen untergeordneten Prozess erstellen

PHP und Node.js

node.js Publish-Subscribe-Modus-Methode

Das obige ist der detaillierte Inhalt vonDie Geschichte zwischen node.js und macOS. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn