frankwallis / plugin-typescript

TypeScript loader for SystemJS
MIT License
248 stars 47 forks source link

js error when loading - cannot read property 'length' of undefined #203

Closed JustASquid closed 7 years ago

JustASquid commented 7 years ago

I've decided to try and switch over to using plugin-typescript with systemjs, instead of first compiling to es6 and then using babel in systemjs - so that I can (hopefully) have source maps working in the Chrome debugger.

I'm not sure where the problem is coming from - it could just be that I don't totally understand the required configuration.

I've mucked around with the setup, and this is the closest I've managed to get.

Here's the relevant part in jspm.config.js: (I've tried with and without defaultExtension).

transpiler: "plugin-typescript",
packages: {
    "timebarons": {
        "main": "main.tsx",
        "defaultExtension": "ts",
        "meta": {
            "*.tsx": {
                "loader": "typescript",
                "typescriptOptions": {
                    "tsconfig": true
                }
            },
            "*.ts": {
                "loader": "typescript",
                "typescriptOptions": {
                    "tsconfig": true
                }
            }
        }
    }
}

Here's the tsconfig file (I can't find any information on the difference between es6 and es2015 here!)

{
  "compilerOptions": {
    "target": "es2015",
    "module": "es2015",
    "sourceMap": true,
    "jsx": "react",
    "allowSyntheticDefaultImports": true
  },
  "exclude": [
    "jspm_packages",
    "source/shared/flags_prod.ts",
    "source/shared/flags_dev.ts"
  ]
}

My directory structure looks like: jspm_packages/ source/ ---otherTsandTsxFiles/ ---main.tsx jspm.config.js tsconfig.json

Where otherTsandTsxFiles contains files included by main.tsx, and source/ is correctly mapped to the package timebarons.

aluanhaddad commented 7 years ago

@JustASquid

Here's the tsconfig file (I can't find any information on the difference between es6 and es2015 here!)

es6 is/was an alias for es2015. Some tools no longer recognize es6, and es2015 is strongly preferred. The reason for the confusion is historical (basically TC39 changed their naming convention when the switched to a different release cadence).

I take it you are using jspm 0.17 👍 because you mention a jspm.config.js file, but it would be good confirm.

You have shown you tsconfig.json file, but have you added the following to jspm.config.js

{ 
  transpiler: "plugin-typescript",
  ...
  typescriptOptions: {
    tsconfig: true
  }
  ...

at the top level?

Also, can I assume you are running

$ jspm bundle timebarons --wid

?

JustASquid commented 7 years ago

Hi @aluanhaddad, thanks for getting back.

Thanks for the clarification regarding es2015. I am indeed using jspm 0.17.

I added the typescriptOptions to the top level (transpiler at top level was already there) but that didn't fix the issue.

I'm not doing any bundling yet, this is all for the dev environment. I don't run any such build step.

However, attempting to do the bundle itself might prove illuminating. Here's the error when trying the bundle:

 Building the bundle tree for timebarons...

err  Error on fetch for timebarons/menu/window.js at  
file:///.../timebarons/public/source/menu/window.js
Loading timebarons/main.tsx
Error: ENOENT: no such file or directory, open '/.../timebarons/public/source/menu/window.js'

It appears to be trying to load a js file - but window is a tsx file, so I assume it's compiling to jsx and then the next step of the bundler can't find it.

aluanhaddad commented 7 years ago

I see, thank you. I find that interesting because combining

transpiler: "plugin-typescript"

with

"module": "es2015"

currently fails when transpiling in the browser (also my preferred development workflow).

As for bundling, the bundle is built in memory, so there are no intermediate .js files created.

As an experiment, could you set "defaultExtension": "tsx" and rename all of your files accordingly.

Different defaultExtension configuration is tricky if you have a mix of .tsx and .ts files in the same directory you will not be able to load them correctly. If you have .ts files and .tsx files mixed in a directory, your best bet is to change them all to .tsx. If they are in different directories, you can use different package configurations to set defaultExtension appropriately.

JustASquid commented 7 years ago

@aluanhaddad

OK, I moved all the tsx files to their own directory and put them in a separate package, as well as making main a plain ts file.

transpiler: "plugin-typescript",
typescriptOptions: {
    "tsconfig": true
},
packages: {
    "timebarons": {
        "main": "main.ts",
        "defaultExtension": "ts",
        "meta": {
            "*.ts": {
                "loader": "typescript",
                "typescriptOptions": {
                    "tsconfig": true
                }
            }
        }
    },
    "menu": {
        "defaultExtension": "tsx",
        "meta": {
            "*.tsx": {
                "loader": "typescript",
                "typescriptOptions": {
                    "tsconfig": true
                }
            }
        }
    }
}

Bundling works perfectly now, however running unbundled still presents a similar error:

aluanhaddad commented 7 years ago

Sorry to hear that. Can you upload a repo? I will take a look.

JustASquid commented 7 years ago

Sorry, I've moved onto other things for the moment, creating a minimal repo is a bit too much work for me right now. Thanks for your help.