2017-04-14 382 views
7

Here is SystemJS + TypeScript plunk,從official Angular plunk template創建。.ts文件不被視爲TypeScript模塊

它拋出

(SystemJS) SyntaxError: Missing initializer in const declaration

at eval()

...

錯誤和明顯評估的.ts文件作爲普通的JavaScript時,文件不包含importexport聲明:

main.ts

const foo: boolean = 'foo'; 

console.log(foo); 

config.js

System.config({ 
    //use typescript for compilation 
    transpiler: 'typescript', 
    //typescript compiler options 
    typescriptOptions: { 
    emitDecoratorMetadata: true 
    }, 
    paths: { 
    'npm:': 'https://unpkg.com/' 
    }, 
    //map tells the System loader where to look for things 
    map: { 

    'app': './src', 
    ... 
    }, 
    //packages defines our app package 
    packages: { 
    app: { 
     main: './main.ts', 
     defaultExtension: 'ts' 
    }, 
    ... 
    } 
}); 

的index.html

... 
<script src="https://unpkg.com/[email protected]/dist/system.js"></script> 
<script src="config.js"></script> 
<script> 
System.import('app') 
    .catch(console.error.bind(console)); 
</script> 
... 

the same plunk is fine當文件具有ES6模塊的跡象:

main.ts

const foo: boolean = 'foo'; 

console.log(foo); 

export default null; 

顯然,如果一個文件有.ts擴展名,I寧願將其評估爲TypeScript,無論它是否導入。

爲什麼在此設置中會發生這種情況?這怎麼解決?

+1

您應該使用'plugin-typescript'。 'systemjs'不附帶譯碼器,所以'transpiler:'typescript''不起作用 – unional

+1

我不認爲這是真的。如果出現'export'語句,TS將起作用。這就是問題所在。否則'const foo:boolean ='foo''會拋出一個語法錯誤,不是嗎? – estus

回答

4

SystemJS可能會工作如下:

> System.import('app') 
    - where is 'app'? 
> map: { 'app': './src', ... 
    - Okay, 'app' is './src' 
    - './src' ?? 
> packages: { app: { main: './main.ts', 
    - Aha, './src/main.ts' 
> ./src/main.ts 
    - Which format?? 
    - 'system' ? -> No 
    - 'esm' ? -> No (if YES, use transpiler: 'typescript') 
    - 'amd' ? -> No 
    - 'cjs' ? -> No 
    - 'global' ? -> Yes -> No transpiler needed. 
> evaluate ./src/main.ts 
    - What is ':string' in JavaScript? 
    - Exception!!! 

Module format detection

When the module format is not set, automatic regular-expression-based detection is used. This module format detection is never completely accurate, but caters well for the majority use cases.

如果自動檢測失敗,則必須手動指定它。

方法1:添加提示來源

EX1:添加export(來自問題)

const foo: boolean = 'foo'; 
console.log(foo); 
export default null; 

EX2:添加export

export const foo: boolean = 'foo'; 
console.log(foo); 

方法2:添加format配置

EX1:包/路徑/間/模式(./ main.ts或./*.ts)/ format

packages: { 
    app: { 
     main: './main.ts', 
     defaultExtension: 'ts', 
     meta: { 
     './main.ts': { 
      format: 'esm' 
     } 
     } 
    } 

EX2:包/路徑/ format

packages: { 
    app: { 
     main: './main.ts', 
     defaultExtension: 'ts', 
     format: 'esm' 
    } 
} 

EX3: meta/pattern(需要應用/前綴)/ format(外部包)

meta: { 
    'app/main.ts': { 
     format: 'esm' 
    } 
} 
+0

太好了,這很詳盡,謝謝。 – estus

3

免責聲明:這只是一個小小的調試,我沒有真正體驗過這個主題,所以對我的理解有任何更正都是值得歡迎的。

如果模塊格式正確確定,SystemJS將只執行轉譯。如果沒有通知模塊格式,它使用快速啓發式來嘗試並確定它(基本上,源代碼上的正則表達式)。 當您有導入語句時,此啓發式工作,當您沒有時導致失敗。 爲您設置了實際的解決方法是明確添加模塊格式的包像這樣:

app: { 
    main: './main.ts', 
    defaultExtension: 'ts', 
    format:'esm' // << Module format. 
}, 
+0

謝謝,這個問題不包含完整的解釋,但任何方式都擊中了公牛的眼睛。 – estus