模塊化深入理解


目錄

export:導出

import:導入

修改模塊名、模塊的整體加載

export default:默認導出

import () :動態加載模塊

 

export(導出)

存在動態綁定數據

在一個文件中可以使用多個 export  來導出多個模塊

下面以 module.js 文件為例,導出了 arr、str、fun1 模塊

export const  arr = [1, 2, 3, 4, 5];   // 導出常量 arr

export let str = '字符‘';        // 導出變量 srt

export function fun1 (){
    console.log('這是導入的函數fun1')
}    // 導出函數 fun1

當然還有更直觀的寫法

const  arr = [1, 2, 3, 4, 5];  

let str = '字符‘';        

function fun1 (){
    console.log('這是導入函數fun1')
}    

// 將要導出的模塊統一寫在一個 export 關鍵字中是很合適的
export {
    arr,
    str,
    fun1
}

存在動態綁定數據的關系,a 變量的改變,可以傳遞到調用者哪里去

export let a = 'a';

setTimeout(()=>{a = 'aa'},1000);

 export 導出的變量都是只讀的,因為它的本質是輸入接口,也就是說,不允許在加載模塊的腳本里面,改寫接口

 

import(導入)

上面使用了 export 導出了模塊,接下來使用 import 導入模塊

 import { arr, str, fun1 } from "./module.js";

 console.log(arr , str);
    
 fun1();

上面的代碼加載了module.js 文件,並提取了module.js 文件中的 arr、str、fun1 模塊,

module.js 提取模塊的名字需要寫在 {} 中,想要提取什么模塊就寫什么模塊,但是名字必須和 module.js 文件導出時的名字一樣

import也和函數、變量一樣存在預編譯,即可以先使用,后導入

import './module.js';  如果這么用,相當於加載了一次modules.js 文件,但是並不會導入在modules.js中定義好的模塊或變量

如果是在 html 中的 script 標簽中導出模塊,那么必須為script 標簽添加 script = ' module '

import 不能寫在被其他語句包裹

// 這樣是不可以的
if (x === 1) {
  import { arr } from './module.js';
} else {
  import { arr } from './module2.js';
}

 

修改模塊名、模塊的整體加載

使用關鍵字 as 修改模塊名,導出和導入模塊命都可以修改

 

// A.js文件
const arr = [1, 2, 3, 4, 5];  
const str = 'str'; 
export { arr as numbers, str };


// B.js文件
import {numbers, str as string} from "./module.js";
console.log(numbers, string);

時候就是想所有模塊都導入,不想把模塊都寫一遍在 {} 中,那么可以 整體加載

 

// A.js文件
const arr = [1, 2, 3, 4, 5];  
const str = 'str';
export {arr, str};

// B.js文件
// 使用 * 號導入所有模塊,然后用 as 重命名,注意這里沒有 {} 了
import * as modules from "./components/2.1as";
console.log(modules.arr, modules.str);

 

 

export default(默認導出)

export default 和 export 一樣都是導出模塊,

同樣可以導出 函數、數組、對象、字符串、數值等

但是一個文件中, export 可以有多個,而 export default 只能有一個

export 導出的模塊,導入時要加 {},而export default 導出模塊,導入時不需要 {},但是允許並要求為它重新命名,下例子中取名為 newStr

// A.js文件
let  str = 'str';
export default str;

// B.js文件
import newStr from './module1';

export 和 export default 可以同時存在一個文件中(但並不建議這么做),導入的時候用  ' , ' 分開。下例子中,一定是 fun 寫在 {arr} 的前面,而不能 將 {arr} 寫在 fun  的前面

// fun 是用 export default 導出的,arr 是用 export,導出的
import fun, {arr} from './module.js';

本質上,export default 導出的是一個 default 的變量/方法,並且 default 后面緊跟的 變量 / 方法 / 值,將會賦值給 default 

// 所以下面的寫法都是 正確的

export default function a (){ return 1 } export default () => { return 1 } export default 4 let str1 = '字符'; let str2 = '字符'; export default {str1, str2}
// 而下面的寫法是 錯誤的

export default var a = 'a';

 

import () (動態引入)

前面說到 import 不能被其他語句包裹,不能動態引入模塊,因為它是在編譯時執行的,不向 require 在運行時才加載,因此可以動態引入

但是 import 函數可以實現動態引入模塊的目的

import 函數返回的是一個 promise 對象

條件加載

 

if (condition) {
  import('moduleA').then(...);
} else {
  import('moduleB').then(...);
}

 

按需加載

button.addEventListener('click', event => {
  import('./dialogBox.js')
  .then(dialogBox => {
    dialogBox.open();
  })
  .catch(error => {
    /* Error handling */
  })
})

動態路徑

import(f())
.then(...);

 

注意

如果使用 export 導出模塊,那么 import 函數導入模塊后,返回的 promise 對象的值是一個 Module 對象,而這些模塊都是 Module 對象中的屬性,

// A.js文件
export const  arr = [1, 2, 3, 4, 5];
export let str = '字符';   

// B.js文件
import('./A.js')
.then((mod) => {
    console.log(mod);
})

控制台打印如下

所以最好的使用這些模塊的方式,是用對象解構語法

import('./components/1.js')
.then(( {arr, str} )=> {
    console.log(arr, str)
})

如果使用 export default 導出,那么使用 import 函數導入后,返回的 promise 對象的值也是一個 Module 對象,與前者的區別在於模塊被賦值到 Module 對象的 default 屬性上

下面圖片中,導出的是 fun1 函數 

由於 default 是關鍵字,所以這里就不能直接使用解構了,不過用下面的寫法

// 最簡單的調用屬性
import('./A.js')
.then((mod) => {
  mod.default();
});

// 重命名
import('./A.js')
.then(( {default: fun1} )=> {
    fun1()
})

 

動態引入模塊錯誤

報錯信息有

Module build failed(模塊生成失敗)

Add @babel/plugin-syntax-dynamic-import (https://git.io/vb4Sv) to the 'plugins' section of your Babel config to enable parsing.(將@babel/plugin syntax dynamic import(https://git.io/vb4sv)添加到babel配置的“plugins”部分以啟用解析。)

解決方法

首先安裝  @babel/plugin-syntax-dynamic-import

然后配置  "plugins": ["@babel/plugin-syntax-dynamic-import"]

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM