2017-04-14 51 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

相关问题