<script type="text/javascript" src="module1.js"></script>
<script type="text/javascript" src="module2.js"></script>
<script type="text/javascript" src="module3.js"></script>
<script type="text/javascript" src="module4.js"></script>
複製代碼
function fun1(){
  //...
}
function fun2(){
  //...
}
//上面的函數fun1,fun2組成了一個模塊,使用的時候直接調用某個函數就好了。
複製代碼
 var module1 = new Object({
count : 0,
fun1 : function (){
     //...
   },
  fun2 : function (){
     //...
   }
 });
 //這個裏面的fun1和fun2都封裝在一個賭俠寧裏,能夠經過對象.方法的形式進行調用;
 module1.fun1();
複製代碼
var module1 = (function(){
var count = 0;
var fun1 = function(){
//...
}
var fun2 = function(){
//...
}
//將想要暴露的內容放置到一個對象中,經過return返回到全局做用域。
return{
fun1:fun1,
fun2:fun2
}
})()
//這樣的話只能在全局做用域中讀到fun1和fun2,可是讀不到變量count,也修改不了了。
//問題:當前這個模塊依賴另外一個模塊怎麼辦?
複製代碼
var module1 = (function (mod){
  mod.fun3 = function () {
   //...
};
return mod;
})(module1);
//爲module1模塊添加了一個新方法fun3(),而後返回新的module1模塊。
//引入jquery到項目中;
var Module = (function($){
var _$body = $("body"); // we can use jQuery now!
var foo = function(){
console.log(_$body); // 特權方法
}
// Revelation Pattern
return {
foo: foo
}
})(jQuery)
Module.foo();
複製代碼
概述javascript
特色css
基本語法:html
exports.xxx = value
// 經過module.exports指定暴露的對象value
module.exports = value
複製代碼
var module = require('模塊相對路徑')
複製代碼
引入模塊發生在何時?java
exports = {Obj}
,暴露的API須做爲此對象的屬性。exports本質是引入了module.exports的對象。不能直接將exports變量指向一個值,由於這樣等於切斷了exports與module.exports的聯繫。exports=module.exports={Obj}
//結構以下
|-modules
|-module1.js//待引入模塊1
|-module2.js//待引入模塊2
|-module3.js//待引入模塊3
|-app.js//主模塊
|-package.json
{
"name": "commonjsnode",
"version": "1.0.0"
}
複製代碼
3.下載第三方模塊:舉例expressnode
npm i express --save
複製代碼
4.模塊化編碼jquery
// module1
// 使用module.exports = value向外暴露一個對象
module.exports = {
name: 'this is module1',
foo(){
console.log('module1 foo()');
}
}
// module2
// 使用module.exports = value向外暴露一個函數
module.exports = function () {
console.log('module2()');
}
// module3
// 使用exports.xxx = value向外暴露一個對象
exports.foo = function () {
console.log('module3 foo()');
};
exports.bar = function () {
console.log('module3 bar()');
};
exports.name = 'this is module3'
//app.js文件
var uniq = require('uniq');
//引用模塊
let module1 = require('./modules/module1');
let module2 = require('./modules/module2');
let module3 = require('./modules/module3');
//使用模塊
module1.foo();
module2();
module3.foo();
module3.bar();
module3.name;
複製代碼
|-js
|-dist //打包生成文件的目錄
|-src //源碼所在的目錄
|-module1.js
|-module2.js
|-module3.js
|-app.js //應用主源文件
|-index.html //瀏覽器上的頁面
|-package.json
{
"name": "browserify-test",
"version": "1.0.0"
}
複製代碼
下載browserifygit
定義模塊代碼:index.html文件要運行在瀏覽器上,須要藉助browserify將app.js文件打包編譯,若是直接在index.html引入app.js就會報錯。es6
打包處理js:根目錄下運行browserify js/src/app.js -o js/dist/bundle.js
github
頁面使用引入:express
<script type="text/javascript" src="js/dist/bundle.js"></script>
複製代碼
define([依賴模塊名], function(){return 模塊對象})
require(['模塊1', '模塊2', '模塊3'], function(m1, m2){//使用模塊對象})
define(function (require, exports, module) {
var reqModule = require("./someModule");
requModule.test();
exports.asplode = function () {
//someing
}
});
複製代碼
AMD規範:github.com/amdjs/amdjs…
AMD是"Asynchronous Module Definition"的縮寫,意思就是"異步模塊定義"。
它採用異步方式加載模塊,模塊的加載不影響它後面語句的運行。全部依賴這個模塊的語句,都定義在一個回調函數中,等到加載完成以後,這個回調函數纔會運行。
AMD也採用require()語句加載模塊,可是不一樣於CommonJS,它要求兩個參數:
require([module], callback);
複製代碼
目前,主要有兩個Javascript庫實現了AMD規範:RequireJS和curl.js。
js/libs/require.js
|-js
|-libs
|-require.js // 引入的require.js
|-modules
|-alerter.js
|-dataService.js
|-main.js
|-index.html
複製代碼
定義require.js的模塊代碼
define(['myLib'], function(myLib){
  function foo(){
    myLib.doSomething();
  }
  // 暴露模塊
  return {foo : foo};
});
//當require()函數加載上面這個模塊的時候,就會先加載myLib.js文件。
複製代碼
- 若是這個模塊還依賴其餘模塊,那麼define()函數的第一個參數,必須是一個數組,指明該模塊的依賴性;
```
// dataService.js
define(function () {
let msg = 'this is dataService'
function getMsg() {
return msg.toUpperCase()
}
return {getMsg}
})
// alerter.js
define(['dataService', 'jquery'], function (dataService, $) {
let name = 'Tom2'
function showMsg() {
$('body').css('background', 'gray')
alert(dataService.getMsg() + ', ' + name)
}
return {showMsg}
})
```
複製代碼
應用主(入口)js: main.js
(function () {
//配置
require.config({
//基本路徑
baseUrl: "js/",
//模塊標識名與模塊路徑映射
paths: {
"alerter": "modules/alerter",//此處不能寫成alerter.js,會報錯
"dataService": "modules/dataService",
}
})
//引入使用模塊
require( ['alerter'], function(alerter) {
alerter.showMsg()
})
})()
複製代碼
頁面使用模塊:
<script data-main="js/main" src="js/libs/require.js"></script>
複製代碼
js/libs/jquery-1.10.1.js
paths: {
'jquery': 'libs/jquery-1.10.1'
}
複製代碼
define(['dataService', 'jquery'], function (dataService, \$) {
var name = 'xfzhang'
function showMsg() {
$('body').css({background : 'red'})
alert(name + ' '+dataService.getMsg())
}
return {showMsg}
})
複製代碼
js/libs/angular.js
// main.js中配置
(function () {
//配置
require.config({
//基本路徑
baseUrl: "js/",
//模塊標識名與模塊路徑映射
paths: {
//第三方庫做爲模塊
'jquery' : './libs/jquery-1.10.1',
'angular' : './libs/angular',
//自定義模塊
"alerter": "./modules/alerter",
"dataService": "./modules/dataService"
},
/*
配置不兼容AMD的模塊
exports : 指定與相對應的模塊名對應的模塊對象
*/
shim: {
'angular' : {
exports : 'angular'
}
}
})
//引入使用模塊
require( ['alerter', 'angular'], function(alerter, angular) {
alerter.showMsg()
console.log(angular);
})
})()
複製代碼
// 沒有依賴的模塊
define(function(require, module, exports){
let value = 'xxx';
//經過require引入依賴模塊
//經過module.exports/exports來暴露模塊
exports.xxx = value
module.exports = value
})
// 有依賴的模塊
define(function(require, exports, module){
//引入依賴模塊(同步)
var module2 = require('./module2')
//引入依賴模塊(異步)
require.async('./module3', function (m3) {
......
})
//暴露模塊
exports.xxx = value
})
複製代碼
js/libs/sea.js
define()
exports
module.exports
複製代碼
require()
seajs.use()
|-js
|-libs
|-sea.js
|-modules
|-module1.js
|-module2.js
|-module3.js
|-module4.js
|-main.js
|-index.html
複製代碼
定義sea.js的模塊代碼
define(function (require, exports, module) {
//內部變量數據
var data = 'this is module1'
//內部函數
function show() {
console.log('module1 show() ' + data)
}
//向外暴露
exports.show = show
})
複製代碼
define(function (require, exports, module) {
module.exports = {
msg: 'I Will Back'
}
})
複製代碼
define(function (require, exports, module) {
const API_KEY = 'abc123'
exports.API_KEY = API_KEY
})
複製代碼
define(function (require, exports, module) {
//引入依賴模塊(同步)
var module2 = require('./module2');
function show() {
console.log('module4 show() ' + module2.msg)
}
exports.show = show
//引入依賴模塊(異步)
require.async('./module3', function (m3) {
console.log('異步引入依賴模塊3 ' + m3.API_KEY)
})
})
複製代碼
define(function (require) {
var m1 = require('./module1')
var m4 = require('./module4')
m1.show()
m4.show()
})
複製代碼
index.html:
<script type="text/javascript" src="js/libs/sea.js"></script>
<script type="text/javascript">
seajs.use('./js/modules/main')
</script>
複製代碼
es6 中新增了兩個命令 export 和 import ;
// math.js
export const add = function (a, b) {
return a + b
}
export const subtract = function (a, b) {
return a - b
}
複製代碼
// main.js
import { add, subtract } from './math.js'
add(1, 2)
substract(3, 2)
複製代碼
定義暴露模塊 : export
export default 對象
複製代碼
export var xxx = value1
export let yyy = value2
// 暴露一個對象
var xxx = value1
let yyy = value2
export {xxx, yyy}
複製代碼
引入使用模塊 : import
import xxx from '模塊路徑/模塊名'
複製代碼
import {xxx, yyy} from '模塊路徑/模塊名'
import * as module1 from '模塊路徑/模塊名'
複製代碼
export不止能夠導出函數,還能夠導出,對象、類、字符串等等;
暴露多個:
export const obj = {test1: ''}
export const test = ''
export class Test {
constuctor() {
}
}
// 或者,直接在暴露的地方定義導出函數或者變量
export let foo = ()=>{console.log('fnFoo');return "foo"},bar="stringBar"
複製代碼
let a=1
let b=2
let c=3
export { a,b,c }
複製代碼
// test.js
let a = 1
let b = 2
let c = 3
export {
a as test,
b,
c
};
import { test, b, c } from './test.js' // 改變命名後只能寫 as 後的命名
複製代碼
// test.js
let a = 1
let b = 2
let c = 3
export {
a as test,
b,
c
};
// lib.js引入test.js的內容
export * from './test.js'
// 引入
import {test,b,c} from './lib.js'
複製代碼
暴露一個對象,默認暴露
// test.js
export default function () {
console.log('hello world')
}
//引入
import say from './test.js' // 這裏能夠指定任意變量名
say() // hello world
複製代碼
import $ from 'jQuery' // 加載jQuery 庫
import _ from 'lodash' // 加載 lodash
import moment from 'moment' // 加載 moment
複製代碼
// main.js
import { add, subtract } from './test'
// 對於export default 導出的
import say from './test'
複製代碼
import {add as sum, subtract} from './test'
sum (1, 2)
複製代碼
// math.js
export const add = function (a, b) {
return a + b
}
export const subtract = function (a, b) {
return a - b
}
//引入
import * as math from './test.js'
math.add(1, 2)
math.subtract(1, 2)
複製代碼
{
"name" : "es6-babel-browserify",
"version" : "1.0.0"
}
複製代碼
npm install babel-cli browserify -g
npm install babel-preset-es2015 --save-dev
複製代碼
{
"presets": ["es2015"]
}
複製代碼
// js/src/module1.js
export function foo() {
console.log('module1 foo()');
};
export let bar = function () {
console.log('module1 bar()');
};
export const DATA_ARR = [1, 3, 5, 1];
// js/src/module2.js
let data = 'module2 data';
function fun1() {
console.log('module2 fun1() ' + data);
};
function fun2() {
console.log('module2 fun2() ' + data);
};
export {fun1, fun2};
// js/src/module3.js
export default {
name: 'Tom',
setName: function (name) {
this.name = name
}
}
// js/src/app.js
import {foo, bar} from './module1'
import {DATA_ARR} from './module1'
import {fun1, fun2} from './module2'
import person from './module3'
import $ from 'jquery'
//引入完畢
$('body').css('background', 'red')
foo()
bar()
console.log(DATA_ARR);
fun1()
fun2()
person.setName('JACK')
console.log(person.name);
複製代碼
<script type="text/javascript" src="js/lib/bundle.js"></script>
複製代碼
引入第三方模塊(jQuery)
npm install jquery@1 --save
複製代碼
import $ from 'jquery'
$('body').css('background', 'red')
複製代碼
模塊化方案 | 優勢 | 缺點 |
---|---|---|
commonJS | 複用性強; 使用簡單; 實現簡單; |
有很多能夠拿來即用的模塊,生態不錯; 同步加載不適合瀏覽器,瀏覽器的請求都是異步加載; 不能並行加載多個模塊。 |
AMD | 異步加載適合瀏覽器 | 可並行加載多個模塊; 模塊定義方式不優雅,不符合標準模塊化 |
ES6 | 可靜態分析,提早編譯 | 面向將來的標準; 瀏覽器原生兼容性差,因此通常都編譯成ES5; 目前能夠拿來即用的模塊少,生態差 |
// CMD
define(function(require, exports, module) {
var a = require('./a');
a.doSomething() // 此處略去 100 行
var b = require('./b') // 依賴能夠就近書寫
b.doSomething() // ... })
// AMD 默認推薦的是
define(['./a', './b'], function(a, b) {
// 依賴必須一開始就寫好
a.doSomething() // 此處略去 100 行
b.doSomething()
...})
複製代碼