<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>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 自己實現一個模塊加載器——bodule.js > shut up, show me the code! 要想真正地了解一個加載器是如何工作的,就是自己實現一個!讓我們來一步一步地實現一個名為bodule.js的模塊加載器。 ## 約定 一個模塊系統,必然有一些約定,下面是bodule.js的規范。 ### 模塊 bodule.js的模塊由以下幾個概念組成: * url,一個url地址對應一個模塊; * meta module:如下形式為一個meta module: **define(id, dependancies?, factory)** id必須為完整的url,dependancies如果沒有依賴,則可以省略,factory包含兩種形式: Function:function(require, [exports,] [module]): 非Function:直接作為該meta模塊的exports。 ~~~ define('http://bodule.org/island205/venus/1.0.0/venus', ['./vango'], function (require, exports, module) { //CommonJS }) // or define('http://bodule.org/island205/venus/1.0.0/conststring', 'bodule.js') // even or define('http://bodule.org/island205/venus/1.0.0/undefined', undefined) ~~~ dependancies中的字符串以及CommonJS中的require的參數,必須為url、相對路徑或頂級路徑的解析依賴于前面的id。 * 一個模塊文件包含一個或多個meta module,但是,在該模塊文件中,必須包含一個該模塊文件url作為id的meta module,例如: `http://bodule.org/island205/venus/1.0.0/venus.js`?對應的模塊文件內容為: ~~~ define('http://bodule.org/island205/venus/1.0.0/venus', ['./vango'], function (require, exports, module) { //CommonJS for venus }) define('http://bodule.org/venus/1.0.0/vango', [], function (require, exports, module) { //CommonJS for vango }) ~~~ 該模塊文件包含兩個meta module,而第一個是必須的。但這兩個meta模塊的順序不做要求。 ### 簡化 為了簡化代碼,針對 ~~~ define('http://bodule.org/island205/venus/1.0.0/venus', ['./vango'], function (require, exports, module) { //CommonJS for venus }) ~~~ 這樣的代碼我們可以將其簡化為: ~~~ define('./venus/1.0.0/venus', ['./vango'], function (require, exports, module) { //CommonJS for venus }) ~~~ 或者: ~~~ define('/venus/1.0.0/venus', ['./vango'], function (require, exports, module) { //CommonJS for venus }) ~~~ 這樣的形式,然相對路徑或者頂級路徑必須要由一個絕對路徑可參照,在bodule.js中,這個絕對路徑來自于當前頁面的url地址,或者使用bodule.package進行配置。 ### bodule cloud 在node中,可以使用require('underscore')來引用node_modules中的模塊,作為bodule.js的目標,將commonjs橋接到瀏覽器端來使用,所以允許使用類似的寫法,這種模塊我們把它稱作bodule模塊,resovle后映射到`http://bodule.org/underscore/stable`,bodule.js會在bodule.org上提供一個云服務,來支持你從這里加載這些bodule模塊。 如果你想使用自己的bodule服務器,可以使用bodule.package來配置boduleServer。 ### npm npm非常流行,bodule.js將其作為模塊的源。我們采取與npm包一致的策略。典型的npm的package.json為(以underscore為例): ~~~ { "name" : "underscore", "description" : "JavaScript's functional programming helper library.", "homepage" : "http://underscorejs.org", "keywords" : ["util", "functional", "server", "client", "browser"], "author" : "Jeremy Ashkenas <jeremy@documentcloud.org>", "repository" : {"type": "git", "url": "git://github.com/jashkenas/underscore.git"}, "main" : "underscore.js", "version" : "1.5.1", "devDependencies": { "phantomjs": "1.9.0-1" }, "scripts": { "test": "phantomjs test/vendor/runner.js test/index.html?noglobals=true" }, "licenses": [ { "type": "MIT", "url": "https://raw.github.com/jashkenas/underscore/master/LICENSE" } ], "files" : ["underscore.js", "LICENSE"] } ~~~ bodule.js將會使用工具將其轉化為bodule模塊,最終會以`http://bodule.org/underscore/1.5.1`這樣的地址地提供出來。注意:該地址會根據package.json中的main,變為`http://bodule.org/underscore/1.5.1/underscore`。 ## bodule.js的API ### .use #### .use(id) 在頁面中使用一個模塊,相當于`node id.js`。 #### .use(dependancies, factory) 在頁面上定義一個即時的模塊,該模塊依賴于dependancies,并use該模塊。等價于: ~~~ define('a-random-id', dependencies, factory) Bodule.use('a-random-id') ~~~ .use比較簡單的例子,[simplest.html](https://github.com/Bodule/bodule-engine/blob/master/test/simplest.html#L10): ~~~ <script type="text/javascript"> Bodule.use('./a.js') Bodule.use('/b.js') Bodule.use(['./c.js', './d'], function (require, exports, module) { var c = require('./c.js') var d = require('./d') console.log(c + d) }) Bodule.use(['./e'], function (require) { var e = require('./e') console.log(e) }) </script> ~~~ ### define #### define(id, dependencies, factory) 定義一個meta module; #### define(id, anythingNotFunction) 定義一個meta module,該模塊的exports即為anythingNotFunction; 幾個例子:[d.js](https://github.com/Bodule/bodule-engine/blob/master/test/d.js),[e.js](https://github.com/Bodule/bodule-engine/blob/master/test/e.js),[backbone.js](https://github.com/Bodule/bodule-engine/blob/master/bodule.org/bower_components/backbone/1.0.0/backbone.js) ### .package(config) 配置模塊和bodule模塊的位置,還可以配置依賴的bodule模塊的版本號。 ~~~ Bodule.package({ cwd: 'http://bodule.org:8080/', path: '/bodule.org/', bodule_modules:{ cwd: 'http://bodule.org:3000/', path: '/bower_components/', dependencies: { 'backbone': '1.0.0' } } }) ~~~ 完整的例子可以參考[bodule.org.html](https://github.com/Bodule/bodule-engine/blob/master/test/bodule.org/bodule.org.html)。 讓我們開始吧! ## coffeescript coffeescript是一門非常有趣的語言,敲起代碼來很舒服,不會被JavaScript各種繁瑣的細節所煩擾。所以我打算使用它來實現bodule.js。訪問[coffeescript.org],上面有簡潔文檔,如果你熟悉JavaScript,我相信你能很快掌握CoffeeScript的。 ## commonjs運行時 從bodule的規范中,可以看出,它其實commonjs,或者說是commonjs wrapping的一個實現。因此,我們將直接使用commonjs的方式來組織我們的代碼,你會發現,這樣的代碼非常清晰易讀。 ~~~ # This is a **private** CommonJS runtime for `bodule.js`. # `__modules` for store private module like `util`,`path`, and so on. modules = {} # `__require` is used for getting module's API: `exports` property. require = (id)-> module = modules[id] module.exports or module.exports = use [], module.factory # Define a module, save module in `__modules`. use `id` to refer them. define = (id, deps, factory)-> modules[id] = id: id deps: deps factory:factory # `__use` to start a CommonJS runtime, or get a module's exports. use = (deps, factory)-> module = {} exports = module.exports = {} # In factory `call`, `this` is global factory require, exports, module module.exports ~~~ 上面這段代碼是commonjs規范一種精簡的表達,出自node項目中的module.js。module.js比這復雜多了,包含了多native module、讀取、執行module文件、以及支持多種格式的module的事情。而我們上面這段代碼就是commonjs最精簡的表達,有了它,我們就可以使用common.js的方式來組織代碼了。 > 注意,代碼中的deps變量完全就是無用的,只是我覺得這樣寫的話,似乎更清晰一點。 ~~~ define 'add', [], (require, exports, module)-> module.exports = (a, b)-> a + b define 'addTwice', ['add'], (require, exports, module)-> add = require 'add' exports.addTwice = (a, b)-> add add(a, b), b use ['addTwice'], (require, exports, module)-> addTwice = require 'addTwice' cosnole.log "#{2} + #{3} + #{3} = #{addTwice 2, 3}" ~~~ 上面的代碼展示了如何使用這個commonjs運行時,很簡單,有木有? > 很簡陋?確實,我們只是用用它來組織代碼,最終實現bodule.js這個復雜的commonjs運行時。 ### bodule API 我們改從何入手編寫一個加載器呢,既然已經有了規范和接口,那我們從接口寫起吧。 ~~~ define 'bodule', [], (require, exports, module)-> Bodule = use: (deps, factory)-> define: (id, deps, factory)-> package: (conf)-> module.exports = Bodule use ['bodule'], (require, exports, module)-> Bodule = require 'bodule' window.Bodule = Bodule window.define = -> Bodule.define.apply Bodule, arguments ~~~
                  <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>

                              哎呀哎呀视频在线观看