原本說嚐鮮使用下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 ...
導出整體上分爲兩種: 命名導出,默認導出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 * 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模塊加載的實質