javascript中的模塊化

所謂的模塊也叫元件或許組件,能夠理解為能夠服用的功用代碼。比方說a頁面用功用了,b頁面用到了這功用了,所以我們能夠把這個功用抽為組件,便於服用。那末javascript中的組件化怎樣運用呢,那末不能不提到下面的三種範例。
1.民間的庫。如遵照CMD範例的sea.js和遵照AMD範例的require.js.
2.node中的模塊化。
3.ES6中的模塊化。

一.(民間的庫)sea.js

我們來先講sea.js。雖然如今這個庫有些過期了。然則頭腦和理念照樣不錯的。

組件的定義:
在js文件中,運用define要領可定義組件。這個要領的參數是一個函數,內里有三個參數,順次分別是require,exports,medule。
require:是在js文件中引模塊的。

var a= require(“./a.js”)

exports:輸出的變量都掛載這exports上,如許做的優點是削減對外暴露的變量。

   exports.mun=1;
   exports.name="lee;   
   exports.show = function(){
        renturn a+b;
    }

module:能夠把返回的所以變量都寫在module里。可返回一組。

 module.exports={
    a:12,
    b:5,
    show:function(){
    }
    //固然了在es6中,json里的函數能夠把“:函數名”去掉,簡寫為
   // show(){
   // } 
}
固然了es6中json中假如有函數,能夠省略

組件的運用:
在html中,固然先是援用sea.js了,在運用,在script中經由過程seajs.use()運用。

    <script src="https://cdn.bootcss.com/seajs/3.0.2/sea.js"></script>
    <script>  
    seajs.use('./index.js',function(module){
        console.log(module.add())
    })  
    </script>  
    假如援用一個以上的組件,就可以夠用把這一組組件放在數組中就可以夠了,以下:
     seajs.use(['./index1.js','./index2.js',.....],function(index1,index,....){
        console.log(module.add())
    })  
    

二.node中的模塊化。

1,沒有define;
2,有exports,require,module
module.exports={a,b,c} 批量導出
3,援用自定義模塊,為了不和系統模塊爭執,
自定義模塊放在node_modules里,
或許前面加./強迫指點加載的目次。
定義模塊:

能夠一個一個定義:

exports.a=12;
exports.b=5;

能夠定義一組:

let a=12;
let b=5;
module.exports = {a,b}

援用模塊:
node.js 也是js,遵照cmd範例,運用require援用模塊。

let mod=require('./aaa.js'); 後綴.js可簡寫不寫。前面的./假如不寫,就需要把這個模塊放在node_modules文件夾里,不然會以node里的系統模塊有影響。




三.ES6:模塊(Module)

概述 :
歷史上,JavaScript 一向沒有模塊(module)系統,沒法將一個大順序拆分紅相互依靠的小文件,再用簡樸的要領拼裝起來。其他言語都有這項功用,比方 Ruby 的require、Python 的import,以至就連 CSS 都有@import,然則 JavaScript 任何這方面的支撐都沒有,這對開闢大型的、龐雜的項目形成了龐大停滯。
在 ES6 之前,社區制訂了一些模塊加載計劃,最主要的有 CommonJS 和 AMD 兩種。前者用於服務器,後者用於瀏覽器。ES6 在言語規範的層面上,完成了模塊功用,而且完成得相稱簡樸,完整能夠庖代 CommonJS 和 AMD 範例,成為瀏覽器和服務器通用的模塊解決計劃。
ES6 模塊的設想頭腦是只管的靜態化,使得編譯時就可以肯定模塊的依靠關聯,以及輸入和輸出的變量。CommonJS 和 AMD 模塊,都只能在運行時肯定這些東西。比方,CommonJS 模塊就是對象,輸入時必需查找對象屬性。

基礎用法

定名導出:
能夠直接在任何變量或許函數前面加export關鍵字,就可以夠將它導出。這類寫法異常簡約,和日常平凡幾乎沒有區分,唯一的區分就是在需要導出的處所加上一個 export 關鍵字。
比方:

export const sqrt = Math.sqrt;
export function square(x) {
    return x * x;
}
export function diag(x, y) {
    return sqrt(square(x) + square(y));
}

然後在另一個文件中如許援用:

import { square, diag } from 'lib'; 
console.log(square(11)); // 121
console.log(diag(4, 3));

你可能會注意到這個新鮮的語法 { square, diag } 不就是前面講過的 destructing嗎。所以你會認為還能夠如許寫:

 import lib from 'lib';
 square = lib.square;

然則實在如許是錯的,由於 import { square, diag } from ‘lib’; 是import的特有語法,並非 destructing 語法,所以實在import的時刻並非直接把全部模塊以對象的情勢引入的。

假如你希望能經由過程 lib.square 的情勢來寫,你應當如許導入:

 import * as lib from 'lib';
 square = lib.square;

不過值得注意的一點是,假如你直接用babel編譯,實行是會報錯的。由於 babel 並不會完整編譯 modules,他只是把 ES6 的modules語法編譯成了 CMD 的語法,所以還需要用 browserify 之類的東西再次編譯一遍。
假如你發明 browserify 找不到 lib,能夠改成 from ‘./lib’ 嘗嘗。

默許導出

本質上,export default就是輸出一個叫做default的變量或要領,然後系統許可你為它取恣意名字。所以,下面的寫法是有用的。
人人會發明上面的寫法比較貧苦,由於必需要指定一個名字。實在許多時刻一個模塊只導出了一個變量,基礎沒必要指定一個名字。
另有一種用法叫默許導出,就是指定一個變量作為默許值導出:

 //------ myFunc.js ------
export default function () { ... };

//------ main1.js ------
import myFunc from 'myFunc';
myFunc();

默許導出的時刻不需要指定一個變量名,它默許就是文件名。
這裏的區分不僅僅是不必寫名字,而是 導出的默許值就是模塊自身,而不是模塊下面的一個屬性,等於 import myFunc from ‘myFunc’; 而不是 import {myFunc} from ‘myFunc’;

定名導出連繫默許導出

默許導出一樣能夠連繫定名導出來運用:
假如想在一條import語句中,同時輸入默許要領和其他接口,能夠寫成下面如許。

import _, { each, each as forEach } from 'lodash';

對應上面代碼的export語句以下。

export default function (obj) {
  // ···
}

export function each(obj, iterator, context) {
  // ···
}

export { each as forEach };
上面代碼的末了一行的意義是,暴露出forEach接口,默許指向each接口,即forEach和each指向同一個要領。

僅支撐靜態導入導出

ES6範例只支撐靜態的導入和導出,也就是必需要在編譯時就可以肯定,在運行時才肯定的是不可的,比以下面的代碼就是不對的:

//動態導入
var mylib;
if (Math.random()) {
    mylib = require('foo');
} else {
    mylib = require('bar');
}
//動態導出
if (Math.random()) {
    exports.baz = ...;
}

種種導入和導出體式格局總結

總結一下,ES6供應了以下幾種導入體式格局:

// Default exports and named exports
import theDefault, { named1, named2 } from 'src/mylib';
import theDefault from 'src/mylib';
import { named1, named2 } from 'src/mylib';

// Renaming: import named1 as myNamed1
import { named1 as myNamed1, named2 } from 'src/mylib';

// Importing the module as an object
// (with one property per named export)
import * as mylib from 'src/mylib';

// Only load the module, don’t import anything
import 'src/mylib';

以下幾種導出體式格局:

 //定名導出
export var myVar1 = ...;
export let myVar2 = ...;
export const MY_CONST = ...;

export function myFunc() {
    ...
}
export function* myGeneratorFunc() {
    ...
}
export class MyClass {
    ...
}
// default 導出
export default 123;
export default function (x) {
    return x
};
export default x => x;
export default class {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
};
//也能夠本身列出一切導出內容
const MY_CONST = ...;
function myFunc() {
    ...
}

export { MY_CONST, myFunc };
//或許在導出的時刻給他們改個名字
export { MY_CONST as THE_CONST, myFunc as theFunc };

//還能夠導出從其他處所導入的模塊
export * from 'src/other_module';
export { foo, bar } from 'src/other_module';
export { foo as myFoo, bar } from 'src/other_module';
    原文作者:呂鵬
    原文地址: https://segmentfault.com/a/1190000014934498
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞