vazco / universe-modules

Use ES6 / ES2015 modules in Meteor with SystemJS
https://atmospherejs.com/universe/modules
MIT License
52 stars 7 forks source link

Need a workaround for typescript #7

Closed vjau closed 9 years ago

vjau commented 9 years ago

I need a workaround for typescript to work. Typescript is able to generate es6 modules, so i thought it could be a good way to get typescript modules to work with meteor through this loader. The problem is that in the foomodule.import.ts source code you have following code :

export default function(){
  return "foo";
}

This file will be transpiled by Typescript compiler to foomodule.import.js es6 code.

Now if i want to import the module in main.import.ts with this code :

import foo from "./foomodule";
foo();

The typescript compiler will complain that foomodule doesn't exist, since the js file is called foomodule.import.js and typescript will look for "foomodule.ts" or "foomodule.js". To make typescript happy, you have to write:

import foo from "./foomodule.import"
foo();

but then the universe-modules loader doesn't find the module...

Any idea for a workaround ?

MacRusher commented 9 years ago

Check out https://github.com/systemjs/systemjs/issues/489 and https://github.com/systemjs/systemjs/issues/506

I'm not familiar with TypeScript, but you should be able to achieve what you want by writing own SystemJS normalization function.

Example implementation is in this post https://github.com/systemjs/systemjs/issues/489#issuecomment-111073905 but instead of that you should check for .import.js or .import.ts and drop last 10 characters, or .import and drop last 7.

Then in you typescript you could write import foo from "./foomodule.import.js" or import foo from "./foomodule.import" and SystemJS will find module that you are looking for.

Note: I have a plan to implement custom normalization/loading functions and ship them with universe:modules as a default. Main reason is to provide better error reporting (current system default is very misleading in context of meteor) and allow loading external assets. This will also allow working TS out of the box.

When you got TS working you can post your solution here, it could be a good base for building default universe:modules normalizer.

vjau commented 9 years ago

Thank you for your help. Actually, i don't need typescript transpiling since this is done in my IDE (Webstorm or Atom). I have been able to correct my problem by doing a simple

moduleId = moduleId + ".import";

before calling Babel.transformMeteor in build-plugin.js This way i can write code typescript is happy with

import foo from "./foomodule.import"

and having a working script once the module is loaded However i cannot see how this could be a general solution for everyone.

MacRusher commented 9 years ago

Does typescript allow you to write import foo from "./foomodule.import.js"? e.g. the full path name? Is this better solution for you or you want to write foomodule.import instead? I will implement this in next version of universe:modules :)

vjau commented 9 years ago

No, typescript doesn't seems to be happy with the full path name (with extension). It's my understanding that es6 modules doesn't allow you to do that either. So for now, i'm "stuck" with import foo from "./foomodule.import", and that's really not a problem. Thanks !

MacRusher commented 9 years ago

Version 0.3.0 should work for you out of the box!

Let me know if something isn't working for you.

vjau commented 9 years ago

New problem with typescript when used with packages : when doing import bar from "me:foo/foo.import" typescript is not happy since he doesn't know a file with that path. I have tried to replace it with `import bar from "packages/foo/foo.import" which make typescript happy, and to use a system.config map to translate those to the real adress, but i could'nt get it to work. Last thing i tried was

System.config({
  map:{
    "packages/packa/packa.import" : "meteor://vjau:packa/packa/packa.import"
  }
})

Thank you.

MacRusher commented 9 years ago

I'll have to improve support for SystemJS configs like map/package/paths. https://github.com/vazco/universe-modules/issues/9 is a related issue.

You could try using SystemJS paths instead of map. Something like

System.paths['meteor://packages/packa/*'] = 'meteor://vjau:packa/*.js'

Just thinking out loud, not sure if this gonna work. Let me know if this gets you into right direction.

But you're gonna run into some problem once you start hosting your packages on atmosphere and not locally inside your packages dir. There is no way to configure TS to be more liberal?

BTW. I'm preparing a test suite with all use cases officially supported by this package. This way there will be no more regressions, at least not in official use cases. I'm planning a first class citizen support for SystemJS packages / Meteor packages connection so this will get better over time. So keep posting these corner case use cases :+1: