.ts file isn't treated as TypeScript module
Asked Answered
R

2

7

Here is SystemJS + TypeScript plunk, created from official Angular plunk template.

It throws

(SystemJS) SyntaxError: Missing initializer in const declaration

at eval ()

...

error and obviously evaluates .ts file as ordinary JavaScript when the file doesn't contain import or export statements:

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>
...

But the same plunk is fine when the file has signs of ES6 module:

main.ts

const foo: boolean = 'foo';

console.log(foo);

export default null;

Obviously, if a file has .ts extension, I would prefer to evaluate it as TypeScript, whether it imports something or not.

Why does this happen in this setup? How can this be fixed?

Rustle answered 14/4, 2017 at 23:40 Comment(2)
You should be using plugin-typescript. systemjs does not come with transpiler so just transpiler: 'typescript' does not workDaciadacie
I don't think it's true. TS works if there is export statement. This is what the question says. Otherwise const foo: boolean = 'foo' would throw a syntax error, wouldn't it?Rustle
A
4

SystemJS will probably work as follows:

> 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.

If auto-detection fails, you must specify it manually.

Method 1: Add hints to source

ex1: add export (from question)

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

ex2: add export

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

Method 2: Add format configuration

ex1: packages / path / meta / pattern(./main.ts or ./*.ts) / format

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

ex2: packages / path / format

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

ex3: meta / pattern (need app/ prefix) / format (outside packages)

meta: {
    'app/main.ts': {
        format: 'esm'
    }
}
Acinaciform answered 26/5, 2017 at 14:16 Comment(0)
D
3

Disclaimer: This comes from just a little debugging, I'm not actually experienced in the subject so any corrections to my understanding are welcome.

SystemJS will only perform transpilation if the module format is determined properly. If the module format is not informed, it uses a fast heuristic to try and determine it (basically, a regular expression over the source). This heuristic works when you have the import statement and fails when you don't. The actual fix for your set up is to add the module format explicitly to the package like so:

app: {
  main: './main.ts',
  defaultExtension: 'ts',
  format:'esm' // << Module format.
},
Diabolism answered 24/5, 2017 at 22:55 Comment(1)
Thanks, the question doesn't contain full explanation but hits the bull's eye any way.Rustle

© 2022 - 2024 — McMap. All rights reserved.