<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ### 穩定度: 3 - 鎖定 `io.js`又一個簡單的模塊加載系統。在`io.js`中,文件和模塊是一一對應的。以下例子中,`foo.js`加載的同目錄下的`circle.js`。 `foo.js`的內容: ~~~ var circle = require('./circle.js'); console.log( 'The area of a circle of radius 4 is ' + circle.area(4)); ~~~ `circle.js`的內容: ~~~ var PI = Math.PI; exports.area = function (r) { return PI * r * r; }; exports.circumference = function (r) { return 2 * PI * r; }; ~~~ `circle.js`模塊暴露了`area()`函數和`circumference()`函數。想要為你的模塊添加函數或對象,你可以將它們添加至特殊的`exports`對象的屬性上。 模塊的本地變量是私有的,好似模塊被包裹在一個函數中。在這個例子中變量`PI`是`circle.js`私有的。 如果想要你的模塊暴露一個函數(例如一個構造函數),或者想要一次賦值就暴露一個完整的對象,而不是一次綁定一個屬性,那就將之賦值給`module.exports`而不是`exports`。 以下,`bar.js`使用了暴露了一個構造函數的`square`模塊: ~~~ var square = require('./square.js'); var mySquare = square(2); console.log('The area of my square is ' + mySquare.area()); ~~~ `square`模塊內部: ~~~ // assigning to exports will not modify module, must use module.exports module.exports = function(width) { return { area: function() { return width * width; } }; } ~~~ 模塊系統在`require("module")`中被實現。 ### 循環依賴 當存在循環的`require()`調用。一個模塊可能在返回時,被沒有被執行完畢。 考慮一下情況: `a.js`: ~~~ console.log('a starting'); exports.done = false; var b = require('./b.js'); console.log('in a, b.done = %j', b.done); exports.done = true; console.log('a done'); ~~~ `b.js`: ~~~ console.log('b starting'); exports.done = false; var a = require('./a.js'); console.log('in b, a.done = %j', a.done); exports.done = true; console.log('b done'); ~~~ `main.js`: ~~~ console.log('main starting'); var a = require('./a.js'); var b = require('./b.js'); console.log('in main, a.done=%j, b.done=%j', a.done, b.done); ~~~ 當`main.js`加載`a.js`,而后`a.js`會去加載`b.js`。與此同時,`b.js`嘗試去加載`a.js`。為了避免一個無限循環,`a.js`會返回一個未完成的副本給`b.js`模塊。`b.js`會接著完成加載,然后它所暴露的值再被提供給`a.js`模塊。 這樣`main.js`就完成了它們的加載。因此程序的輸出是: ~~~ $ iojs main.js main starting a starting b starting in b, a.done = false b done in a, b.done = true a done in main, a.done=true, b.done=true ~~~ 如果在你的程序里有循環依賴,請確保它們按你的計劃工作。 #### 核心模塊 `io.js`中有一些模塊是被編譯成二進制的。這些模塊會在本文檔的其他地方詳細討論。 核心模塊被定義在`io.js`源碼的`lib/`目錄下。 當被`require()`時,核心模塊總是被優先加載的。例如`require('http')`總是會返回內建的HTTP模塊,甚至是有一個同名文件時。 #### 文件模塊 如果準確的文件名沒有被發現,那么`io.js`將會依次添加`.js`,`.json`或`.node`后綴名,然后試圖去加載。 `.js`文件被解釋為`JavaScript`文本文件,`.json`被解釋為`JSON`文本文件,`.node`文件被解釋為編譯好的插件模塊,然后被`dlopen`加載。 前綴是`'/'`則是文件的絕對路徑。例如`require('/home/marco/foo.js')`將會加載`/home/marco/foo.js`。 前綴是`'./'`則是調用`require()`的文件的相對路徑。也就是說,`circle.js`必須與`foo.js`在同一目錄下,這樣`require('./circle')`才能找到它。 如果沒有`'/'`,`'./'`或`'../'`前綴,模塊要么是一個核心模塊,或是需要從`node_modules`目錄中被加載。 如果指定的路徑不存在,`require()`將會拋出一個`code`屬性是`'MODULE_NOT_FOUND'`的錯誤。 #### 從node_modules目錄中加載 如果傳遞給`require()`的模塊標識符不是一個本地模塊,也沒有以`'/'`,`'../'`或`'./'`開始。那么`io.js`將會從當前目錄的父目錄開始,添加`/node_modules`,試圖從這個路徑來加載模塊。 如果還是沒有找到模塊,那么它會再移至此目錄的父目錄,如此往復,直至到達文件系統的根目錄。 例如,如果一個位于`'/home/ry/projects/foo.js'`的文件調用了`require('bar.js')`,那么`io.js`將會按照以下的路徑順序來查找: ~~~ /home/ry/projects/node_modules/bar.js /home/ry/node_modules/bar.js /home/node_modules/bar.js /node_modules/bar.js ~~~ 這要求程序本地化(localize)自己的依賴,防止它們崩潰。 你也可以在模塊名中加入一個路徑后綴,來引用這個模塊中特定的一個文件或子模塊。例如,`require('example-module/path/to/file')`將會從`example-module`的位置解析相對路徑`path/to/file`。路徑后綴遵循相同的模塊解析語義。 #### 作為模塊的目錄 在一個單獨目錄下組織程序和庫,然后提供一個單獨的入口,是非常便捷的。有三種方法,可以將目錄作為`require()`的參數,來加載模塊。 第一種方法是,在模塊的根目錄下創建一個`package.json`文件,其中指定了`main`模塊。一個示例`package.json`文件: ~~~ { "name" : "some-library", "main" : "./lib/some-library.js" } ~~~ 如果這個文件位于`./some-library`,那么`require('./some-library')`將會試圖去加載`./some-library/lib/some-library.js`。 這就是`io.js`所能夠了解`package.json`文件的程度。 如果目錄中沒有`package.json`文件,那么`io.js`將會視圖去加載當前目錄中的`index.js`或`index.node`。例如,如果在上面的例子中沒有`package.json`,那么`require('./some-library')`將會試圖加載: ~~~ ./some-library/index.js ./some-library/index.node ~~~ #### 緩存 模塊在第一次被加載后,會被緩存。這意味著,如果都解析到了相同的文件,每一次調用`require('foo')`都將會返回同一個對象。 多次調用`require('foo')`可能不會造成模塊代碼被執行多次。這是一個重要的特性。有了它,“部分完成”的對象也可以被返回,這樣,傳遞依賴也能被加載,即使它們可能會造成循環依賴。 如果你想要一個模塊被多次執行,那么就暴露一個函數,然后執行這個函數。 ##### 模塊緩存警告 模塊的緩存依賴于它們被解析后的文件名。所以調用模塊的位置不同,可以會解析出不同的文件名(比如需要從node_modules目錄中加載)。所以不能保證`require('foo')`總是會返回相同的對象,因為它們可能被解析為了不同的文件。 #### module對象 - {Object} 每一個模塊中,變量`module`是一個代表了當前模塊的引用。為了方便,`module.exports`也可以通過模塊作用域中的`exports`取得。`module`對象實際上不是全局的,而是每個模塊本地的。 #### module.exports - Object `module.exports`對象是由模塊系統創建的。有時這是難以接受的;許多人希望它們的模塊是一些類的實例。如果需要這樣,那么就將想要暴露的對象賦值給`module.exports`。注意,將想要暴露的對象傳遞給`exports`,將僅僅只會重新綁定(rebind)本地變量`exports`,所以不要這么做。 例如假設我們正在寫一個叫做`a.js`的模塊: ~~~ var EventEmitter = require('events').EventEmitter; module.exports = new EventEmitter(); // Do some work, and after some time emit // the 'ready' event from the module itself. setTimeout(function() { module.exports.emit('ready'); }, 1000); ~~~ 那么在另一個文件中我們可以: ~~~ var a = require('./a'); a.on('ready', function() { console.log('module a is ready'); }); ~~~ 主要,對`module.exports`的賦值必須立刻完成。它不能在任何的回調函數中完成。以下例子將不能正常工作: `x.js`: ~~~ setTimeout(function() { module.exports = { a: "hello" }; }, 0); ~~~ `y.js`: ~~~ var x = require('./x'); console.log(x.a); ~~~ #### exports快捷方式 `exports`變量是一個`module.exports`的引用。如果你將一個新的值賦予它,那么它將不再指向先前的那個值。 為了說明這個行為,將`require()`的實現假設為這樣: ~~~ function require(...) { // ... function (module, exports) { // Your module code here exports = some_func; // re-assigns exports, exports is no longer // a shortcut, and nothing is exported. module.exports = some_func; // makes your module export 0 } (module, module.exports); return module; } ~~~ 一個指導方針是,如果你弄不清楚`exports`和`module.exports`之間的關系,請只使用`module.exports`。 #### module.require(id) - id String - Return: 被解析的模塊的`module.exports` `module.require`方法提供了一種像`require()`一樣,從源模塊中加載模塊的方法。 注意,為了這么做,你必須取得`module`對象的引用。因為`require()`返回`module.exports`,并且`module`對象是一個典型的只在特定的模塊作用域中有效的變量,如果要使用它,必須被明確地導出。 #### module.id - String 模塊的識別符。通常是被完全解析的文件名。 #### module.filename - String 模塊完全解析后的文件名。 #### module.loaded - Boolean 模塊是否加載完成,或者是正在加載的過程中。 #### module.parent - Module Object 引用這個模塊的模塊。 #### module.children - Array 這個模塊所引入的模塊。 #### 總體來說 為了獲得`require()`被調用時將要被加載的準確文件名,使用`require.resolve()`函數。 綜上所述,以下是一個`require.resolve`所做的事的高級算法偽代碼: ~~~ require(X) from module at path Y 1. If X is a core module, a. return the core module b. STOP 2. If X begins with './' or '/' or '../' a. LOAD_AS_FILE(Y + X) b. LOAD_AS_DIRECTORY(Y + X) 3. LOAD_NODE_MODULES(X, dirname(Y)) 4. THROW "not found" LOAD_AS_FILE(X) 1. If X is a file, load X as JavaScript text. STOP 2. If X.js is a file, load X.js as JavaScript text. STOP 3. If X.json is a file, parse X.json to a JavaScript Object. STOP 4. If X.node is a file, load X.node as binary addon. STOP LOAD_AS_DIRECTORY(X) 1. If X/package.json is a file, a. Parse X/package.json, and look for "main" field. b. let M = X + (json main field) c. LOAD_AS_FILE(M) 2. If X/index.js is a file, load X/index.js as JavaScript text. STOP 3. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP 4. If X/index.node is a file, load X/index.node as binary addon. STOP LOAD_NODE_MODULES(X, START) 1. let DIRS=NODE_MODULES_PATHS(START) 2. for each DIR in DIRS: a. LOAD_AS_FILE(DIR/X) b. LOAD_AS_DIRECTORY(DIR/X) NODE_MODULES_PATHS(START) 1. let PARTS = path split(START) 2. let I = count of PARTS - 1 3. let DIRS = [] 4. while I >= 0, a. if PARTS[I] = "node_modules" CONTINUE c. DIR = path join(PARTS[0 .. I] + "node_modules") b. DIRS = DIRS + DIR c. let I = I - 1 5. return DIRS ~~~ #### 從全局文件夾加載 如果`NODE_PATH`環境變量被設置為了一個以冒號分割的絕對路徑列表,那么在找不到模塊時,`io.js`將會從這些路徑中尋找模塊(注意:在Windows中,`NODE_PATH`是以分號間隔的)。 `NODE_PATH`最初被創建,是用來支持在當前的模塊解析算法被凍結(frozen)前,從不同的路徑加載模塊的。 `NODE_PATH`仍然被支持,但是,如今`io.js`生態圈已經有了放置依賴模塊的公約,它已經不那么必要的。有時,當人們沒有意識到`NODE_PATH`有被設置時,依賴于`NODE_PATH`的部署可能會產生出人意料的表現。有時,一個模塊的依賴改變了,造成了通過`NODE_PATH`,加載了不同版本的模塊。 另外,`io.js`將會查找以下路徑: - 1: $HOME/.node_modules - 2: $HOME/.node_libraries - 3: $PREFIX/lib/node `$HOME`是用戶的家目錄,`$PREFIX`是`io.js`中配置的`node_prefix`。 由于一些歷史原因,高度推薦你將依賴放入`node_modules`目錄。它會被加載的更快,且可靠性更好。 #### 訪問主模塊 當一個文件直接由`io.js`執行,`require.main`將被設置為這個模塊。這意味著你可以判斷一個文件是否是直接被運行的。 ~~~ require.main === module ~~~ 對于一個文件`foo.js`,如果通過`iojs foo.js`運行,以上將會返回`true`。如果通過`require('./foo')`,將會返回`false`。 因為`module`提供了一個`filename`屬性(通常等于`__filename`),所以當前應用的入口點可以通過檢查`require.main.filename`來獲取。 #### 附錄:包管理小貼士 `io.js`的`require()`函數的語義被設計得足夠通用,來支持各種目錄結構。包管理程序諸如`dpkg`,`rpm`和`npm`將可以通過不修改`io.js`模塊,來構建本地包。 以下我們給出一個建議的可行的目錄結構: 假設`/usr/lib/node/<some-package>/<some-version>`中有指定版本包的內容。 包可以依賴于其他包。為了安裝`foo`包,你可能需要安裝特定版本的`bar`包。`bar`包可能有它自己的依賴,在一些情況下,它們的依賴可以會沖突或者產生循環。 由于`io.js`會查找任何它加載的包得真實路徑(也就是說,解析`symlinks`),解析以下結構的方案非常簡單: - /usr/lib/node/foo/1.2.3/ - `foo`包的內容,`1.2.3`版本。 - /usr/lib/node/bar/4.3.2/ - `foo`包所依賴的`bar`包的內容。 - /usr/lib/node/foo/1.2.3/node_modules/bar - 指向`/usr/lib/node/bar/4.3.2/`的符號鏈接。 - /usr/lib/node/bar/4.3.2/node_modules/* - 指向`bar`包所依賴的包的符號鏈接。 因此,即使有循環依賴,或者依賴沖突,每個模塊都能夠獲取它們使用的特定版本的依賴。 當`foo`包中的代碼執行`require('bar')`,將會獲得符號鏈接`/usr/lib/node/foo/1.2.3/node_modules/bar`指向的版本。接著,`bar`包種的代碼執行`require('quux')`,它將會獲得符號鏈接`/usr/lib/node/bar/4.3.2/node_modules/quux`指向的版本。 此外,為了優化模塊查找的過程,我們將模塊放在`/usr/lib/node_modules/<name>/<version>`而不是直接放在`/usr/lib/node`中。然后在找不到依賴時,`io.js`就不會一直去查找`/usr/node_modules`或`/node_modules`目錄了。 為了讓模塊在`io.js`的REPL中可用,可能需要將`/usr/lib/node_modules`目錄加入到`$NODE_PATH`環境變量。因為使用`node_modules`目錄的模塊查找都是使用相對路徑,且基于調用`require()`的文件的真實路徑,因此包本身可以在任何位置。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看