【重要】ES6-23 JavaScript模塊化

  • 前端js模塊化的演變發展
  • 模塊化解決的問題
  • 傳統模塊化、插件化
  • CommonJS
  • AMD/CMD
  • ES6模塊化

ES6以前 沒有js引擎

  1. 一開始js寫在html的script標簽里
  2. js內容增多,抽取出index.js文件,外部引入
  3. js再增加,index.html對應index.js index2.html對應index2.js(模塊化概念的誕生)
  4. 含有可復用的代碼,提出公共的common.js
  5. 引入common.js的所有內容不合理 → 不能光以頁面為基準來區分程序塊、分js文件

案例一 模塊化初試

// index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script type="text/javascript" src="js/module_a.js"></script><script type="text/javascript" src="js/module_b.js"></script><script type="text/javascript" src="js/module_c.js"></script><script type="text/javascript" src="js/index.js"></script>
</body>
</html>
// module_a.js
var a = [1, 2, 3, 4, 5].reverse()
// module_b.js
var b = a.concat([6, 7, 8, 9, 10])
// module_c.js
var c = b.join('-')
// index.js
console.log(a)
console.log(b)
console.log(c)

在這里插入圖片描述

存在問題

  • js引擎遇到script時阻塞,所以這4個js文件必須按內部的邏輯,順序加載,順序是不能變的
  • 這4個文件共用了JS作用域-全局作用域
  • 因此:污染全局 + if 變量重名 → 變量覆蓋

模塊化解決問題:

  1. 加載順序
  2. 污染全局

案例二 IIFE注入

歷史問題:ECMA規定語句應當以分號結尾,早前js都是運行在瀏覽器上的,但瀏覽器支持判斷當前是否是語句,是就自動加上分號。當使用多個IIFE,且不寫分號時,瀏覽器無法識別,報錯。因此約定俗成的規定,IIFE前面必須寫分號,更規范的是結尾也寫分號,即
;(function(){
})();

  1. 使用IIFE,解決污染全局,為了易于拓展,模塊應當返回對象
  2. 新的問題,若沒有拋到全局,如何在模塊之間獲得相應的abc
  3. 用變量接收IIFE的返回值,在需要用的的模塊傳入(注入),解決了模塊依賴
  4. 注意:模塊名完全獨立,不應該重復,因此在全局聲明了,而內部abc屬于數據類型的變量,不能在全局聲明
  5. 注意:不注入moduleABC,直接用moduleA.a訪問變量能得到正確結果,但注入意味著moduleABC被引入到局部作用域下,不再需要去全局上查找了
// module_a.js
var moduleA = (function () {var a = [1, 2, 3, 4, 5].reverse()return {a: a}
})();
// module_b.js
var moduleB = (function (moduleA) {var b = moduleA.a.concat([6, 7, 8, 9, 10])return {b: b}
})(moduleA);
// module_c.js
var moduleC = (function (moduleB) {var c = moduleB.b.join('-')return {c: c}
})(moduleB);
// index.js
; (function (moduleA, moduleB, moduleC) {console.log(moduleA.a)console.log(moduleB.b)console.log(moduleC.c)
})(moduleA, moduleB, moduleC);

存在問題

  1. 順序問題依然未解決

插件

  1. 構造函數執行init
  2. 構造函數掛載到window(插件)
  3. script里實例化
    在這里插入圖片描述
    在這里插入圖片描述

在這里插入圖片描述

案例三 CommonJS

NodeJS誕生帶來了前所未有的模塊化體驗
require(...) 引入模塊
module.exports導出模塊

運行在node環境下

CommonJS是模塊化規范,來源于NodeJS
在服務端開發,引入模塊用require,是同步的方法
只要引用,就會創建模塊的實例
有非常強的緩存機制
一定是在Node上運行,客戶端運行不了(要借助webpack?)
require實質是IIFE,會傳入一些參數
(function(exports,require,module,__filename.__dirname){})()

  • CommonJS
  • 只引入index.js
// index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script type="text/javascript" src="index.js"></script>
</body>
</html>
// module_a.js
var a = (function () {return [1, 2, 3, 4, 5].reverse()
})();
module.exports = {a
};
// module_b.js
var moduleA = require('./module_a')
var b = (function () {return moduleA.a.concat([6, 7, 8, 9, 10])
})();
module.exports = {b
}
// module_c.js
var moduleB = require('./module_b')
var c = (function () {return moduleB.b.join('-')
})();
module.exports = {c: c
}
// index.js
var moduleA = require('./js/module_a.js');
var moduleB = require('./js/module_b.js');
var moduleC = require('./js/module_c.js');
; (function () {console.log(moduleA.a)console.log(moduleB.b)console.log(moduleC.c)
})()

案例四 AMD

  • 不需要借助webpack就能運行在客戶端
  • 所有依賴加載完成后才會執行回調函數(前置依賴)

AMD Asynchronous Module Definition 異步模塊定義
來源于CommonJS
define(moduleName, [module], factory) 定義模塊
require([module], callback) 引入模塊
RequireJS實現AMD

  1. 引入require.js
  2. 定義+使用依賴時注入
  3. 使用module得先require.config配置路徑
// index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="js/require.js"></script><script src="js/index.js"></script>
</body>
</html>
// module_a.js
define('moduleA', function () {var a = [[1, 2, 3, 4, 5]]return {a: a.reverse()}
})
// module_b.js
define('moduleB', ['moduleA'], function (moduleA) {return {b: moduleA.a.concat([6, 7, 8, 9, 10])}
})
// module_c.js
define('moduleC', ['moduleB'], function (moduleB) {return {c: moduleB.b.join('-')}
})
// index.js
require.config({paths: {moduleA: 'js/module_a',moduleB: 'js/module_b',moduleC: 'js/module_c'}
})
require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC) {console.log(moduleA.a)console.log(moduleB.b)console.log(moduleC.c)
});

案例五CMD

  • 阿里對模塊化的貢獻
  • require加載 define定義
  • exports導出(return和它的效果一直) module操作
  • 需要配置模塊URL
  • 依賴加載完畢后執行factory
  • 依賴就近 按需加載(這是和CommonJS AMD本質上的不同)

Common Mudule Definition 通用模塊定義
define(function(require,exports,module){}) 定義模塊
seajs.use([module路徑],function(moduleA,moduleB,moduleC){}) 使用模塊

// index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="js/sea.js"></script><script src="js/index.js"></script>
</body>
</html>
// module_a.js
define(function (require, exports, module) {var a = [[1, 2, 3, 4, 5]]return {a: a.reverse()}
})
// module_b.js
define(function (require, exports, module) {var moduleA = require('module_a')return {b: moduleA.a.concat([6, 7, 8, 9, 10])}
})
// module_c.js
define(function (require, exports, module) {var moduleB = require('module_b')return {c: moduleB.b.join('-')}
})
// index.js
seajs.use(['module_a.js', 'module_b.js', 'module_c.js'], function (moduleA, moduleB, moduleC) {console.log(moduleA.a)console.log(moduleB.b)console.log(moduleC.c)
})

案例六 ES6模塊化規范

import module from ‘模塊路徑’ 導入模塊
export module 導出模塊

Uncaught SyntaxError: Cannot use import statement outside a module

調試過程中的報錯解答

// index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script type="module" src="./js/index.js"></script>
</body>
</html>
// module_a.js
export default {a: [1, 2, 3, 4, 5].reverse()
}
// module_b.js
import moduleA from './module_a.js'
export default {b: moduleA.a.concat([6, 7, 8, 9, 10])
}
// module_c.js
import moduleB from './module_b.js'
export default {c: moduleB.b.join('-')
}
// index.js
import moduleA from './module_a.js'
import moduleB from './module_b.js'
import moduleC from './module_c.js'; (function (moduleA, moduleB, moduleC) {console.log(moduleA.a)console.log(moduleB.b)console.log(moduleC.c)
})(moduleA, moduleB, moduleC);

案例7 CommonJS與ES6的區別

  • 配置webpack
    在這里插入圖片描述
    在這里插入圖片描述
// export.js
exports.a = 0;
setTimeout(() => {console.log('來自export', ++exports.a)
}, 300);
// commonjs.js
const { a } = require('./export')
setTimeout(() => {console.log('來自commonjs', a)
}, 300);
// es6.js
import { a } from './export'
setTimeout(() => {console.log('來自es6', a) // a是只讀的
}, 300);

在這里插入圖片描述

  1. commonjs輸出的是一個值的拷貝
  2. es6模塊輸出的是值的引用
  3. commonjs模塊是在運行時加載(commonjs運行在服務端,require時加載)
  4. es6模塊是在編譯時加載

YUI

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/250963.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/250963.shtml
英文地址,請注明出處:http://en.pswp.cn/news/250963.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Quartz.Net定時任務EF+MVC版的web服務

之前項目采用JAVA 的 Quartz 進行定時服調度務處理程序&#xff0c;目前在.NET下面使用依然可以完成相同的工作任務&#xff0c;其實什么語言不重要&#xff0c;關鍵是我們要學會利用語言實現價值。它是一個簡單的執行任務計劃的組件&#xff0c;基本包括這三部分&#xff1a;J…

jquery --- 多選下拉框的移動(穿梭框)

效果如下: 幾個注意地方: 1.多選下拉框需要添加 multiple 2.獲取選中的元素KaTeX parse error: Expected EOF, got # at position 3: (#?id option:selec…(#id option:not(:selected)) 下面是代碼的各個部分實現, 方便引用,最后是總體代碼,方便理解 添加選中到右邊: // …

ES6-24 生成器與迭代器的應用

手寫生成器 先done再false&#xff0c;不然index就提前了一步1 var arr [1,2] function generator(arr){var i 0;return{next(){var done i > arr.length ? true : false,value done ? undefined : arr[i];return {value : value,done : done} }} } var gen gener…

1013 B. And

鏈接 [http://codeforces.com/contest/1013/problem/B] 題意 給你一個n和x,再給n個數&#xff0c;有一種操作用x&a[i]取代&#xff0c;a[i],問使其中至少兩個數相同&#xff0c;要多少次操作&#xff0c;如果不能輸出-1. 思路 x&a[i],無論&多少次&#xff0c;a[i]都…

jquery --- 收縮兄弟元素

點擊高亮的收縮兄弟元素. 思路: 1.點擊的其實是tr.(類為parent) 2.toggleClass可以切換樣式 3.slblings(’.class’).toggle 可以根據其類來進行隱藏顯示 代碼如下: <!DOCTYPE html> <html> <head> <meta charset"utf-8"><style>.pa…

Webpack基礎

path.resolve // 只要以/開頭&#xff0c;就變為絕對路徑 // ./和直接寫效果相同 var path require("path") //引入node的path模塊path.resolve(/foo/bar, ./baz) // returns /foo/bar/baz path.resolve(/foo/bar, baz) // returns /foo/bar/baz path.res…

(php)實現萬年歷

1 <?php2 //修改頁面編碼3 header("content-type:text/html;charsetutf-8");4 5 //獲取當前年6 $year$_GET[y]?$_GET[y]:date(Y);7 8 //獲取當年月9 $month$_GET[m]?$_GET[m]:date(m); 10 11 //獲取當前月多少天 12 $daysdate(t,strtotime("{$year}-{$m…

LeetCode:二叉樹相關應用

LeetCode&#xff1a;二叉樹相關應用 基礎知識 617.歸并兩個二叉樹 題目 Given two binary trees and imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not. You need to merge them into a new …

ubuntu16.04 python3.5 opencv的安裝與卸載(轉載)

轉載https://blog.csdn.net/qq_37541097/article/details/79045595 Ubuntu16.04 自帶python2.7和python3.5兩個版本&#xff0c;默認為python2.7&#xff0c;我使用的是3.5&#xff0c;所以首先將默認的python版本改為3.5. 在終端輸入下列指令&#xff1a; sudo update-alterna…

Webpack進階(一) tree shaking與不同mode

Tree Shaking 生產環境去除沒有使用到的內容&#xff08;開發環境沒有刪除&#xff0c;會影響調試&#xff09;只支持ESM規范&#xff08;靜態引入&#xff0c;編譯時引入&#xff09;&#xff0c;不支持CJS&#xff08;動態引入&#xff0c;執行時引入&#xff09; // webpa…

jquery --- 網頁選項卡

點擊,不同的tab_menu,顯示不同的tab_box 注意點: 1.獲取ul下,當前li的編號. $(‘div ul li’).index(this) 2.顯示ul下編號為$index的li -> $(‘ul li’).eq($index) <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <style&g…

Webpack進階(二)代碼分割 Code Splitting

源代碼index.js里包含2部分① 業務邏輯代碼 1mb② 引入&#xff08;如lodash包&#xff09;的代碼 1mb若更新了業務邏輯代碼&#xff0c;但在瀏覽器運行時每次都下載2mb的index.js顯然不合理&#xff0c;第三方包是不會變的 手動拆分 webpack.base.js entry: {main: path.re…

5177. 【NOIP2017提高組模擬6.28】TRAVEL (Standard IO)

Description Input Output Solution 有大佬說&#xff1a;可以用LCT做。&#xff08;會嗎&#xff1f;不會&#xff09; 對于蒟蒻的我&#xff0c;只好用水法&#xff08;3s&#xff0c;不虛&#xff09;。 首先選出的泡泡怪一定是連續的一段 L&#xff0c; R 然后 L 一定屬于蟲…

python 3.x 爬蟲基礎---http headers詳解

python 3.x 爬蟲基礎 python 3.x 爬蟲基礎---http headers詳解 python 3.x 爬蟲基礎---Urllib詳解 python 3.x 爬蟲基礎---Requersts,BeautifulSoup4&#xff08;bs4&#xff09; python 3.x 爬蟲基礎---正則表達式 前言  上一篇文章 python 爬蟲入門案例----爬取某站上海租房…

Webpack進階(三)

懶加載 lazy loading 用到的時候才加載vue 首屏不加載index.js const oBtn document.getElementById(j-button) oBtn.onclick async function () {const div await createElement()document.body.appendChild(div) } async function createElement() {const { default: _ …

P2634 [國家集訓隊]聰聰可可

鏈接&#xff1a;https://www.luogu.org/problemnew/show/P2634 題目描述 聰聰和可可是兄弟倆&#xff0c;他們倆經常為了一些瑣事打起來&#xff0c;例如家中只剩下最后一根冰棍而兩人都想吃、兩個人都想玩兒電腦&#xff08;可是他們家只有一臺電腦&#xff09;……遇到這種問…

算法 --- 快慢指針判斷鏈表是否有環

解題思路: 分別設置2個指針(s,q)指向鏈表的頭部,s每次指向下面一個(s s.next),q每次指向下面2個(q q.next.next). 如果存在環,q總會在某一時刻追上s /*** Definition for singly-linked list.* function ListNode(val) {* this.val val;* this.next null;* }*//**…

APP拉起小程序

結論&#xff1a;APP可以喚起小程序&#xff0c;前提是APP開發者在微信開放平臺帳號下申請移動應用&#xff0c;通過審核并關聯小程序&#xff0c;參考如下&#xff1a; 準備工作: APP開發者認證微信開放平臺 https://kf.qq.com/faq/170824URbmau170824r2uY7j.html APP開發者…

node --- 使用nrm改變npm的源

說明: 1.nrm只是單純的提供了幾個常用的下載包的URL地址,方便我們再使用npm裝包是 很方便的進行切換. 2.nrm提供的cnpm 和通過 cnpm裝包是2個不同的東西(使用cnpm install必須先安裝cnpm -> npm install -g cnpm) 安裝nrm: // linux $ [sudo] npm install --global nrm// w…