webpack與模塊化

模塊化

把復(fù)雜的問題分解成相對(duì)獨(dú)立的模塊,降低程序復(fù)雜性,提高代碼的重用。

  • commonJS
  • AMD
  • CMD
  • UMD
  • ESM

模塊化的核心

  • 獨(dú)立的作用域(一個(gè)文件就是模塊,擁有獨(dú)立的作用域,且導(dǎo)出的模塊都自動(dòng)處于 嚴(yán)格模式下,即'use strict'
  • 如何導(dǎo)出模塊內(nèi)部數(shù)據(jù)
  • 如何導(dǎo)入外部模塊數(shù)據(jù)

導(dǎo)出模塊

// 導(dǎo)出單個(gè)
export let name1,name2, ..., nameN;
export let name1 = ...,name2 = ..., nameN;
export function funName() { ... }
export class className { ... }

// 導(dǎo)出列表
export { name1, name2, ..., nameN };

// 重命令導(dǎo)出
export { variable1 as name1, variable2 as name2, ..., nameN };

// 默認(rèn)導(dǎo)出
export default function(...) {...}
export default expression;
export default function name(...) { ... }
export { name1 as default, ... }

// 模塊重定向?qū)С?export *  from  ...;
export { name1,name2 } from ...;
export { import1 as name1, import2 as name2 } from ...;
export { default } from ...;

導(dǎo)入模塊

靜態(tài)導(dǎo)入
在瀏覽器,import語句只能在聲明了type="module"的 script 的標(biāo)簽中使用

import defaultExport from "module-name";
import * as name from "module-name";
import { export } from "module-name";
import { export as alias } from "module-name";
import { export1 , export2 } from "module-name";
import { foo , bar } from "module-name/path/to/specific/un-exported/file";
import { export1 , export2 as alias2 , [...] } from "module-name";
import defaultExport, { export [ , [...] ] } from "module-name";
import defaultExport, * as name from "module-name";
import "module-name";

靜態(tài)導(dǎo)入方式不支持延遲加載,import 必須這模塊的最開始

document.onclick = function () {
    // import 必須放置在當(dāng)前模塊最開始加載
    import m1 from './m1.js'
    console.log(m1);
}

動(dòng)態(tài)導(dǎo)入

此外,還有一個(gè)類似函數(shù)的動(dòng)態(tài) import(),它不需要依賴 type="module" 的 script 標(biāo)簽。

關(guān)鍵字 import 可以像調(diào)用函數(shù)一樣來動(dòng)態(tài)的導(dǎo)入模塊。以這種方式調(diào)用,將返回一個(gè) promise

import('./m.js')
  .then(m => {
    //...
});
// 也支持 await
let m = await import('./m.js');

通過 import() 方法導(dǎo)入返回的數(shù)據(jù)會(huì)被包裝在一個(gè)對(duì)象中,即使是 default 也是如此

CommonJS

在早起前端對(duì)于模塊化并沒有什么規(guī)范,反而是偏向服務(wù)端的應(yīng)用有更強(qiáng)烈的需求,CommonJS 規(guī)范就是一套偏向服務(wù)端的模塊化規(guī)范,NodeJS 就采用了這個(gè)規(guī)范。

獨(dú)立模塊作用域

一個(gè)文件就是模塊,擁有獨(dú)立的作用域

導(dǎo)出模塊內(nèi)部數(shù)據(jù)

通過 module.exportsexports 對(duì)象導(dǎo)出模塊內(nèi)部數(shù)據(jù)

// a.js
let a = 1;
let b = 2;

module.exports = {
  x: a,
  y: b
}
// or
exports.x = a;
exports.y = b;

導(dǎo)入外部模塊數(shù)據(jù)

通過 require 函數(shù)導(dǎo)入外部模塊數(shù)據(jù)

// b.js
let a = require('./a');
a.x;
a.y;

AMD

因?yàn)?CommonJS 規(guī)范一些特性(基于文件系統(tǒng),同步加載),它并不適用于瀏覽器端,所以另外定義了適用于瀏覽器端的規(guī)范

AMD(Asynchronous Module Definition)

https://github.com/amdjs/amdjs-api/wiki/AMD

瀏覽器并沒有具體實(shí)現(xiàn)該規(guī)范的代碼,我們可以通過一些第三方庫來解決

requireJS

https://requirejs.org/

// 1.html
<script data-main="scripts/main" src="https://cdn.bootcss.com/require.js/2.3.6/require.min.js"></script>

獨(dú)立模塊作用域

通過一個(gè) define 方法來定義一個(gè)模塊,并通過該方法的第二個(gè)回調(diào)函數(shù)參數(shù)來產(chǎn)生獨(dú)立作用域

// scripts/Cart.js
define(function() {
  // 模塊內(nèi)部代碼
})

導(dǎo)出模塊內(nèi)部數(shù)據(jù)

通過 return 導(dǎo)出模塊內(nèi)部數(shù)據(jù)

// scripts/Cart.js
define(function() {
  return class Cart {
    add(item) {
      console.log(`添加商品:${item}`)
    }
  }
})

導(dǎo)入外部模塊數(shù)據(jù)

通過前置依賴列表導(dǎo)入外部模塊數(shù)據(jù)

// scripts/main.js
// 定義一個(gè)模塊,并導(dǎo)入 ./Cart 模塊
define(['./Cart'], function(Cart) {
  let cart = new Cart()
  cart.add({name: 'iphoneXX', price: 1000000})
})

requireJS 的 CommonJS 風(fēng)格

require.js 也支持 CommonJS 風(fēng)格的語法

導(dǎo)出模塊內(nèi)部數(shù)據(jù)

// scripts/Cart.js
define(['require', 'exports', 'module'], function(require, exports, module) {
  class Cart {
    add(item) {
      console.log(`添加商品:${item}`)
    }
  }
  exports.Cart = Cart;
})
// 忽略不需要的依賴導(dǎo)入
define(['exports'], function(exports) {
  class Cart {
    add(item) {
      console.log(`添加商品:${item}`)
    }
  }
  exports.Cart = Cart;
})
// 如果是依賴的導(dǎo)入為:require, exports, module,也可以省略依賴導(dǎo)入聲明
define(function(require, exports, module) {
  class Cart {
    add(item) {
      console.log(`添加商品:${item}`)
    }
  }
  exports.Cart = Cart;
})

導(dǎo)入外部模塊數(shù)據(jù)

// scripts/main.js
define(['./Cart'], function(Cart) {
  let cart = new Cart()
  cart.add({name: 'iphoneXX', price: 1000000})
})

UMD

嚴(yán)格來說,UMD 并不屬于一套模塊規(guī)范,它主要用來處理 CommonJSAMD、CMD 的差異兼容,是模塊代碼能在前面不同的模塊環(huán)境下都能正常運(yùn)行

(function (root, factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        // Node, CommonJS-like
        module.exports = factory(require('jquery'));
    }
    else if (typeof define === "function" && define.amd) {
        // AMD 模塊環(huán)境下
        define(['jquery'], factory);
    }
}(this, function ($) { // $ 要導(dǎo)入的外部依賴模塊
    $('div')
    // ...
    function b(){}
    function c(){}

    // 模塊導(dǎo)出數(shù)據(jù)
    return {
        b: b,
        c: c
    }
}));
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • webpack與模塊化 模塊化已經(jīng)是現(xiàn)代前端開發(fā)中不可或缺的一部分了 把復(fù)雜的問題分解成相對(duì)獨(dú)立的模塊,這樣的設(shè)計(jì)...
    kino2046閱讀 497評(píng)論 0 0
  • 1 Webpack 1.1 概念簡(jiǎn)介 1.1.1 WebPack是什么 1、一個(gè)打包工具 2、一個(gè)模塊加載工具 3...
    Kevin_Junbaozi閱讀 7,022評(píng)論 0 16
  • 因?yàn)閮?nèi)容太多,沒有大綱不方便閱讀,所以也可以跳轉(zhuǎn) 前端各種模塊化方案總結(jié) 附帶大綱[https://tenloy....
    Tenloy閱讀 4,595評(píng)論 0 6
  • 模塊化概述 傳統(tǒng)開發(fā)模式的主要問題① 命名沖突② 文件依賴通過模塊化解決上述問題 模塊化就是把單獨(dú)的一個(gè)功能封裝到...
    檸月如風(fēng)z閱讀 252評(píng)論 0 0
  • 當(dāng)前主流 JS 模塊化方案 CommonJS 規(guī)范,nodejs 實(shí)現(xiàn)的規(guī)范 AMD 規(guī)范,requirejs 實(shí)...
    那少婦閱讀 454評(píng)論 0 0

友情鏈接更多精彩內(nèi)容