前端模塊化開(kāi)發(fā)

1. 前言

現(xiàn)在的前端開(kāi)發(fā), 通常是一個(gè)單頁(yè)面應(yīng)用,每一個(gè)視圖通過(guò)異步的方式加載旱幼,這導(dǎo)致頁(yè)面初始化和使用過(guò)程中會(huì)加載越來(lái)越多的 JS 代碼搂捧,如何在開(kāi)發(fā)環(huán)境組織好這些碎片化的代碼和資源浑此,并且保證他們?cè)跒g覽器端快速蚯妇、優(yōu)雅的加載和更新,就需要一個(gè)模塊化系統(tǒng)涛舍。

1.1 最簡(jiǎn)單的模塊

其實(shí)我們?cè)押瘮?shù)作為模塊,但會(huì)污染全局變量富雅,并且模塊成員之間沒(méi)什么關(guān)系掸驱。這個(gè)時(shí)候我們可以運(yùn)用面向?qū)ο笏枷耄褂昧⒓磮?zhí)行函數(shù)實(shí)現(xiàn)閉包没佑,可以避免變量污染亭敢,同時(shí)同一模塊內(nèi)的成員也有了關(guān)系,在模塊外部無(wú)法修改我們沒(méi)有暴露出來(lái)的變量图筹、函數(shù),這就是簡(jiǎn)單的模塊让腹。但是這樣處理起來(lái)麻煩远剩,并且遠(yuǎn)遠(yuǎn)不夠。

1.2 期望的模塊系統(tǒng)

模塊的加載和傳輸骇窍,我們首先能想到兩種極端的方式瓜晤,一種是每個(gè)模塊文件都單獨(dú)請(qǐng)求,另一種是把所有模塊打包成一個(gè)文件然后只請(qǐng)求一次腹纳。顯而易見(jiàn)痢掠,每個(gè)模塊都發(fā)起單獨(dú)的請(qǐng)求造成了請(qǐng)求次數(shù)過(guò)多驱犹,導(dǎo)致應(yīng)用啟動(dòng)速度慢;一次請(qǐng)求加載所有模塊導(dǎo)致流量浪費(fèi)足画、初始化過(guò)程慢雄驹。這兩種方式都不是好的解決方案,它們過(guò)于簡(jiǎn)單粗暴淹辞。

分塊傳輸医舆,按需進(jìn)行懶加載,在實(shí)際用到某些模塊的時(shí)候再增量更新象缀,才是較為合理的模塊加載方案蔬将。要實(shí)現(xiàn)模塊的按需加載,就需要一個(gè)對(duì)整個(gè)代碼庫(kù)中的模塊進(jìn)行靜態(tài)分析央星、編譯打包的過(guò)程霞怀。

在上面的分析過(guò)程中,我們提到的模塊僅僅是指 JS 模塊文件莉给。然而毙石,在前端開(kāi)發(fā)過(guò)程中還涉及到樣式、圖片禁谦、字體胁黑、HTML 模板等等眾多的資源。如果他們都可以視作模塊州泊,并且都可以通過(guò)require的方式來(lái)加載丧蘸,將帶來(lái)優(yōu)雅的開(kāi)發(fā)體驗(yàn),那么如何做到讓 require 能加載各種資源呢遥皂?在編譯的時(shí)候力喷,要對(duì)整個(gè)代碼進(jìn)行靜態(tài)分析,分析出各個(gè)模塊的類型和它們依賴關(guān)系演训,然后將不同類型的模塊提交給適配的加載器來(lái)處理弟孟。Webpack 就是在這樣的需求中應(yīng)運(yùn)而生。

2. 模塊系統(tǒng)

2.1 script

  • 全局作用域下容易造成變量沖突
  • 文件只能按照 <script> 的書(shū)寫(xiě)順序進(jìn)行加載
  • 開(kāi)發(fā)人員必須主觀解決模塊和代碼庫(kù)的依賴關(guān)系
  • 在大型項(xiàng)目中各種資源難以管理样悟,長(zhǎng)期積累的問(wèn)題導(dǎo)致代碼庫(kù)混亂不堪

2.2 CommonJS

服務(wù)器端的 Node.js 遵循 CommonJS 規(guī)范拂募,該規(guī)范的核心思想是允許模塊通過(guò) require 方法來(lái)同步加載所要依賴的其他模塊,然后通過(guò) exportsmodule.exports 來(lái)導(dǎo)出需要暴露的接口窟她。

require('module');
require('../file.js');
exports.doStuff = function() {};
module.exports = someValue;

// moduleA.js
module.exports = function(value) {
  return value * 2;
};

// moduleB.js
var multiplyBy2 = require('./moduleA');
var result = multiplyBy2(4);

優(yōu)點(diǎn):

  • 服務(wù)器端模塊便于重用
  • NPM 中已經(jīng)有將近 20 萬(wàn)個(gè)可以使用模塊包
  • 簡(jiǎn)單并容易使用

缺點(diǎn):

  • 同步的模塊加載方式不適合在瀏覽器環(huán)境中陈症,同步意味著阻塞加載,瀏覽器資源是異步加載的
  • 不能非阻塞的并行加載多個(gè)模塊

2.3 AMD

define(id?, dependencies?, factory)震糖,它要在聲明模塊的時(shí)候指定所有的依賴 dependencies录肯,并且還要當(dāng)做形參傳到 factory 中,對(duì)于依賴的模塊提前執(zhí)行吊说,依賴前置论咏。

define('module', ['dep1', 'dep2'], function(d1, d2) {
  return someExportedValue;
});
require(['module', '../file'], function(module, file) {
  /* ... */
});

一些用例:
定義一個(gè)名為 myModule 的模塊优炬,它依賴 jQuery 模塊:

define('myModule', ['jquery'], function($) {
  // $ 是 jquery 模塊的輸出
  $('body').text('hello world');
});
// 使用
define(['myModule'], function(myModule) {});

注意:在 webpack 中,模塊名只有局部作用域厅贪,在 Require.js 中模塊名是全局作用域蠢护,可以在全局引用。
定義一個(gè)沒(méi)有 id 值的匿名模塊卦溢,通常作為應(yīng)用的啟動(dòng)函數(shù):

define(['jquery'], function($) {
  $('body').text('hello world');
});

依賴多個(gè)模塊的定義:

define(['jquery', './math.js'], function($, math) {
  // $ 和 math 一次傳入 factory
  $('body').text('hello world');
});

模塊輸出:

define(['jquery'], function($) {
  var HelloWorldize = function(selector) {
    $(selector).text('hello world');
  };

  // HelloWorldize 是該模塊輸出的對(duì)外接口
  return HelloWorldize;
});

在模塊定義內(nèi)部引用依賴:

define(function(require) {
  var $ = require('jquery');
  $('body').text('hello world');
});

優(yōu)點(diǎn):

  • 適合在瀏覽器環(huán)境中異步加載模塊
  • 可以并行加載多個(gè)模塊

缺點(diǎn):

  • 提高了開(kāi)發(fā)成本糊余,代碼的閱讀和書(shū)寫(xiě)比較困難,模塊定義方式的語(yǔ)義不順暢
  • 不符合通用的模塊化思維方式单寂,是一種妥協(xié)的實(shí)現(xiàn)

2.4 CMD

define(function(require, exports, module) {
  var $ = require('jquery');
  var Spinning = require('./spinning');
  exports.doSomething = ...
  module.exports = ...
})

優(yōu)點(diǎn):

  • 依賴就近贬芥,延遲執(zhí)行
  • 可以很容易在 Node.js 中運(yùn)行

缺點(diǎn):

  • 依賴 SPM 打包,模塊的加載邏輯偏重

2.5 UMD (暫未接觸)

2.6 ES6 模塊

ES6 模塊的設(shè)計(jì)思想宣决,是盡量的靜態(tài)化蘸劈,使得編譯時(shí)就能確定模塊的依賴關(guān)系,以及輸入和輸出的變量尊沸。CommonJS 和 AMD 模塊威沫,都只能在運(yùn)行時(shí)確定這些東西。

import "jquery";
export function doStuff() {}
module "localModule" {}

優(yōu)點(diǎn):

  • 容易進(jìn)行靜態(tài)分析
  • 面向未來(lái)的 EcmaScript 標(biāo)準(zhǔn)

缺點(diǎn):

  • 原生瀏覽器端還沒(méi)有實(shí)現(xiàn)該標(biāo)準(zhǔn)
  • 全新的命令字洼专,新版的 Node.js 才支持

實(shí)現(xiàn):

3. 模塊系統(tǒng)/規(guī)范對(duì)比

3.1 AMD 與 CMD

從前有兩個(gè)規(guī)范棒掠,一個(gè)是 AMD,一個(gè)是 CMD屁商。RequireJS 是 AMD 規(guī)范的實(shí)現(xiàn)烟很,SeaJS 是 CMD 規(guī)范的實(shí)現(xiàn)。一個(gè)主張?zhí)崆凹虞d依賴蜡镶,一個(gè)主張延遲加載依賴雾袱。后來(lái)出現(xiàn)了 CommomJS 規(guī)范,CommomJS 是服務(wù)端規(guī)范官还,node 就是采用這個(gè)規(guī)范芹橡,他是同步加載,畢竟服務(wù)端不用考慮異步望伦。

3.2 AMD 與 CommonJs

AMD 的應(yīng)用場(chǎng)景則是瀏覽器林说,異步加載的模塊機(jī)制。require.js 的寫(xiě)法大致如下:

define(['firstModule'], function(module) {
  //your code...
  return anotherModule;
});

CommonJs 是應(yīng)用在 NodeJs屯伞,是一種同步的模塊機(jī)制述么。它的寫(xiě)法大致如下:

var firstModule = require('firstModule');
//your code...
module.export = anotherModule;

其實(shí)我們單比較寫(xiě)法,就知道 CommonJs 是更為優(yōu)秀的愕掏。它是一種同步的寫(xiě)法,友好而且代碼也不會(huì)繁瑣臃腫顶伞。但更重要的原因是饵撑,隨著 npm 成為主流的 JS 組件發(fā)布平臺(tái)剑梳,越來(lái)越多的前端項(xiàng)目也依賴于 npm 上的項(xiàng)目,或者自身就會(huì)發(fā)布到 npm 平臺(tái)滑潘。所以我們對(duì)如何可以使用 npm 包中的模塊是我們的一大需求垢乙。

3.3 browserify 與 webpack

browserify 工具支持我們直接使用 require()的同步語(yǔ)法去加載 npm 模塊,使用不多這里就不做介紹语卤。

  1. Webpack 其實(shí)就是一個(gè)打包工具追逮,他的思想就是一切皆模塊,css 是模塊粹舵,js 是模塊钮孵,圖片是模塊。并且提供了一些列模塊加載(各種-loader)來(lái)編譯模塊眼滤。官方推薦使用 commonJS 規(guī)范巴席,但是也支持 CMD 和 AMD。無(wú)論是node應(yīng)用模塊诅需,還是webpack配置 漾唉,均是采用CommonJS模塊化規(guī)范。

  2. webpack 支持哪些功能特性:

  • 支持 CommonJs 和 AMD 模塊堰塌,意思也就是我們基本可以無(wú)痛遷移舊項(xiàng)目赵刑。
  • 支持模塊加載器和插件機(jī)制,可對(duì)模塊靈活定制场刑。特別是我最愛(ài)的 babel-loader般此,有效支持 ES6。
  • 可以通過(guò)配置摇邦,打包成多個(gè)文件恤煞。有效利用瀏覽器的緩存功能提升性能。
  • 將樣式文件和圖片等靜態(tài)資源也可視為模塊進(jìn)行打包施籍。配合 loader 加載器居扒,可以支持 sass,less 等 CSS 預(yù)處理器丑慎。
  • 內(nèi)置有 source map喜喂,即使打包在一起依舊方便調(diào)試。
  • 看完上面這些竿裂,可以想象它就是一個(gè)前端工具玉吁,可以讓我們進(jìn)行各種模塊加載,預(yù)處理后腻异,再打包进副。之前我們對(duì)這些的處理是放在 grunt 或 gulp 等前端自動(dòng)化工具中。有了 webpack悔常,我們無(wú)需借助自動(dòng)化工具對(duì)模塊進(jìn)行各種處理影斑,讓我們工具的任務(wù)分的更加清晰给赞。

4. 相關(guān)知識(shí)

4.1 ES6 模塊

4.1.1 對(duì)象的導(dǎo)出

1. export default{
        add(){}
 }
2. export fucntion add(){} 相當(dāng)于 將add方法當(dāng)做一個(gè)屬性掛在到exports對(duì)象

4.1.2 對(duì)象的導(dǎo)入

如果導(dǎo)出的是:export default{ add(){}}
那么可以通過(guò)  import obj from './calc.js'
如果導(dǎo)出的是:
export fucntion add(){} 
export fucntion substrict(){} 
export const PI=3.14
那么可以通過(guò)按需加載 import {add,substrict,PI} from './calc.js'

4.2 Node 模塊

4.2.1 傳統(tǒng)非模塊化開(kāi)發(fā)有如下的缺點(diǎn)

  1. 命名沖突
  2. 文件依賴

4.2.2 前端標(biāo)準(zhǔn)的模塊化規(guī)范

  1. AMD - requirejs
  2. CMD - seajs

4.2.3 服務(wù)器端的模塊化規(guī)范

CommonJS - Node.js

4.2.4 Node 模塊化相關(guān)的規(guī)則

  1. 如何定義模塊:一個(gè) js 文件就是一個(gè)模塊,模塊內(nèi)部的成員都是相互獨(dú)立
  2. 模塊成員的導(dǎo)出和引入:
    exports 與 module 的關(guān)系:module.exports = exports = {};
    模塊成員的導(dǎo)出最終以 module.exports 為準(zhǔn)
    如果要導(dǎo)出單個(gè)的成員或者比較少的成員矫户,一般我們使用 exports 導(dǎo)出片迅;如果要導(dǎo)出的成員比較多,一般我們使用 module.exports 的方式;這兩種方式不能同時(shí)使用
var sum = function(a, b) {
  return parseInt(a) + parseInt(b);
};
// 方法1
// 導(dǎo)出模塊成員
exports.sum = sum;
//引入模塊
var module = require('./xx.js');
var ret = module.sum(12, 13);

// 方法2
// 導(dǎo)出模塊成員
module.exports = sum;
//引入模塊
var module = require('./xx.js');
module();

// // 方法1
// exports.sum = sum;
// exports.subtract = subtract;
//
// var m = require('./05.js');
// var ret = m.sum(1,2);
// var ret1 = m.subtract(1,2);
// console.log(ret,ret1);
//
// // 方法2
// module.exports = {
//     sum : sum,
//     subtract : subtract,
//     multiply : multiply,
//     divide : divide
// }
//
// var m = require('./05.js');
// console.log(m);

4.3 webpack

4.3.1 模塊打包器

根據(jù)模塊的依賴關(guān)系進(jìn)行靜態(tài)分析皆辽,然后將這些模塊按照指定的規(guī)則生成對(duì)應(yīng)的靜態(tài)資源柑蛇。如何在一個(gè)大規(guī)模的代碼庫(kù)中,維護(hù)各種模塊資源的分割和存放驱闷,維護(hù)它們之間的依賴關(guān)系耻台,并且無(wú)縫的將它們整合到一起生成適合瀏覽器端請(qǐng)求加載的靜態(tài)資源。市面上已經(jīng)存在的模塊管理和打包工具并不適合大型的項(xiàng)目遗嗽,尤其單頁(yè)面 Web 應(yīng)用程序粘我。最緊迫的原因是如何在一個(gè)大規(guī)模的代碼庫(kù)中,維護(hù)各種模塊資源的分割和存放痹换,維護(hù)它們之間的依賴關(guān)系征字,并且無(wú)縫的將它們整合到一起生成適合瀏覽器端請(qǐng)求加載的靜態(tài)資源。

這些已有的模塊化工具并不能很好的完成如下的目標(biāo):

  • 將依賴樹(shù)拆分成按需加載的塊
  • 初始化加載的耗時(shí)盡量少
  • 各種靜態(tài)資源都可以視作模塊
  • 將第三方庫(kù)整合成模塊的能力
  • 可以自定義打包邏輯的能力
  • 適合大項(xiàng)目娇豫,無(wú)論是單頁(yè)還是多頁(yè)的 Web 應(yīng)用

4.3.2 Webpack 的特點(diǎn)

Webapck 和其他模塊化工具有什么區(qū)別呢匙姜?

  1. 代碼拆分
    Webpack 有兩種組織模塊依賴的方式,同步和異步冯痢。異步依賴作為分割點(diǎn)氮昧,形成一個(gè)新的塊。在優(yōu)化了依賴樹(shù)后浦楣,每一個(gè)異步區(qū)塊都作為一個(gè)文件被打包袖肥。
  2. Loader
    Webpack 本身只能處理原生的 JavaScript 模塊,但是 loader 轉(zhuǎn)換器可以將各種類型的資源轉(zhuǎn)換成 JavaScript 模塊振劳。這樣椎组,任何資源都可以成為 Webpack 可以處理的模塊。
  3. 智能解析
    Webpack 有一個(gè)智能解析器历恐,幾乎可以處理任何第三方庫(kù)寸癌,無(wú)論它們的模塊形式是 CommonJS、 AMD 還是普通的 JS 文件弱贼。甚至在加載依賴的時(shí)候蒸苇,允許使用動(dòng)態(tài)表達(dá)式 require("./templates/" + name + ".jade")
  4. 插件系統(tǒng)
    Webpack 還有一個(gè)功能豐富的插件系統(tǒng)吮旅。大多數(shù)內(nèi)容功能都是基于這個(gè)插件系統(tǒng)運(yùn)行的溪烤,還可以開(kāi)發(fā)和使用開(kāi)源的 Webpack 插件,來(lái)滿足各式各樣的需求。
  5. 快速運(yùn)行
    Webpack 使用異步 I/O 和多級(jí)緩存提高運(yùn)行效率氛什,這使得 Webpack 能夠以令人難以置信的速度快速增量編譯莺葫。

4.3.3 webpack 是什么?

CommonJS 和 AMD 是用于 JavaScript 模塊管理的兩大規(guī)范枪眉,前者定義的是模塊的同步加載,主要用于 NodeJS再层;而后者則是異步加載贸铜,通過(guò) requirejs 等工具適用于前端。隨著 npm 成為主流的 JavaScript 組件發(fā)布平臺(tái)聂受,越來(lái)越多的前端項(xiàng)目也依賴于 npm 上的項(xiàng)目蒿秦,或者 自身就會(huì)發(fā)布到 npm 平臺(tái)。因此蛋济,讓前端項(xiàng)目更方便的使用 npm 上的資源成為一大需求棍鳖。
web 開(kāi)發(fā)中常用到的靜態(tài)資源主要有 JavaScript、CSS碗旅、圖片渡处、Jade 等文件,webpack 中將靜態(tài)資源文件稱之為模塊祟辟。 webpack 是一個(gè) module bundler(模塊打包工具)医瘫,其可以兼容多種 js 書(shū)寫(xiě)規(guī)范,且可以處理模塊間的依賴關(guān)系旧困,具有更強(qiáng)大的 js 模塊化的功能醇份。Webpack 對(duì)它們進(jìn)行統(tǒng) 一的管理以及打包發(fā)布

4.3.4 為什么使用 webpack?

1. 對(duì) CommonJS 吼具、 AMD 僚纷、ES6 的語(yǔ)法做了兼容
2. 對(duì) js、css拗盒、圖片等資源文件都支持打包
3. 串聯(lián)式模塊加載器以及插件機(jī)制怖竭,讓其具有更好的靈活性和擴(kuò)展性,例如提供對(duì) CoffeeScript锣咒、ES6 的支持
4. 有獨(dú)立的配置文件 webpack.config.js
5. 可以將代碼切割成不同的 chunk侵状,實(shí)現(xiàn)按需加載,降低了初始化時(shí)間
6. 支持 SourceUrls 和 SourceMaps毅整,易于調(diào)試
7. 具有強(qiáng)大的 Plugin 接口趣兄,大多是內(nèi)部插件,使用起來(lái)比較靈活
8.webpack 使用異步 IO 并具有多級(jí)緩存悼嫉。這使得 webpack 很快且在增量編譯上更加快

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末艇潭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蹋凝,老刑警劉巖鲁纠,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異鳍寂,居然都是意外死亡改含,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門迄汛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)捍壤,“玉大人,你說(shuō)我怎么就攤上這事鞍爱【榫酰” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵睹逃,是天一觀的道長(zhǎng)盗扇。 經(jīng)常有香客問(wèn)我,道長(zhǎng)沉填,這世上最難降的妖魔是什么疗隶? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮拜轨,結(jié)果婚禮上抽减,老公的妹妹穿的比我還像新娘。我一直安慰自己橄碾,他們只是感情好卵沉,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著法牲,像睡著了一般史汗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拒垃,一...
    開(kāi)封第一講書(shū)人閱讀 49,816評(píng)論 1 290
  • 那天停撞,我揣著相機(jī)與錄音,去河邊找鬼悼瓮。 笑死戈毒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的横堡。 我是一名探鬼主播埋市,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼命贴!你這毒婦竟也來(lái)了道宅?” 一聲冷哼從身側(cè)響起食听,我...
    開(kāi)封第一講書(shū)人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎污茵,沒(méi)想到半個(gè)月后樱报,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡泞当,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年迹蛤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片襟士。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡笤受,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出敌蜂,到底是詐尸還是另有隱情,我是刑警寧澤津肛,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布章喉,位于F島的核電站,受9級(jí)特大地震影響身坐,放射性物質(zhì)發(fā)生泄漏秸脱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一部蛇、第九天 我趴在偏房一處隱蔽的房頂上張望摊唇。 院中可真熱鬧,春花似錦涯鲁、人聲如沸巷查。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)岛请。三九已至,卻和暖如春警绩,著一層夾襖步出監(jiān)牢的瞬間崇败,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工肩祥, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留后室,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓混狠,卻偏偏與公主長(zhǎng)得像岸霹,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子檀蹋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 前端模塊化開(kāi)發(fā)簡(jiǎn)介 歷史上松申,JavaScript 一直沒(méi)有模塊(module)體系云芦,無(wú)法將一個(gè)大程序拆分成互相依賴...
    榮兒飛閱讀 4,242評(píng)論 0 6
  • 在JavaScript發(fā)展的初期是為了實(shí)現(xiàn)簡(jiǎn)單的頁(yè)面交互邏輯, 就這么一句話. 如今, 瀏覽器性能得到極大的提高,...
    HelloJames閱讀 625評(píng)論 0 2
  • CommonJS 服務(wù)器端的 Node.js 遵循 CommonJS規(guī)范,該規(guī)范的核心思想是允許模塊通過(guò) requ...
    LiLi原上草閱讀 172評(píng)論 0 0
  • 前端模塊化開(kāi)發(fā) 常見(jiàn)的三大模塊化框架贸桶。 CommonJS: 1.根據(jù)CommonJS規(guī)范舅逸,一個(gè)單獨(dú)的文件就是一個(gè)模...
    一長(zhǎng)亭閱讀 332評(píng)論 0 2
  • 概念 模塊化開(kāi)發(fā),一個(gè)模塊就是一個(gè)實(shí)現(xiàn)特定功能的文件皇筛,有了模塊我們就可以更方便的使用別人的代碼琉历,要用什么功能就加載...
    biu丶biubiu閱讀 242評(píng)論 0 0