JavaScript 模塊化語法 import、export示例詳解
JavaScript 模塊化語法 import、export 詳解
1. 為什么需要模塊化?
在 JavaScript 早期,所有代碼都是寫在一個(gè) 全局作用域 中,這樣做的問題是:
- 變量污染:所有變量、函數(shù)都是全局的,容易互相干擾。
- 文件依賴管理困難:多個(gè) JS 文件之間的依賴關(guān)系混亂,難以維護(hù)。
- 代碼復(fù)用困難:無法方便地拆分和復(fù)用代碼。
為了解決這些問題,模塊化 方案應(yīng)運(yùn)而生。
2. JavaScript 模塊化的發(fā)展
2.1 早期的模塊化方案
在 ES6 之前,JS 主要依賴以下方案進(jìn)行模塊化:
- IIFE(立即執(zhí)行函數(shù)表達(dá)式):用函數(shù)封裝代碼,避免污染全局變量。
- CommonJS(Node.js 使用):
require()
引入模塊。module.exports
導(dǎo)出模塊。
- AMD(Asynchronous Module Definition):
- 主要用于瀏覽器端,使用
define()
和require()
加載模塊(如 RequireJS)。
- 主要用于瀏覽器端,使用
- UMD(Universal Module Definition):
- 兼容 CommonJS 和 AMD,用于同時(shí)支持瀏覽器和 Node.js。
但這些方案都有一定的缺陷,比如 CommonJS 是同步加載的,不適用于瀏覽器端,AMD 又顯得過于復(fù)雜。
3. ES6 模塊化(ESM)—— import & export
ES6 在 2015 年引入了 import
和 export
關(guān)鍵字,成為 JavaScript 官方的模塊化方案(ECMAScript Modules, ESM)。
3.1 基本用法
ES6 模塊化使用 export
導(dǎo)出模塊,import
導(dǎo)入模塊。
(1)導(dǎo)出模塊 (export
)
在一個(gè) JavaScript 文件中,我們可以使用 export
關(guān)鍵字導(dǎo)出變量、函數(shù)或類。
? 導(dǎo)出方式 1:命名導(dǎo)出(Named Export)
// math.js export const PI = 3.14159; export function add(a, b) { return a + b; } export class Calculator { multiply(a, b) { return a * b; } }
? 導(dǎo)出方式 2:默認(rèn)導(dǎo)出(Default Export)
// greet.js export default function greet(name) { return `Hello, ${name}!`; }
(2)導(dǎo)入模塊 (import
)
? 導(dǎo)入方式 1:導(dǎo)入命名導(dǎo)出
import { PI, add, Calculator } from './math.js'; console.log(PI); // 3.14159 console.log(add(2, 3)); // 5 const calc = new Calculator(); console.log(calc.multiply(2, 3)); // 6
? 導(dǎo)入方式 2:導(dǎo)入默認(rèn)導(dǎo)出
import greet from './greet.js'; console.log(greet('Alice')); // Hello, Alice!
? 導(dǎo)入方式 3:重命名導(dǎo)入
import { add as sum } from './math.js'; console.log(sum(2, 3)); // 5
? 導(dǎo)入方式 4:整體導(dǎo)入
import * as MathUtils from './math.js'; console.log(MathUtils.PI); // 3.14159 console.log(MathUtils.add(2, 3)); // 5
4. export 詳解
4.1 命名導(dǎo)出(Named Export)
命名導(dǎo)出可以導(dǎo)出多個(gè)變量、函數(shù)或類:
export const name = 'Alice'; export function greet() { return 'Hello!'; } export class User {}
導(dǎo)入時(shí)需要使用 相同的名稱:
import { name, greet, User } from './module.js';
4.2 默認(rèn)導(dǎo)出(Default Export)
默認(rèn)導(dǎo)出通常用于 導(dǎo)出單個(gè)模塊,例如:
export default function greet() { return 'Hello!'; }
導(dǎo)入時(shí)可以使用 任何名稱:
import myGreet from './module.js'; console.log(myGreet()); // Hello!
4.3 默認(rèn)導(dǎo)出 + 命名導(dǎo)出
export default function main() { console.log('Default function'); } export const version = '1.0'; export function helper() { console.log('Helper function'); }
導(dǎo)入:
import main, { version, helper } from './module.js'; main(); // Default function console.log(version); // 1.0 helper(); // Helper function
5. import 詳解
5.1 import 只能在模塊頂級(jí)使用
import
語句不能放在 條件語句或函數(shù)內(nèi)部,否則會(huì)報(bào)錯(cuò):
if (true) { import { add } from './math.js'; // ? 錯(cuò)誤 }
正確用法:
import { add } from './math.js'; if (true) { console.log(add(2, 3)); }
5.2 動(dòng)態(tài)導(dǎo)入 import()
ES2020 引入了 動(dòng)態(tài)導(dǎo)入,適用于 按需加載(懶加載):
if (someCondition) { import('./math.js').then(({ add }) => { console.log(add(2, 3)); }); }
也可以用 async/await
:
async function loadMath() { const math = await import('./math.js'); console.log(math.add(2, 3)); } loadMath();
6. ES6 模塊 vs CommonJS
特性 | ES6 模塊(ESM) | CommonJS(CJS) |
---|---|---|
關(guān)鍵字 | import / export | require() / module.exports |
運(yùn)行方式 | 預(yù)解析(靜態(tài)導(dǎo)入) | 運(yùn)行時(shí)(動(dòng)態(tài)導(dǎo)入) |
是否支持頂層導(dǎo)入 | ? 是 | ? 否 |
是否支持異步導(dǎo)入 | ? import() | ? 僅同步 |
適用環(huán)境 | 瀏覽器 & Node.js (ESM) | Node.js (CJS) |
默認(rèn)方式 | 適用于瀏覽器和前端 | Node.js 默認(rèn)方式 |
特性ES6 模塊(ESM)CommonJS(CJS)關(guān)鍵字import
/ export
require()
/ module.exports
運(yùn)行方式預(yù)解析(靜態(tài)導(dǎo)入)運(yùn)行時(shí)(動(dòng)態(tài)導(dǎo)入)是否支持頂層導(dǎo)入? 是? 否是否支持異步導(dǎo)入? import()
? 僅同步適用環(huán)境瀏覽器 & Node.js (ESM)Node.js (CJS)默認(rèn)方式適用于瀏覽器和前端Node.js 默認(rèn)方式
7. 瀏覽器中如何使用 import / export
7.1 直接使用 <script type="module">
<script type="module"> import { add } from './math.js'; console.log(add(2, 3)); </script>
7.2 通過 Webpack / Vite / Rollup
現(xiàn)代前端工具(如 Webpack)可以 打包 ES6 模塊 以支持更舊的瀏覽器:
npm install webpack
8. 結(jié)論
- ES6 模塊化 (import / export) 是 JavaScript 官方推薦的模塊化方案,解決了 代碼復(fù)用、作用域管理、依賴管理 等問題。
- 默認(rèn)導(dǎo)出 (export default) 適用于導(dǎo)出單個(gè)對(duì)象或函數(shù)。
- 命名導(dǎo)出 (export {}) 適用于導(dǎo)出多個(gè)變量、函數(shù)或類。
- 動(dòng)態(tài)導(dǎo)入 (import()) 可實(shí)現(xiàn) 懶加載,適用于按需加載模塊。
- ESM 和 CommonJS 不兼容,但 Node.js 也開始支持 ESM(.mjs 文件)。
- 關(guān)于JavaScript使用export和import的兩個(gè)報(bào)錯(cuò)解決
- Js模塊打包exports require import的用法和區(qū)別
- MongoDB使用mongoexport和mongoimport命令,批量導(dǎo)出和導(dǎo)入JSON數(shù)據(jù)到同一張表的實(shí)例
- import與export在node.js中的使用詳解
- 一文讓你徹底搞清楚javascript中的require、import與export
- node.js中使用Export和Import的方法
- JavaScript ES6中export、import與export default的用法和區(qū)別
相關(guān)文章
18個(gè)JavaScript編寫簡(jiǎn)潔高效代碼的技巧分享
在這篇文章中,小編將和大家分享18個(gè)JavaScript技巧,以及一些你應(yīng)該知道的示例代碼,以編寫簡(jiǎn)潔高效的代碼,感興趣的小伙伴快跟隨小編一起學(xué)習(xí)一下吧2024-01-01功能強(qiáng)大的Bootstrap組件(結(jié)合js)
這篇文章主要介紹了功能強(qiáng)大的Bootstrap組件,介紹js結(jié)合Bootstrap組件的使用方法,感興趣的小伙伴們可以參考一下2016-08-08微信小程序 仿美團(tuán)分類菜單 swiper分類菜單
本文主要介紹了微信小程序仿美團(tuán)分類菜單(swiper分類菜單)的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-04-04深入理解JavaScript中實(shí)例對(duì)象和new命令
典型的面向?qū)ο缶幊陶Z言(比如C++和 Java),都有“類”(class)這個(gè)概念。所謂“類”就是對(duì)象的模板,對(duì)象就是“類”的實(shí)例,下面這篇文章主要給大家介紹了關(guān)于JavaScript中實(shí)例對(duì)象和new命令的相關(guān)資料,需要的朋友可以參考下2022-12-12echarts自定義tooltip中的內(nèi)容代碼示例
在ECharts中,通過formatter函數(shù)自定義圖例樣式,可以實(shí)現(xiàn)更靈活的圖表展示,滿足特定的視覺需求,這篇文章主要介紹了echarts自定義tooltip中內(nèi)容的相關(guān)資料,需要的朋友可以參考下2024-10-10JS實(shí)現(xiàn)圖片預(yù)加載之無序預(yù)加載功能代碼
這篇文章主要介紹了JS實(shí)現(xiàn)圖片預(yù)加載之無序預(yù)加載功能代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-05-05js實(shí)現(xiàn)選中頁面文字將其分享到新浪微博
這篇文章主要介紹了js實(shí)現(xiàn)選中頁面文字將其分享到新浪微博,需要的朋友可以參考下2015-11-11javascript設(shè)置文本框光標(biāo)的方法實(shí)例小結(jié)
這篇文章主要介紹了javascript設(shè)置文本框光標(biāo)的方法,結(jié)合實(shí)例形式總結(jié)分析了javascript針對(duì)文本框光標(biāo)的位置、設(shè)置及文本操作的相關(guān)技巧,需要的朋友可以參考下2016-11-11js如何使用Pagination+PageHelper實(shí)現(xiàn)分頁
本文主要介紹了js如何使用Pagination+PageHelper實(shí)現(xiàn)分頁,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06