【從一個 TypeScript 報錯理解 ES6 模塊的三種導入方式】

從一個 TypeScript 報錯理解 ES6 模塊的三種導入方式

在日常開發中,我們經常遇到模塊導入導出的場景。最近在處理一個項目時,遇到了一個有趣的問題:對于只有默認導出的模塊,我們該使用哪種導入方式?這個問題引發了對 JavaScript 模塊系統的深入思考。

問題起源

在項目中,我們遇到這樣一段代碼:

// 原始代碼
import * as OverviewApi from '@/views/home/overview/api'// api.ts 的內容
export default {allStationInfo(data = {}) {// ... }
}

這段代碼雖然能運行,但出現了 TypeScript 錯誤:Property 'allStationInfo' does not exist on type...。這促使我們重新思考模塊導入的最佳實踐。

模塊化的歷史演進

在深入討論導入方式之前,我們先了解一下 JavaScript 模塊化的發展歷程:

  1. 早期階段(2009年之前)

    • 沒有官方模塊系統
    • 主要通過全局變量和命名空間模式組織代碼
    • 容易造成命名沖突和依賴混亂
  2. CommonJS時代(2009年)

    // 導出
    module.exports = { method: function() {} }
    // 導入
    const module = require('./module')
    
    • Node.js采用的模塊規范
    • 同步加載,不適合瀏覽器環境
  3. AMD時代(2011年)

    define(['dependency'], function(dependency) {return { method: function() {} }
    })
    
    • 專為瀏覽器設計
    • 支持異步加載
    • 使用相對復雜
  4. ES6模塊系統(2015年)

    • 官方標準化的模塊系統
    • 同時支持瀏覽器和Node.js
    • 支持靜態分析,有利于tree-shaking

三種主要的導入方式

1. 默認導入

import Api from './api'
  • 直接獲取模塊的默認導出
  • 最簡潔的使用方式
  • 適用于模塊只有一個主要導出對象的情況

2. 命名空間導入

import * as Api from './api'
  • 將所有導出(包括默認導出)收集到一個命名空間對象中
  • 默認導出會在 .default 屬性下
  • 適用于模塊有多個導出的情況

3. 命名導入默認導出

import { default as Api } from './api'
  • 顯式地將默認導出重命名
  • 效果與默認導入相同
  • 較少使用,除非需要特別明確導入的是默認導出

使用場景分析

不同的導入方式適合不同的場景:

默認導入適用場景

  1. 單一功能模塊

    // React組件
    import Button from './Button'
    // 工具類
    import axios from 'axios'
    
  2. 主要功能模塊

    // 配置文件
    import config from './config'
    // API服務
    import apiService from './api'
    

命名空間導入適用場景

  1. 工具庫

    // 數據可視化庫
    import * as d3 from 'd3'
    // 工具函數集合
    import * as Utils from './utils'
    
  2. 類型定義

    // TypeScript類型定義
    import * as Types from './types'
    

混合使用場景

// 同時使用默認導出和具名導出
import React, { useState, useEffect } from 'react'

實際應用對比

讓我們看一個具體的例子:

// api.ts
export default {method1() {},method2() {}
}// 使用方式對比
// 1. 默認導入
import Api from './api'
Api.method1()  // ? 推薦:簡潔直觀// 2. 命名空間導入
import * as ApiNamespace from './api'
ApiNamespace.default.method1()  // △ 可用但繁瑣// 3. 命名導入默認導出
import { default as Api } from './api'
Api.method1()  // ? 作用同默認導入

TypeScript 中的考慮

在 TypeScript 項目中,選擇正確的導入方式還需要考慮類型系統:

// 默認導出的類型推斷通常更直接
import Api from './api'
// TypeScript 能更好地推斷 Api 的類型// 命名空間導入可能需要額外的類型處理
import * as ApiNamespace from './api'
// 需要通過 .default 訪問,類型推斷可能不如默認導入直接

最佳實踐建議

  1. 對于只有默認導出的模塊

    • 使用默認導入
    • 保持代碼簡潔
    • 便于類型推斷
  2. 對于有多個導出的模塊

    • 使用具名導入
    • 或在需要時使用命名空間導入
    • 明確導入內容,便于tree-shaking
  3. 項目規范

    • 在團隊中保持一致的導入方式
    • 制定清晰的模塊設計規范
    • 考慮代碼可維護性

結論

JavaScript 模塊系統的發展給我們提供了多種導入方式的選擇。在實際開發中,應該根據具體場景選擇最合適的方式:

  • 理解各種導入方式的歷史背景和設計初衷
  • 根據模塊的導出內容選擇合適的導入方式
  • 考慮團隊協作和代碼維護的需求
  • 注意 TypeScript 類型系統的支持情況

最重要的是,理解這些不同方式的工作原理,這樣才能在遇到問題時做出正確的選擇。沒有絕對的對錯,關鍵是選擇最適合當前場景和團隊的方式。

參考資料

  • ECMAScript 6 模塊規范
  • TypeScript 模塊文檔
  • Node.js CommonJS 文檔
  • 實際項目經驗總結

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/900935.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/900935.shtml
英文地址,請注明出處:http://en.pswp.cn/news/900935.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

安徽京準:NTP網絡時鐘服務器功能及同步模式的介紹

安徽京準:NTP網絡時鐘服務器功能及同步模式的介紹 安徽京準:NTP網絡時鐘服務器功能及同步模式的介紹 1、NTP網絡時鐘服務器概念: NTP時鐘服務器,表面意思是時間計量工具的服務設備,其在現代工業中是用于對客戶端設備…

JMeter從入門到荒廢-常見問題匯總

啟動某個ThreadGroup的時候,啟動不了 現象 點擊start按鈕的時候,結果樹和匯總報告都沒有任何數據。 同時,點擊右上角的error log 發現有錯誤信息: 錯誤信息如下: 2025-04-09 10:03:48,009 ERROR o.a.j.g.a.ActionR…

Elasticsearch 學習規劃

Elasticsearch 學習規劃 明確學習目標與動機 場景化需求分析 - **S**:掌握Elasticsearch架構體系,熟練使用Elasticsearch 進行數據分析,Elasticsearch結合java 項目落地案例 - **M**:搜索和Elasticsearch相關GitHub項目 - **A**:每…

核心案例 | 湖南汽車工程職業大學無人機操控與編隊技術實驗室

核心案例 | 湖南汽車工程職業大學無人機操控與編隊技術實驗室 為滿足當今無人機行業應用需求,推動無人機技術的教育與實踐深度融合,北京卓翼智能科技有限公司旗下品牌飛思實驗室與湖南汽車工程職業大學強強聯手,共同建設無人機操控與編隊技術…

【Android】Android 獲取當前前臺應用包名與自動化控制全流程實踐筆記(適配 Android 10+)

一、前言 在 Android 系統中,獲取當前運行的前臺應用、返回桌面、跳轉權限設置、關閉其他應用等行為,往往受到系統的嚴格限制。隨著 Android 版本的提升(特別是 Android 10 之后,即 API 29),很多傳統方法已…

Sentinel核心源碼分析(上)

文章目錄 前言一、客戶端與Spring Boot整合二、SphU.entry2.1、構建責任鏈2.2、調用責任鏈2.2.1、NodeSelectorSlot2.2.2、ClusterBuilderSlot2.2.3、LogSlot2.2.4、StatisticSlot2.2.5、AuthoritySlot2.2.6、SystemSlot2.2.7、FlowSlot2.2.7.1、selectNodeByRequesterAndStrat…

淺談「分詞」:原理 + 方案對比 + 最佳實踐

在文本搜索、自然語言處理、智能推薦等場景中,「分詞」 是一個基礎但至關重要的技術點。無論是用數據庫做模糊查詢,還是構建搜索引擎,分詞都是提高效率和準確度的核心手段。 🔍 一、什么是分詞? 分詞(Tok…

transformers:打造的先進的自然語言處理

github地址:https://github.com/huggingface/transformers Transformers 提供了數以千計的預訓練模型,支持 100 多種語言的文本分類、信息抽取、問答、摘要、翻譯、文本生成。它的宗旨是讓NLP 技術人易用。 Transformers 提供了便于快速下載和使用的API…

Spring Boot 集成 MongoDB 時自動創建的核心 Bean 的詳細說明及表格總結

以下是 Spring Boot 集成 MongoDB 時自動創建的核心 Bean 的詳細說明及表格總結: 核心 Bean 列表及詳細說明 1. MongoClient 類型:com.mongodb.client.MongoClient作用: MongoDB 客戶端核心接口,負責與 MongoDB 服務器建立連接、…

113. 在 Vue 3 中使用 OpenLayers 實現鼠標移動顯示坐標信息

? 寫在前面 在地圖類項目開發中,一個常見需求就是:實時獲取用戶鼠標在地圖上的經緯度坐標,并展示在地圖上。 本文將通過一個簡單的案例,手把手帶大家在 Vue 3 項目中集成 OpenLayers 地圖庫,并實現以下功能&#xf…

docker配置redis容器時搭載哨兵節點的情況下配置文件docker-compose.yml示例

1.配置數據節點(主從節點) version: 3.7 services:master:image: redis:5.0.9container_name: redis-masterrestart: alwayscommand: redis-server --appendonly yesports:- 6379:6379slave1:image: redis:5.0.9container_name: redis-slave1restart: a…

C++建造者模式進化論

還在為 C 對象那 長得令人發指 的構造函數參數列表抓狂嗎?🤯 是不是經常在 int hp, int mp, int strength, int faith... 這樣的參數“連連看”中迷失自我,一不小心就把法力值傳給了血量,或者力量值填到了信仰欄?&…

在Ubuntu內網環境中為Gogs配置HTTPS訪問(通過Apache反向代理使用IP地址)

一、準備工作 確保已安裝Gogs并運行在HTTP模式(默認端口3000) 確認服務器內網IP地址(如192.168.1.100) 二、安裝Apache和必要模塊 sudo apt update sudo apt install apache2 -y sudo a2enmod ssl proxy proxy_http rewrite headers 三、創建SSL證書 1. 創建證書存儲目錄…

數據中臺、BI業務訪談(二):組織架構梳理的坑

這是數據中臺、BI業務訪談系列的第二篇文章,在上一篇文章中,我重點介紹了在給企業的業務部門、高層管理做業務訪談之前我們要做好行業、業務知識的功課。做好這些功課之后,就到了實際的訪談環節了。 業務訪談關鍵點 那么在具體業務訪談的時…

spark集群,Stand alone,Hadoop集群有關啟動問題

你的問題是因為 start-all.sh 是 Hadoop 的啟動腳本(用于啟動 HDFS 和 YARN),而不是 Spark 的啟動腳本。而你已經通過 start-cluster.sh 啟動了 Hadoop 相關服務(HDFS/YARN),再次執行 start-all.sh 會導致服…

Kotlin 通用請求接口設計:靈活處理多樣化參數

在 Kotlin 中設計一個通用的 ControlParams 類來處理不同的控制參數,有幾種常見的方法:方案1:使用密封類(Sealed Class) sealed class ControlParamsdata class LightControlParams(val brightness: Int,val color: S…

aspark 配置2

編寫Hadoop集群啟停腳本 1.建立新文件,編寫腳本程序 在hadoop101中操作,在/root/bin下新建文件:myhadoop,輸入如下內容: 2.分發執行權限 保存后退出,然后賦予腳本執行權限 [roothadoop101 ~]$ chmod x /r…

Webstorm 使用搜不到node_modules下的JS內容 TS項目按Ctrl無法跳轉到函數實現

將node_modules標記為不排除,此時要把內存改大,不然webstorm中途建立索引時,會因為內存不足,導致索引中途停止,造成后續搜索不出來 更改使用內存設置 內存調為4096 若出現搜不出來js內容時,請直接重啟下該項…

vue-element-plus-admin的安裝

文檔鏈接:開始 | vue-element-plus-admin 之前嘗試按照官方文檔來安裝,運行npm run dev命令卻不能正常打開訪問瀏覽器,換一個方式 首先在目錄下打開命令窗口 1、克隆項目 從 GitHub 獲取代碼 # clone 代碼 git clone https://github.com…

【windows10】基于SSH反向隧道公網ip端口實現遠程桌面

【windows10】基于SSH反向隧道公網ip端口實現遠程桌面 1.背景2.SSH反向隧道3.遠程連接電腦 1.背景 ?Windows 10遠程桌面協議的簡稱是RDP(Remote Desktop Protocol)?。 RDP是一種網絡協議,允許用戶遠程訪問和操作另一臺計算機。 遠程桌面功…