2017-05-14 40 views
0

我正在使用Typescript,ES6模塊語法和SystemJS/builder。Systemjs Bundle全局導入配置

我試圖做的基本要求是:

  • 使用@types包使打字稿代碼完成(全球NPM安裝以及)
  • 使用ES6模塊導入語法(如import * as _ from 'lodash'
  • 讓構建者從構建中排除全局變量,並仍然使用dev/production中的CDN URL來正確導入它們。

我使用的構建和開發/生產ENV的配置只是爲了得到它,並打算:

System.config({ 
    meta: { 
    "lodash": { 
     "format": "global", 
     "build": false, 
     "exports": "_" 
    } 
    // ...more meta 
    }, 
    map: { 
    "lodash": "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js", 
    // ...more maps 
    } 
}); 

從這裏我有transpiles到ES6一個NPM任務,然後一切都捆綁通過babel插件進入單個文件。該腳本直接加載到生產頁面上並加載。問題是,一旦一個全局依賴進口我不斷收到類似的錯誤「_.clone不是一個函數」等,由於systemjs包裹CDN進口與對象像

{default: _ } //_ is the actual lodash export

我已經成功地改變導入到import _ from 'lodash' 但後來我得到IDE錯誤,因爲lodash(也沒有任何其他全局腳本像角)不會導出默認值,我失去了代碼完成。

這裏滿足systemjs/builder的需求的正確方法是什麼?

作爲一個方面說明,我很好,使用腳本標記加載,而不是systemjs CDN導入,如果更好。

回答

1

對於這種情況,TypeScript有一個標記--allowSyntheticDefaultImports。具體來說,它通知類型分析者另一個轉換器,加載器或捆綁器在後面的步驟中提供映射module.exportsexports.default

可以在tsconfig.json下編譯器選項指定該標誌

{ 
    "compilerOptions": { 
    "target": "esnext", 
    "module": "es2015", 
    "allowSyntheticDefaultImports": true, 
    "moduleResolution": "node", 
    "baseUrl": "." 
    } 

注意,當模塊格式設置爲"system",設置該標誌含蓄。現在

你可以寫

import _ from "lodash"; 

和打字稿會理解它,它進行類型檢查,並驗證其是否正確使用。但是,這隻會影響類型檢測。在這種情況下,您仍然需要一個提供運行時綜合的加載器或中間轉換器。

import * as _ from "lodash"; 

違反提出的NodeJS - > ESM互操作的建議,如果你把它作爲_([1, 2]).map(x => x ** 2)也違反了ES規範其禁止被調用的模塊命名空間的對象,所以你做得很好利用的。 SystemJS提供的--allowSyntheticDefaultImports標誌和interop。

+0

對於未來的觀衆:最終工作的結果是將Aluan的答案和將TypeScripts編譯模塊格式設置爲「System」「」「module」:「System」,「'」的組合。如果我只在全局上切換了syntheticDefaultImports,那麼是正確的,但'default'鍵未定義。 –

+0

@RyanQ,應該不是這種情況,我認爲你在SystemJS中缺少包配置。使用'「模塊」:「系統」'是一個不錯的選擇,並且是推薦的,但它不是必需的。回想一下'--allowSyntheticDefaultImports'隻影響類型檢查。如果SystemJS沒有自動提供默認值,那麼幾乎肯定會有一些缺失配置,但很難說沒有看到你目前的配置。 –

+1

你在配置部分是正確的。當我最終找到解決方案時,我會回到這裏,但目前我還沒有找到一個適合dev/production的良好配置。 allowSyntheticDefaultImports至少在IDE方面有所幫助。 –