es6 module模塊

原本說嚐鮮使用下es6的import和export呢,結果以上來就遇到了問題了,發現以原來require的思惟(CommonJS)去使用es6的module了。node

您能看出問題嗎

首先要說的就是,下面的測試走不通報錯,但您能看出問題在哪裏嗎,若是不能,也許須要繼續讀下去,真正瞭解下es6的module。es6

//controller/union.js
export async function transReqPage(ctx, next) {
    return await {'hello': 'world'};
}

//test-import.js
import unionController from '../controller/union';

unionController.transReqPage()
    .then(function(res) {
        console.log(res);
    })
    .catch(function(err) {
        console.log(err);
    });

錯誤信息babel

suntopo@suntopo-X550VX:~/Desktop/workspace/UionPay$ babel-node ./test-import.js
/home/suntopo/Desktop/workspace/UionPay/test-import.js:9
_union2.default.transReqPage().then(function (res) {
               ^

TypeError: Cannot read property 'transReqPage' of undefined
...

export

導出整體上分爲兩種: 命名導出默認導出async

命名導出

export { name1, name2, …, nameN };
export let name1 = …, name2 = …, …, nameN; // also var, const
export function name1(…) { … } // also class, function*

常見的就三種函數

function test() {console.log('test')}
export {test, test as test1}
export function test() {console.log('test');}
export var test = 'test';

常見的錯誤形式測試

var test = 'test';
export test
function test() {console.log('test');}
export test

究其緣由:export規定的是對外的接口,必須與內部變量創建一一對應關係,即既要有接口名,又要有變量名,接口名能夠顯示指定也能夠隱式的指定,但無非就是上面說的幾種形式,最明顯的形式能夠這樣ui

export { a as b}

這裏明確的指明的接口名b,同是也指明瞭一一對應的變量a,可是這種形式仍是有些繁瑣尤爲在接口名和變量名相同的時候,因而能夠寫成這樣spa

export {a}

當變量a變得很簡單的時候,這樣寫也可能會比較繁瑣,因而乎又有了簡寫code

export var a=1;

當咱們的模塊也許只有一個接口的時候,或者說想要模塊有一個默認的接口的時候,有能夠再次簡寫--默認導出對象

默認導出

export default function() {console.log('test')}

實際上解釋默認導出時,若是從用戶使用import的角度來解釋更加清楚,好比用戶在使用模塊的時候,她必須清楚模塊接口的名字才能正確引用,可是這每每給用戶帶來很大的不便,好比說該模塊就一個接口,或該模塊有一個默認的接口,我就想拿來就用而已,因而纔有了默認導出。

注:一個模塊只能有一個默認導出

import

導入和導出老是相對的,既然導出有兩種,那麼導入也可能會有不一樣。

import * asname from "module-name"; 
import { member } from "module-name"; 
import { member as alias } from "module-name"; 
import { member1 , member2 } from "module-name"; 
import { member1 , member2 as alias2 , [...] } from "module-name"; 

import defaultMember, { member [ , [...] ] } from "module-name"; 
import defaultMember, * as name from "module-name"; 
import defaultMember from "module-name"; 
import "module-name";

命名導入

在導出中咱們強調了兩個關鍵字,接口名和變量名,對於導入而言咱們關心的只有接口名,只有知道接口名才能正確的調用該接口。

import接受一個對象,裏面指定要從其餘模塊導入的接口名

import {test} from './test'

一樣,也可給導入到該模塊的接口重命名

import {test as test1} from './test'

可是當須要導入多個接口的時候,一個個寫接口可能不現實,因此提供了導入整個模塊全部接口的寫法

import * as TEST from './test';

默認導入

能夠導出默認選項,不管是一個對象,一個函數或一個 class。相對地, 也可使用 import 默認導出,不用{}, 不用變量名,不用as,導入的就是默認導出的幾口

最簡單版本,直接導入默認

import test from './test'

混合版

import test, * as test1 from './test';

注意: test1中並不包含test接口,各自獨立的,儘管使用了*

那麼問題處在哪裏呢

首先看下我導出和導入的方式

export async function transReqPage

import unionController from '../controller/union';

咱們導入的方式其實是採用默認導入,可是導出卻沒有默認導出,因此報找不到方法咯。那麼咱們該怎麼修改呢?首先要看咱們的需求,若是咱們的模塊僅僅只須要導出一個接口,那麼在export後面加上default就OK了,可是一般狀況下咱們須要導出多個接口,因此這裏須要咱們修改下導入的方式,採用命名導入方式,例如其中一種導入全部的接口

import * as unionController from '../controller/union';

動態綁定

不一樣於CommonJS的拷貝,es6的模塊使用動態綁定,即導入是導出的一個引用,詳細內容見es6模塊加載的實質

相關文章
相關標籤/搜索