mirror of
https://github.com/ZiuChen/ZiuChen.github.io.git
synced 2025-08-18 23:49:33 +08:00
110 lines
50 KiB
JavaScript
110 lines
50 KiB
JavaScript
import{_ as s,o as n,c as a,a as l}from"./app.94d5b31a.js";const A=JSON.parse('{"title":"前端工程化","description":"","frontmatter":{},"headers":[{"level":2,"title":"Node.js","slug":"node-js","link":"#node-js","children":[{"level":3,"title":"什么是Node.js","slug":"什么是node-js","link":"#什么是node-js","children":[]},{"level":3,"title":"Node.js的应用场景","slug":"node-js的应用场景","link":"#node-js的应用场景","children":[]},{"level":3,"title":"Node.js的参数传递","slug":"node-js的参数传递","link":"#node-js的参数传递","children":[]},{"level":3,"title":"Node中的全局对象","slug":"node中的全局对象","link":"#node中的全局对象","children":[]}]},{"level":2,"title":"模块化开发","slug":"模块化开发","link":"#模块化开发","children":[{"level":3,"title":"模块化的初衷","slug":"模块化的初衷","link":"#模块化的初衷","children":[]},{"level":3,"title":"CommonJS","slug":"commonjs","link":"#commonjs","children":[]}]}],"relativePath":"note/Front-end Engineering.md","lastUpdated":1676030729000}'),e={name:"note/Front-end Engineering.md"},o=l(`<h1 id="前端工程化" tabindex="-1">前端工程化 <a class="header-anchor" href="#前端工程化" aria-hidden="true">#</a></h1><h2 id="node-js" tabindex="-1">Node.js <a class="header-anchor" href="#node-js" aria-hidden="true">#</a></h2><ul><li>什么是Node.JS Node的应用场景</li><li>JS代码执行</li><li>Node的输入和输出</li><li>Node的全局对象</li></ul><h3 id="什么是node-js" tabindex="-1">什么是Node.js <a class="header-anchor" href="#什么是node-js" aria-hidden="true">#</a></h3><p>Node.js是一个基于<strong>V8 JavaScript引擎</strong>的<strong>JavaScript运行时环境</strong></p><ul><li>V8可以嵌入到任何C++应用程序中,无论是Chrome还是Node.js,事实上都嵌入了V8引擎来执行JavaScript代码</li><li>在Chrome浏览器中,还需要解析、渲染HTML、CSS等相关渲染引擎,另外还需要支持浏览器操作的API、浏览器自己的事件循环</li><li>在Node.js中我们也需要进行一些额外操作:文件系统读写、网络IO、加密、压缩解压文件等</li></ul><p>可以简单总结出Node.js和浏览器的区别</p><ul><li><p>Chrome浏览器</p><ul><li><p>Blink负责解析HTML文档,遇到JavaScript标签时将内容交给V8引擎</p></li><li><blockquote><p>Blink 是 Google Chrome 浏览器的渲染引擎,V8 是 Blink 内置的 JavaScript 引擎</p></blockquote><ul><li>预分析:检查语法错误但不生成AST树</li><li>生成AST:语法分析、词法分析后,生成抽象语法树(AST) <ul><li>AST 为每一行代码定义键值对。初始类型标识符定义 AST 属于一个程序,然后所有代码行将定义在主体内部,主体是一个对象数组。</li></ul></li><li>生成字节码:基线编译器(Ignition)将 AST 转换为字节码</li><li>生成机器代码:优化编译器 (Turbofan) 将字节码转换为优化的机器代码。另外,在逐行执行字节码的过程中,<strong>如果一段代码经常被执行,V8会直接将这段代码转换并保存为机器码</strong>,下次执行不需要经过字节码,优化了执行速度</li></ul></li></ul></li><li><p>Node.js</p><ul><li>只处理JavaScript代码 内部V8引擎负责JS代码的执行</li><li>JavaScript代码 -> V8 -> Node.js Bindings -> LibUV</li><li>LibUV是使用<strong>C语言编写的库</strong>,提供了<strong>事件循环、文件系统读写、网络IO、线程池</strong>等等内容</li></ul></li></ul><p></p><h3 id="node-js的应用场景" tabindex="-1">Node.js的应用场景 <a class="header-anchor" href="#node-js的应用场景" aria-hidden="true">#</a></h3><ul><li>前端开发的库都是以node包形式管理的</li><li>npm yarn pnpm成为前端开发使用最多的工具</li><li>使用Node.js作为Web服务器开发、中间件、代理服务器</li><li>借助Node.js完成前后端渲染的同构应用</li><li>编写脚本工具 构建项目 打包代码等</li><li>Electron桌面应用程序</li></ul><h3 id="node-js的参数传递" tabindex="-1">Node.js的参数传递 <a class="header-anchor" href="#node-js的参数传递" aria-hidden="true">#</a></h3><h4 id="process-argv" tabindex="-1"><code>process.argv</code> <a class="header-anchor" href="#process-argv" aria-hidden="true">#</a></h4><p><code>process.argv</code>返回一个数组</p><ul><li>在代码中通过<code>process.argv[2]</code>读取来自命令行的额外参数</li><li><code>process.argv[0]</code> <code>process.argv[1]</code>分别为<code>node.exe</code>的绝对路径和<code>目标文件</code>的绝对路径</li></ul><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// sum.js</span></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> x </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> process</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">argv[</span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">]</span></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> y </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> process</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">argv[</span><span style="color:#F78C6C;">3</span><span style="color:#A6ACCD;">]</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(x </span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;"> y)</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><div class="language-sh line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;"># 通过命令行运行node执行脚本 并传入参数</span></span>
|
||
<span class="line"><span style="color:#FFCB6B;">node</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">sum.js</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">5</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">10</span><span style="color:#A6ACCD;"> </span><span style="color:#676E95;font-style:italic;"># 15</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><h4 id="console" tabindex="-1">console <a class="header-anchor" href="#console" aria-hidden="true">#</a></h4><ul><li><code>console.log</code> 打印内容到stdout并加上换行符</li><li><code>console.clear</code> 清空当前stdout中的内容</li><li><code>console.trace</code> 打印字符串<code>Trace: </code>到stderr <ul><li>将堆栈跟踪打印到代码中的当前位置</li></ul></li></ul><h4 id="repl" tabindex="-1">REPL <a class="header-anchor" href="#repl" aria-hidden="true">#</a></h4><p>在浏览器的控制台选项卡中,我们可以通过输入JS代码与之交互,在Node.js中同样提供了类似的功能</p><ul><li>REPL是Read-Eval-Print Loop的简称,翻译为:读取-求值-输出循环</li><li>REPL是一个<strong>简单的、交互式的编程环境</strong></li><li>在命令行窗口中输入<code>node</code>即可进入</li></ul><h3 id="node中的全局对象" tabindex="-1">Node中的全局对象 <a class="header-anchor" href="#node中的全局对象" aria-hidden="true">#</a></h3><p>在浏览器中,我们可以在JS代码中访问全局对象<code>window</code>,代表当前标签窗口</p><p>在Node.js中的全局对象名为<code>global</code>,在控制台输出<code>global</code>对象:</p><div class="language-sh line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#89DDFF;">></span><span style="color:#A6ACCD;"> global</span></span>
|
||
<span class="line"><span style="color:#89DDFF;"><</span><span style="color:#A6ACCD;">ref </span><span style="color:#89DDFF;">*</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">></span><span style="color:#A6ACCD;"> Object </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">global</span><span style="color:#89DDFF;">]</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">global:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">Circular </span><span style="color:#89DDFF;">*</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">]</span><span style="color:#A6ACCD;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">clearInterval:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">Function: clearInterval</span><span style="color:#89DDFF;">]</span><span style="color:#A6ACCD;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">clearTimeout:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">Function: clearTimeout</span><span style="color:#89DDFF;">]</span><span style="color:#A6ACCD;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">setInterval:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">Function: setInterval</span><span style="color:#89DDFF;">]</span><span style="color:#A6ACCD;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">setTimeout:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">Function: setTimeout</span><span style="color:#89DDFF;">]</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">Symbol(nodejs.util.promisify.custom)</span><span style="color:#89DDFF;">]</span><span style="color:#82AAFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">Getter</span><span style="color:#89DDFF;">]</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">queueMicrotask:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">Function: queueMicrotask</span><span style="color:#89DDFF;">]</span><span style="color:#A6ACCD;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">performance:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">Performance</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">nodeTiming:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">PerformanceNodeTiming</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">name:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">node</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">entryType:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">node</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">startTime:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span><span style="color:#C3E88D;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">duration:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2245.9675999991596</span><span style="color:#C3E88D;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">nodeStart:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1.7120999991893768</span><span style="color:#C3E88D;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">v8Start:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">7.749699998646975</span><span style="color:#C3E88D;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">bootstrapComplete:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">56.47019999846816</span><span style="color:#C3E88D;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">environment:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">28.44789999909699</span><span style="color:#C3E88D;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">loopStart:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">97.62589999847114</span><span style="color:#C3E88D;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">loopExit:</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">-1,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">idleTime:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2070.0206</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> },</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">timeOrigin:</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1675854922619.539</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> },</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">clearImmediate:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">Function: clearImmediate</span><span style="color:#89DDFF;">]</span><span style="color:#A6ACCD;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#FFCB6B;">setImmediate:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">Function: setImmediate</span><span style="color:#89DDFF;">]</span><span style="color:#A6ACCD;"> </span><span style="color:#C3E88D;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">Symbol(nodejs.util.promisify.custom)</span><span style="color:#89DDFF;">]</span><span style="color:#82AAFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">[</span><span style="color:#A6ACCD;">Getter</span><span style="color:#89DDFF;">]</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> }</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br></div></div><h4 id="常见的全局对象" tabindex="-1">常见的全局对象 <a class="header-anchor" href="#常见的全局对象" aria-hidden="true">#</a></h4><ul><li><code>Buffer</code></li><li><code>clearImmediate</code></li><li><code>clearInterval</code></li><li><code>clearTimeout</code></li><li><code>console</code><ul><li>和控制台交互</li></ul></li><li><code>process</code><ul><li>提供了Node进程中相关的信息</li><li>Node的运行环境、系统环境变量、参数等</li></ul></li><li><code>queueMicrotask(callback)</code></li><li><code>setImmediate(callback, [, ...args])</code></li><li><code>setInterval(callback, delay[, ...args])</code></li><li><code>setTimeout(callback, delay[, ...args])</code></li><li><code>TextDecoder</code></li><li><code>TextEncoder</code></li><li><code>URL</code></li><li><code>URLSearchParams</code></li><li><code>WebAssembly</code></li></ul><h4 id="特殊的全局对象" tabindex="-1">特殊的全局对象 <a class="header-anchor" href="#特殊的全局对象" aria-hidden="true">#</a></h4><p><code>__dirname</code> <code>__filename</code> <code>exports</code> <code>module</code> <code>require()</code></p><ul><li>这些变量看起来是全局的,其实并不是(它们仅存在于模块范围内),只是每个模块中都有</li><li>它们在命令行交互中是不可使用的</li><li><code>__dirname</code> 当前模块的目录名</li><li><code>__filename</code> 当前模块的文件名</li><li><code>exports</code> <code>module</code> <code>require()</code>将在模块章节中讲解</li></ul><h4 id="global对象" tabindex="-1"><code>global</code>对象 <a class="header-anchor" href="#global对象" aria-hidden="true">#</a></h4><p><code>global</code>是一个全局对象</p><ul><li>在Node.js环境下,之前的 <code>process</code> <code>console</code> <code>setTimeout</code>等都有被放入到<code>global</code>中</li><li>而在浏览器中,这些全局API是被放到<code>window</code>对象上的</li></ul><p>这无异于增加了开发者的心智负担,所以在最新的ECMA标准中出现了<code>globalThis</code>,指向全局对象</p><ul><li>在浏览器中的<code>globalThis</code>指向<code>window</code>对象</li><li>在Node.js中的<code>globalThis</code>指向<code>global</code>对象</li></ul><p>两个全局对象的区别:在浏览器中通过<code>var</code>定义的变量会被放到<code>window</code>对象上,而Node.js不会</p><h2 id="模块化开发" tabindex="-1">模块化开发 <a class="header-anchor" href="#模块化开发" aria-hidden="true">#</a></h2><ul><li>认识模块化开发</li><li>CommonJS和Node</li><li>require函数解析</li><li>AMD和CMD(已经被时代淘汰 了解即可)</li><li>ESModule用法详解</li><li>ESModule运行原理</li></ul><h3 id="模块化的初衷" tabindex="-1">模块化的初衷 <a class="header-anchor" href="#模块化的初衷" aria-hidden="true">#</a></h3><ul><li>将大的程序拆分成一个个小的易于维护的代码</li><li>每个模块负责程序中的一部分逻辑,拥有<strong>自己的作用域</strong>、<strong>定义变量名时不会发生冲突</strong></li><li>模块可以暴露<strong>变量、函数、对象</strong>等导出</li><li>模块可以导入其他模块的<strong>变量、函数、对象</strong></li></ul><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// moduleA.js</span></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> moduleA </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> (</span><span style="color:#C792EA;">function</span><span style="color:#89DDFF;">(){</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">name</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">"</span><span style="color:#C3E88D;">Ziu</span><span style="color:#89DDFF;">"</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">age</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">18</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">run</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">()</span><span style="color:#F07178;"> </span><span style="color:#C792EA;">=></span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">name</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">+</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">age</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">+</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">is running.</span><span style="color:#89DDFF;">'</span><span style="color:#F07178;">)</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">name</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">age</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">run</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)()</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#676E95;font-style:italic;">// moduleB.js</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(moduleA</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">name) </span><span style="color:#676E95;font-style:italic;">// 在其他模块中调用</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br></div></div><h3 id="commonjs" tabindex="-1">CommonJS <a class="header-anchor" href="#commonjs" aria-hidden="true">#</a></h3><p>CommonJS是一种<strong>规范</strong>,当初命名为ServerJS,旨在浏览器以外的地方使用,后为体现其广泛性,改名为CommonJS,简称CJS</p><p><strong>规范 是用来指导 实现的</strong></p><ul><li><code>Node</code> 是CommonJS在服务端的代表<strong>实现</strong></li><li><code>Browserify</code> 是CommonJS在浏览器中的一种<strong>实现</strong> (正在被淘汰)</li><li><code>WebPack</code> 打包工具具备支持CommonJS的支持和转换</li></ul><p>所以,Node.js对CommonJS进行了支持和实现,让JavaScript在Node上运行时可以实现模块化开发</p><ul><li>每个<code>.js</code>文件都是一个单独的模块</li><li>每个模块中都包含变量<code>exports</code> <code>module.exports</code> <code>require</code></li></ul><div class="vp-code-group"><div class="tabs"><input type="radio" name="group-F_aXn" id="tab-TxsEzVK" checked="checked"><label for="tab-TxsEzVK">env.js</label><input type="radio" name="group-F_aXn" id="tab-t7XhYd2"><label for="tab-t7XhYd2">utils.js</label><input type="radio" name="group-F_aXn" id="tab-JDMSuc7"><label for="tab-JDMSuc7">index.js</label></div><div class="blocks"><div class="language-js active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// env.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">exports.</span><span style="color:#A6ACCD;">name </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">Ziu</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">exports.</span><span style="color:#A6ACCD;">age </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">18</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// utils.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">module.exports</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">sum</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">function</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">x</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#A6ACCD;font-style:italic;">y</span><span style="color:#89DDFF;">)</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;font-style:italic;">return</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">x</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">+</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">y</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// index.js</span></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> utils </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">require</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">utils.js</span><span style="color:#89DDFF;">'</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;">utils</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">sum</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 3</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> sum </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">require</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">utils.js</span><span style="color:#89DDFF;">'</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"><span style="color:#82AAFF;">sum</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">1</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2</span><span style="color:#A6ACCD;">) </span><span style="color:#676E95;font-style:italic;">// 3</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span><span style="color:#A6ACCD;"> name</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> age </span><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">require</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">env.js</span><span style="color:#89DDFF;">'</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(name</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;"> age) </span><span style="color:#676E95;font-style:italic;">// Ziu 18</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div></div></div><h4 id="exports的本质" tabindex="-1"><code>exports</code>的本质 <a class="header-anchor" href="#exports的本质" aria-hidden="true">#</a></h4><p><code>exports</code>和<code>require</code>在Node中的本质</p><ul><li><code>exports</code>是一个对象,我们可以在这个对象中添加很多属性,添加的属性则会被导出 <ul><li>在没有向该对象添加任何属性之前,它是一个空对象</li></ul></li><li>当通过<code>require</code>导入时:<code>const env = require('env.js')</code><ul><li><code>env</code>这个变量等于<code>env.js</code>中的<code>exports</code>对象</li><li>本质上是<code>env</code>是<code>exports</code>对象的引用赋值</li></ul></li></ul><div class="vp-code-group"><div class="tabs"><input type="radio" name="group-iKNI6" id="tab-qXy9i5t" checked="checked"><label for="tab-qXy9i5t">utils.js</label><input type="radio" name="group-iKNI6" id="tab-4q1AmMr"><label for="tab-4q1AmMr">index.js</label></div><div class="blocks"><div class="language-js active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// utils.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">exports.</span><span style="color:#A6ACCD;">a </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">0</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#676E95;font-style:italic;">// 1s后修改a值</span></span>
|
||
<span class="line"><span style="color:#82AAFF;">setTimeout</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#89DDFF;">exports.</span><span style="color:#A6ACCD;">a</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">1</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">},</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1000</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#676E95;font-style:italic;">// 2s后检查a值</span></span>
|
||
<span class="line"><span style="color:#82AAFF;">setTimeout</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">exports.</span><span style="color:#A6ACCD;">a</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">// 2</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">},</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">2000</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// index.js</span></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> utils </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">require</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">./utils</span><span style="color:#89DDFF;">'</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(utils</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">a) </span><span style="color:#676E95;font-style:italic;">// 0</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#82AAFF;">setTimeout</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">utils</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">a</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">// 1</span></span>
|
||
<span class="line"><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">utils</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">a</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">2</span><span style="color:#F07178;"> </span><span style="color:#676E95;font-style:italic;">// 反过来修改a值</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">},</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">1500</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div></div></div><p>在上述代码中,<code>utils</code>对象中的属性<code>a</code>在一秒后被赋值为<code>1</code>,因此在index.js中输出<code>utils.a</code>得到了两次不同的结果</p><p>反过来,在index.js中修改导入的<code>utils.a</code>的值后,修改结果也会反映在<code>exports.a</code>上,输出的值为<code>2</code></p><p>实际开发中不要修改导入模块中的变量,改变原模块中变量的值并不规范</p><h4 id="module-exports" tabindex="-1"><code>module.exports</code> <a class="header-anchor" href="#module-exports" aria-hidden="true">#</a></h4><p>在Node.js中,真正常用的导出方式是<code>module.exports</code></p><ul><li><code>module.exports</code>本质上就是<code>exports</code>对象(同一个内存地址)</li><li>可以直接给<code>exports</code>对象赋值,将需要导出的内容统一导出</li><li>给<code>module.exports</code>重新赋值,即改变了<code>exports</code>对象的指向,<strong>后续的修改不再影响原模块中的变量</strong></li></ul><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> name </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">Ziu</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> run </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">()</span><span style="color:#A6ACCD;"> </span><span style="color:#C792EA;">=></span><span style="color:#A6ACCD;"> console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(name </span><span style="color:#89DDFF;">+</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">is running.</span><span style="color:#89DDFF;">'</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#89DDFF;">module.exports</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> name</span><span style="color:#89DDFF;">,</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> run</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><h4 id="二者的区别" tabindex="-1">二者的区别 <a class="header-anchor" href="#二者的区别" aria-hidden="true">#</a></h4><p>既然如此,为什么还要存在<code>exports</code>这个概念呢?</p><ul><li>在CommonJS中是没有<code>module.exports</code>的概念的</li><li>为了实现模块的导出,Node.js使用的是<code>Module</code>类,每一个模块都是<code>Module</code>的实例,也就是<code>module</code></li><li>所以在Node.js中真正用于导出的并不是<code>exports</code>,而是<code>module.exports</code></li><li><code>module</code>对象中的<code>exports</code>属性是<code>exports</code>对象的一个引用 <ul><li><code>module.exports === exports === utils</code></li></ul></li></ul><p>如果<code>module.exports</code>不再引用<code>exports</code>对象了,修改<code>exports</code>对象也就没有意义了</p><div class="vp-code-group"><div class="tabs"><input type="radio" name="group-txLdb" id="tab-EFVDb1J" checked="checked"><label for="tab-EFVDb1J">utils.js</label><input type="radio" name="group-txLdb" id="tab-5r1zvs3"><label for="tab-5r1zvs3">index.js</label></div><div class="blocks"><div class="language-js active line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// utils.js</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">module.exports</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">{</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;"> </span><span style="color:#F07178;">name</span><span style="color:#89DDFF;">:</span><span style="color:#A6ACCD;"> </span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">Ziu</span><span style="color:#89DDFF;">'</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">}</span></span>
|
||
<span class="line"><span style="color:#89DDFF;">exports.</span><span style="color:#A6ACCD;">age </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#F78C6C;">18</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-theme-palenight"><code><span class="line"><span style="color:#676E95;font-style:italic;">// index.js</span></span>
|
||
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> utils </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">require</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">'</span><span style="color:#C3E88D;">utils.js</span><span style="color:#89DDFF;">'</span><span style="color:#A6ACCD;">)</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(utils</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">name) </span><span style="color:#676E95;font-style:italic;">// Ziu</span></span>
|
||
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(utils</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">age) </span><span style="color:#676E95;font-style:italic;">// undefined</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers-wrapper" aria-hidden="true"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div></div></div><p>当使用<code>module.exports = { ... }</code>后,模块中原有的<code>exports</code>不再被导入识别,导入的内容将变为<code>module.exports</code>指定的对象内容</p><h4 id="require的本质" tabindex="-1"><code>require</code>的本质 <a class="header-anchor" href="#require的本质" aria-hidden="true">#</a></h4><p><code>require</code>是一个函数,可以帮助我们导入一个文件(模块)中导出的对象</p><ul><li>为什么可以省略掉<code>.js</code>后缀,直接使用<code>require('./utils')</code></li><li>为什么可以省略掉<code>index.js</code>,直接使用<code>require('./tools')</code>导入<code>tools/index.js</code></li></ul><p>这涉及到<code>require</code>在匹配路径后的查找规则:</p><p>分为三种情况:<strong>内置模块、自定义路径、包名</strong></p><ul><li>导入Node.js内置的模块,如<code>const path = require('path')</code><ul><li>直接返回该内置模块 并停止后续的查找</li></ul></li><li>根据路径导入自定义的模块,如<code>const utils = require('./{filename}')</code><ul><li>按照路径寻找该模块<code>./</code> <code>../</code> <code>/</code></li><li>如果指定了后缀名,则按照后缀名查找</li><li>如果未指定后缀名,则: <ol><li>直接查找该文件</li><li>查找<code>{filename}.js</code>文件</li><li>查找<code>{filename}.json</code>文件</li><li>查找<code>{filename}.node</code>文件</li></ol></li><li>如果按照上述方式没找到文件,则<strong>将<code>{filename}</code>作为路径继续查找</strong></li><li>查找目录下的<code>index</code>文件 <code>{filename}/index</code><ol><li>查找<code>{filename}/index.js</code>文件</li><li>··· ···</li></ol></li><li>没找到:报错<code>Cannot find module 'xxx'</code></li></ul></li><li>包名,如<code>const lodash = require('lodash')</code><ul><li>到项目根目录的<code>node_modules</code>中查找</li><li><code>node_modules/{package_name}/index.js</code></li><li>当前项目目录的<code>node_modules</code>找不到则继续向上查找,直到查找到根目录的<code>node_modules</code></li></ul></li></ul><h4 id="模块的加载过程" tabindex="-1">模块的加载过程 <a class="header-anchor" href="#模块的加载过程" aria-hidden="true">#</a></h4><ul><li>模块在被第一次引入时,模块中的JS代码会被运行一次 <ul><li>代码执行顺序与<code>require</code>的位置相关</li></ul></li><li>模块如果被多次引入,会被缓存,最终只加载一次 <ul><li>这是因为每个模块对象<code>module</code>上都有一个属性<code>loaded</code></li><li><code>loaded === false</code>表示该模块尚未被加载</li><li>第二次被<code>require</code>引入时会检查该属性是否为<code>true</code></li></ul></li><li>如果有循环引用,加载顺序如何? <ul><li>数据结构:图结构(graph)遍历时有深度优先搜索(DFS)、广度优先搜索(BFS)两种算法</li><li>Node采用的是深度优先算法</li></ul></li></ul><h4 id="commonjs的缺点" tabindex="-1">CommonJS的缺点 <a class="header-anchor" href="#commonjs的缺点" aria-hidden="true">#</a></h4><ul><li>加载模块是同步加载的 <ul><li>只有等到对应的模块加载完毕,当前模块中的内容才能被执行</li><li>当然,在服务器中加载JS文件都是本地文件,加载速度非常快,不会受影响</li></ul></li><li>但是在浏览器中使用CommonJS <ul><li>需要先从服务器下载JS文件,后加载运行</li><li>阻塞JS执行 阻塞页面加载</li></ul></li><li>在WebPack中使用CommonJS <ul><li>CommonJS会被WebPack解析</li><li>将CommonJS代码转化为bundle 浏览器可以直接运行</li></ul></li></ul>`,76),p=[o];function c(r,t,i,d,y,C){return n(),a("div",null,p)}const F=s(e,[["render",c]]);export{A as __pageData,F as default};
|