AFAIK, the barbatus:typescript is the "official" typescript support.
However, it seems that the project is not updated anymore.
I think meteor should support typescript natively like meteor supports coffeescript.
Coffeescript is much less popular than typescript:

nathantreid:typescript-babel, a babel based typescript package support also has problems with changing versions of meteor/babel
Having 1st class TypeScript support for Meteor would be huge! There's also a problem with absolute imports that needs to be fixed as well with typescript. https://github.com/Microsoft/TypeScript/issues/13730
I've been writing more and more TypeScript lately, and I approve of this direction. I'm going to need some help validating the functionality of this typescript package, once it's ready, but in general I plan to follow the structure of the packages/non-core/coffeescript package: separating the typescript and typescript-compiler packages, non-core, delegating to babel-compiler to avoid having to compile import and export, etc. The good news is that this doesn't have to be tied to any Meteor release, since doesn't need to be a "core" package.
I'm going to need some help validating the functionality of this typescript package
I am happy to help you out here!
but in general I plan to follow the structure of the packages/non-core/coffeescript package: separating the typescript and typescript-compiler packages, non-core, delegating to babel-compiler to avoid having to compile import and export, etc.
👍 since babel can handle typescript, that's the best way to go!
I'm happy to test any beta release of the typescript > babel package 👍
It would be great to have this.
@benjamn it would be great to see that support added, as we at Rocket.Chat are looking to move towards TypeScript (some of the packages we write extenerally and import are TypeScript) for our code internally. However, as mentioned the barbatus:typescript package isn't up to date with TypeScript and some reason the sourcemaps aren't working as expected (debugging in VSCode leads to the generated JavaScript files instead of the TypeScript).
...it gets more and more annoying to be struck with meteor 2.5 because many newer versions of type definitions use new features and do not compile with 2.5....
@scharf We hear you!
@scharf FYI babartus updated TS to 2.8
I made some experiments using barbatus:typescript versus tsc --watch.
It turns out, that on my project barbatus:typescript takes about 10 times longer to compile.
VELOCITY_DEBUG=1 METEOR_PROFILE=1 meteorbarbatus:typescript: 16 sec Top leaves:
| other plugin barbatus:typescript........................14,191 ms (3)
| linker File#getPrelinkedOutput.............................436 ms (296)
| getPrelinkedFiles toStringWithSourceMap....................256 ms (2)
| Target#minifyJs............................................170 ms (2)
| other compileUnibuild (the app)............................140 ms (3)
| other bundler writeFile....................................112 ms (239)
|
| (#5) Total: 16,592 ms (Rebuild App)
tsc --watch: 1.5 sectsc --watch reacts quite quickly and compiles the file.
| Top leaves:
| other Builder#copyNodeModulesDirectory.....................131 ms (25)
| other plugin ecmascript....................................121 ms (3)
|
| (#5) Total: 1,496 ms (Rebuild App)
I wonder how long it would take when babel does the typescript compilation: Is it more like barbatus:typescript or more like tsc --watch?
Forgot to mention how long it really takes until the app updates: with barbatus:typescript it takes about 25-30 sec and with tsc --watch it takes about 4-5 sec. This adds up during a workday and gets really frustrating.
I have a 2017 MacBookPro (2,9 GHz Intel Core i7), some of my co-workers have slower computers and it takes up to a minute to update with barbatus:typescript.
Wouldn't it be possible to let tsc compile to a dist folder, and have this dist folder watched by meteor? Or would that give to much overhead?
It doesn't sound efficient, as your then building two times. Kind of a 2 stage build. But if I understand @scharf correctly, he's already doing something like that and it seems to be a lot faster.
The only reason I still use barbatus:typescript is for the source map support. Do you guys know any workflow to support sourcemap in meteor with just tsc?
Wouldn't it be possible to let tsc compile to a dist folder, and have this dist folder watched by meteor? Or would that give to much overhead?
I thought about this... Hmmm with the meteor section (in package.json) introduced in Meteor 1.7, it might be possible to do that quite easily.
We're still going to want to wrap tsc with a Meteor compiler plugin, just because that's how Meteor works. Compiling TypeScript files outside of Meteor and letting Meteor think they're JS modules is never going to give an ideal experience.
@benjamn awesome! Any ideas when this will be started or any eta? I would _love_ to get started using TypeScript within Rocket.Chat, since we will soon be having a definitions it only makes sense to move towards TypeScript..especially as a large open source project. :heart:
Compiling TypeScript files outside of Meteor and letting Meteor think they're JS modules is never going to give an ideal experience.
...but if it reduces the update time on each meteor watch cycle form 30 sec to 4 seconds it makes a difference -- and debugging the generated code without .map is better than wasting hours waiting for meteor to update....
That 30 second baseline is based on barbatus:typescript 😉
That 30 second baseline is based on barbatus:typescript 😉
yes ... and I am sure a real integration of TypeScript into meteor could do much better 😉
I have days where meteor rebuilds 300 times and my hack saves me 2h of waiting time....
One more spec to add to this story could be the source map for Android/iOS.
Actually with barbatus:typescript, on Android (don't know on iOS) the TS source map does not appears. There is only the final JS app shown on the chrome remote debugger, making debug more complicated.
Would it be possible to use TypeScript only for the tooling. With a noEmit in the config and to let babel handle all the compilation ?
(glad to see that TS support is coming tho)
I have been working with TypeScript for more than 2 years and love it. I see that many projects either switch to TypeScript or are developed with TypeScript right from the start. I am not a meteor user yet, but would like to try it. Therefore a big +1 for TypeScript only!
UP, any news? Is there official docs how to use TypeScript with Meteor?
Did someone try this already with meteor?
https://blogs.msdn.microsoft.com/typescript/2018/08/27/typescript-and-babel-7/
I hope with Babel directly supporting typescript, that it cannot be that hard for the meteor team to support it....
I tried it out and it works fine with @babel/preset-typescript.
There is one required change in the ecmascript package:
https://github.com/meteor/meteor/blob/4294869c13e49c96520956874744bcd269bd5da1/packages/ecmascript/plugin.js#L2
Plugin.registerCompiler({
- extensions: ['js', 'jsx'],
+ extensions: ['js', 'jsx', 'ts', 'tsx'],
}, function () {
return new BabelCompiler({
react: true
Still this is important:
While Babel can take over compiling/transpiling – doing things like erasing your types and rewriting the newest ECMAScript features to work in older runtimes – it doesn’t have type-checking built in, and still requires using TypeScript to accomplish that.
That means there is no type-checking with the effect that you don't get warning/erros in the meteor console. So you have to configure your code editor to display type issues. The tsconfig.json has no effect on Babel compiling.
It is only used by your code editor/tsc. That's why you should configure it like suggested in https://blogs.msdn.microsoft.com/typescript/2018/08/27/typescript-and-babel-7/:
{
"compilerOptions": {
// Target latest version of ECMAScript.
"target": "esnext",
// Search under node_modules for non-relative imports.
"moduleResolution": "node",
// Process & infer types from .js files.
"allowJs": true,
// Don't emit; allow Babel to transform files.
"noEmit": true,
// Enable strictest settings like strictNullChecks & noImplicitAny.
"strict": true,
// Disallow features that require cross-file information for emit.
"isolatedModules": true,
// Import non-ES modules as default imports.
"esModuleInterop": true
}
}
My .babelrc looks like this:
{
"presets": ["@babel/env", "@babel/preset-typescript", "@babel/react"],
"plugins": ["@babel/proposal-class-properties", "@babel/proposal-object-rest-spread"]
}
I am not sure if we should update ecmascript package to allow processing ts and tsx files. I think this should only be the case if @babel/preset-typescript is added in .babelrc. Otherwise there could be conflicts with barbatus:typescript.
Another solution is to use typescript inside of .js and .jsx files.
It works fine without any changes in the ecmascript package (only add @babel/preset-typescript), but code editors like VSCode will tell you that you can not use typescript inside of javascript files. Still the type check works :).
@lmachens
I tried the same way you did, but babel seems to fail for several different reasons while parsing the code.
imports/client/base/reactive-store.ts:7:9: /home/yorrd/Documents/job/orga/BaseProject/imports/client/base/reactive-store.ts: Unexpected token (7:9)
5 |
6 | class InnerStore {
> 7 | public static store: Map<any, Map<string,
Map<string, any>>> = new Map();
| ^
8 | }
9 |
10 | export class ReactiveStore<T extends ChangeSubject<any>> {
imports/client/adornis-components/a-loader.ts:5: /home/yorrd/Documents/job/orga/BaseProject/imports/client/adornis-components/a-loader.ts: Support for the experimental syntax 'decorators-legacy' isn't currently
enabled (5:1):
3 | import { debounceTime } from 'rxjs/operators';
4 |
> 5 | @element('a-loader')
| ^
6 | export class AdornisLoader extends Base {
7 | private static taskList: Array<Promise<any>> = [];
8 | private static rxjs = new BehaviorSubject<boolean | null>(true);
Did you add any other presets to babel? I tried adding the @babel/plugin-proposal-decorators, to no avail
@yorrd
First issue Unexpected token:
I tried it out in my project and it works. Ecmascript can compile it and do not throw an error.
How does your .babelrc looks like and which version of ecmascript package are you using?
Second issue experimental syntax 'decorators-legacy':
I don't use decorators in this project, but I read that you have to define it before @babel/plugin-proposal-class-properties. See https://babeljs.io/docs/en/next/babel-plugin-proposal-decorators.html#note-compatibility-with-babel-plugin-proposal-class-properties
And you might have to set legacy: true.
@lmachens sorry for the late reply.
I'm now using 0.12.0-rc18.16 with your modifications to the plugin.js. My .babelrc now is
{
"presets": ["@babel/env", "@babel/preset-typescript", "@babel/react"],
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy": false }],
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-object-rest-spread"
]
}
Changing legacy to true / false doesn't make a difference in the outcome.
Btw, that wasn't all the log, I've also got an exception when using class after declare
> 6 | export declare class ProductKlazz {
| ^
Thanks for looking into this!
With @babel/plugin-proposal-decorators I have issues too and had to add "decoratorsBeforeExport": true. Now I get errors here: order: 'asc' as 'asc' | 'desc'. Maybe it it not compatible with @babel/preset-typescript?
It should work together if you take a look at this guide: https://medium.com/@hubert.zub/using-babel-7-and-preset-typescript-to-compile-angular-6-app-448eb1880f2c
@lmachens thanks for your support! When I compile the files with babel, it works now. If I start with meteor, it still has issues with the (static) class properties. Does Meteor's ecmascript package overwrite the .babelrc partially?
The decorator issue is fixed, thanks :)
Working with this .babelrc now, getting an exception which I'm not sure what it's about.
{
"presets": ["@babel/preset-env"],
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose": true }],
"@babel/plugin-proposal-object-rest-spread",
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-transform-typescript"
]
}
W20180927-22:59:38.090(2)? (STDERR) TypeError: Cannot read property 'indexOf' of undefined
W20180927-22:59:38.090(2)? (STDERR) at babel-runtime.js (packages/babel-runtime.js:36:26)
W20180927-22:59:38.091(2)? (STDERR) at fileEvaluate (packages/modules-runtime.js:322:7)
W20180927-22:59:38.096(2)? (STDERR) at Module.require (packages/modules-runtime.js:224:14)
W20180927-22:59:38.097(2)? (STDERR) at require (packages/modules-runtime.js:244:21)
W20180927-22:59:38.097(2)? (STDERR) at packages/babel-runtime.js:85:15
W20180927-22:59:38.101(2)? (STDERR) at packages/babel-runtime.js:92:3
W20180927-22:59:38.101(2)? (STDERR) at /home/yorrd/Documents/job/orga/BaseProject/.meteor/local/build/programs/server/boot.js:411:36
W20180927-22:59:38.101(2)? (STDERR) at Array.forEach (<anonymous>)
W20180927-22:59:38.101(2)? (STDERR) at /home/yorrd/Documents/job/orga/BaseProject/.meteor/local/build/programs/server/boot.js:220:19
W20180927-22:59:38.101(2)? (STDERR) at /home/yorrd/Documents/job/orga/BaseProject/.meteor/local/build/programs/server/boot.js:471:5
That doesn't look like a babel error to me.
That doesn't look like a babel error to me.
more like a babel-runtime error, so within meteor? You're saying I should open a Meteor issue?
@benjamn can you give use feedback to https://github.com/meteor/meteor-feature-requests/issues/285#issuecomment-422291789?
There will be conflicts with barbatus:typescript if we add ts and tsx to the extensions.
So maybe it makes more sense to create a ecmascript-ts package?
Or is it possible to read the .babelrc to find out if @babel/preset-typescript is added, before register extensions?
My past experiments with @babel/plugin-transform-typescript and @babel/preset-typescript have left me with the strong impression that, while compiling TypeScript with Babel is an interesting proof-of-concept, that approach will never be as good as simply using tsc. A much better approach is to use tsc to compile your TypeScript code to modern ECMAScript that Babel can handle, and then use babel-compiler to finish compiling the code down to the modern/legacy/server language targets.
Because Babel configuration can be so complicated, I would also caution against implementing TypeScript support through .babelrc plugins. You really want a separate compiler plugin that handles the .ts and .tsx file extensions. I am not comfortable making the ecmascript package handle those file extensions as well, especially if TypeScript support relies on the developer to include custom plugins in a .babelrc file. If the ecmascript package itself doesn't support TypeScript syntax out of the box, it should not be handling the .ts and .tsx extensions.
Thanks for your answer.
I would use tsc in automatic tests or in a separated process with --watch and not use it to compile the code. This makes it much faster because babel won't perform typechecking. Still you have safe code because of the tsc process/tests.
So it makes sense to create a fork of ecmascript package which supports .ts and .tsx files.
I published lmachens:ecmascript-ts which registers .ts and .tsx files and uses the babel compiler.
See https://github.com/lmachens/ecmascript-ts for a usage guide.
tsc --watchIn my current projects, we run tsc --watch as a separate process.
.js filesOne of the problems I have with tsc --watch is that it does not clean up generated .js files that are supposed to be deleted because the .ts or .tsx file has disappeared.
So, you need something else to clean those files up. We run our build process using make and we created rules to take care of that. But I think a naive use of tsc --watch can cause unexpected problems if you move or delete typescript files.
This is particularly a problem, if you switch branches. There is always the danger of having left over files form a previous branch, if you do not check in the .js files and add them to .gitignore.
We have solved the problem by some versatile make rules, but I was hoping that meteor could handle this.
--outDir)Things are easy, if your entire project has only typescript files. Then you can do something like this to remove the generated typescript files:
find imports client server \( -name "*.js" -o -name "*.jsx" \) | xargs rm -f
But if you are in the process of moving to typescript and you have some javascript files left, then you have to figure out the generated files. And that can be difficult, because you cannot easily tell if the file is a original javascript file or a generated typescript file.
--outDir does not copy non-typescript filesI thought about using another directory tree for the generated javascript files (using the --outDir compiler option), but the problem here is that you may need other resources like style files that you import by relative path. Unfortunately, the tsc --watch does not copy other files into the --outDir which forces you to start something else that copies the files into that directory...
Looking for a simple watch tool that copies the non typescript files into the --outDir, so that the i can use --outDir and tsc does not generate the .js files next to my sources...
tsc --watch can work quite well, if you have some other tools running that make sure that obsolete files are cleaned up or (in case you use --outDir) that you have something that copies the non typescript resources.
Wouldn't that all be fixed if you use the noEmit setting, and use babel to transpile to js?
@scharf are you happy with your rebuild times compared to the tsc solution? Did you notice a significant speedup? We're desperately looking to decrease build times, at this point, I'll do pretty much anything :sweat_smile:
@yorrd we just have two new team members and they have been using barbatus:typescript in their previous project. They are pretty amazed how much faster the build is with the tsc watcher running as separate process. I would jut try it and see what speedup you get...
@scharf loving it! 10 times faster... one issue though: module imports don't work for me anymore (import xyz from 'imports/...'). Any idea on this? Are you just using absolute imports at the moment?
@yorrd
Are you just using absolute imports at the moment?
No, we are using relative imports -- I did not even know that absolute imports would work...
@scharf hmmm, do you mind sharing your tsconfig.json with me? I'm importing paths like imports/client/reactive-store or imports/db which meteor complains about when starting (can't resolve module ... in file ...). I'd be happy to help with the remaining issues.
Here's mine:
{
"compilerOptions": {
"target": "es6",
"lib": ["esnext", "es7", "webworker", "es5", "es6", "dom"],
"baseUrl": ".",
"paths": {
"*": ["*"]
},
"module": "commonjs",
"moduleResolution": "node",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"sourceMap": true,
"allowJs": false,
"strict": true
},
"compileOnSave": true,
}
Mine looks like this:
{
"compilerOptions": {
"module": "commonjs",
"target": "es2017",
"jsx": "react",
"lib": ["dom","es6","es2015","es2017", "dom.iterable","scripthost"],
"inlineSourceMap": true,
"inlineSources": true,
"importHelpers":true,
"experimentalDecorators": true,
"noImplicitAny": true,
"noImplicitThis": true,
"strict": true,
"skipLibCheck": true,
"strictNullChecks": true,
"removeComments": false,
"downlevelIteration": true
},
"exclude": [
"node_modules",
".meteor",
"public",
"private"
]
}
@scharf, I would love to read about how/what you're now doing exactly. Just 'watching' the files for better hinting support in your IDE, or really "bundling" with tsc, and using the mainModule in package.json to point Meteor to the compiled js.
@scharf I'm also very interested in understanding your exact setup. I've been trying a few different methods of replace barbatus:typescript and so far haven't had luck getting everything to work perfectly. (Admittedly, one of my strategies was switching entirely to webpack and that had a lot of complications). I'm using absolute imports and ran into the same problem as @yorrd. Getting super tired of my 20-30 second build times and dreaming of HMR and react-hot-loader...
Just a quick note that the Meteor 1.8 blog post discusses plans for an official typescript package: https://blog.meteor.com/meteor-1-8-erases-the-debts-of-1-7-77af4c931fe3
@benjamn thanks for the update! :tada: I wasn't sure whether you're actually in contact with barbatus about the topic from the wording in your medium post, so I went ahead and opened an issue over at his repository - please upvote and show your support there if you're wondering the same. Even though the official package will hopefully be the go-to solution at some point, many people will still be using barbatus:typescript until then. Let's get some momentum into this thing!
And of course @benjamn, if you need any help testing the official typescript package, I'm here! :smile:
We are using make for all our projects. I don't like unpredictable and non reproducible environments.
tsc -watch is only a small part of what our make doesSo, our Makefile does the following (among other things):
meteor if it is not installedadmin/bin directory which links to the meteor node and meteor npm and some other tools (we had really bad experience adding node_modules/.bin to $PATH, because it contained a touch command, which was very different from the unix touch command. In general, adding this directory at the beginning of $PATH is dangerous, adding it at the end has the risk of something else in $PATH to shadow the expected command, which makes the environment unpredictable)admin/activate script that users can source in bash. It puts this admin/bin at the beginning of the $PATH so that npm calls the correct one (it also sets other environment variables if needed)clean traget that removes all generated codestart target that installs everything needed (including compiling the typescript files if needed)start also starts a tsc --watch process (after making sure there are no obsolete .js files).js filespre-commit and pre-push hooks (since make is clever, it runs things only once. The second time it is fast, unless the conditions have changed. So, if your run tslint successfully and you don't change any file, it will skip the step)tslintyour-branch and I start the app something goes wrong"Makefile.make?You might ask, why we don't use npm commands? Because you need to get the correnct npm in the first place (correct version of node and npm installed). And because make was build to deal with dependencies:
A does not exist your have to run b. X changes you have to run y to update Z.So, when switching branches, the Makefile takes care of all the things that need to be done in order to get things working. It usually uses the minimal steps needed.
It takes some time to maintain the Makefile, but it is like with bugs and testing: if something goes wrong, we add a new rule to the Makefile to deal with it.
I like make (gmake), because it usually comes with dev-tools and there is no need to install it. (but maybe I am biased, because I use make since 30+ years)
Unfortunately, our Makefiles grew quite big and contains stuff that is specific to our Project, so sharing it is not an option...
For new team members, to start working, they do a git clone ... and then make. It takes care of everything (installs what needs to be installed, or complains about things that are missing). It works on Mac Linux and Windows (using cygwin).
I really wonder how other teams do this.
I really wonder how other teams do this.
curl https://install.meteor.com/ | sh
git clone ssh://[email protected]/my-project
cd my-project
meteor npm install
meteor npm run start
Never has let me down.
I'm currently only wrestling to get a nice docker production workflow. The dev environment never has been a problem with meteor (okay, besides the Babel beta troubles)
yeah we're pretty much also just cloning, installing everything with a semi-automated script and we're good to go. Especially with windows, sometimes there are issues, but we have a good Readme for that and a lot of helpful communication in the team ;) don't feel like it's worth the effort to write a custom make file for our needs, given the fact that we're not used to that.
For deployment, mobile building and everything else, we use small custom npm scripts that are tailored 100% to the few distinct environments our team is running on (most arch linux, a few windows with subsystem, mac just uses the same scripts and has been working fine for the past years).
Thanks a lot for your input @scharf ! We're going to wait and see for a couple more days and if nothing is happening try and reproduce your awesome setup :smiley:
I have been using meteor with typescript/barbatus since a few months now, and definitely, looking forward, typescript is the only way to go for us, going back to javascript is just too painful.
Aside from the the outdated/wrong definition files for most packages (including several ones from MDG like react-meteor-data unfortunately) and the compilation times, the experience of typescript + meteor is simply fantastic.
I am really looking forward for an official support for typescript.
Thanks for the fantastic work so far!
While waiting for this support to land, what I did was move new functionality to private NPM modules as much as feasible and just build them with TSC ; and only redeploying the compiled (ES5) files to the main app once the tests pass for the modularized features. Not a solution for our accounts packages, regrettably (accounts-drupal), but works fine for our published Logging package (filog, even with Meteor dependencies.
Alright guys, we have taken action, rebuild times were upwards of 15 seconds which is completely unacceptable for us. Since @barbatus doesn't seem to be active anymore, there is now a fork of barbatus:typescript called adornis:typescript which implements lazy compilation. The effects are notable (testing for client recompilation only atm), thanks @benjamn :
before: roughly 7 seconds typescript compilation (18.2s complete according to METEOR_PROFILE)
after: 1.5 to 2 seconds typescript compilation (12.8s complete according to METEOR_PROFILE)
So that's 1/3 off the recompile time on my laptop (i5 8250U), which is significant. Until here, cc @scharf , how close does this get to your rebuild times?
This is what our METEOR_PROFILE says now:
| wrapped.fs.statSync 1 ms (20)
| Rebuild App..................................................14,025 ms (1)
| └─ bundler.bundle............................................14,025 ms (1)
| └─ files.withCache........................................14,025 ms (1)
| ├─ compiler.compile(the app)............................5,256 ms (1)
| │ └─ files.withCache...................................5,256 ms (4)
| │ └─ compileUnibuild (the app) 5,256 ms (4)
| └─ bundler.bundle..makeClientTarget.....................7,838 ms (2)
| └─ Target#make.......................................7,838 ms (2)
| ├─ Target#_runCompilerPlugins.....................4,958 ms (2)
| │ └─ plugin adornis:typescript 4,682 ms (2)
| └─ Target#_emitResources..........................2,620 ms (2)
| └─ PackageSourceBatch.computeJsOutputFilesMap..2,556 ms (2)
| └─ ImportScanner#scanImports for the app 1,091 ms (2)
|
| Top leaves:
| plugin adornis:typescript................................4,682 ms (2)
| sha1.......................................................783 ms (2264)
| files.readFile.............................................665 ms (492)
| sha512.....................................................462 ms (567)
| Babel.compile..............................................234 ms (838)
| Target#minifyJs............................................181 ms (2)
| ImportScanner#_getAbsModuleId..............................173 ms (5584)
| files.realpath.............................................164 ms (1488)
| ImportScanner#_resolve.....................................123 ms (3767)
| other PackageSourceBatch.computeJsOutputFilesMap...........113 ms (2)
|
| (#31) Total: 14,026 ms (Rebuild App)
Any idea what's still taking up >10 seconds that aren't used compiling typescript? ( @benjamn ) We'd love to do more work, just not sure where to start. It seems that compileUnibuild takes a lot of time. In this specific project, there are 50+ .ts files in the imports directory.
We have a dream where rebuild times are so fast that you don't lose your train of thought while developing while at the same time preventing serious battery consumption, which is a real issue for us. Whatever we can do to help, let me know.
@yorrd This is great!
You might be able to get more granularity from METEOR_PROFILE if you pass a smaller number, e.g. METEOR_PROFILE=10 to show anything that takes at least 10ms. At some point, though, METEOR_PROFILE just won't be precise enough, and you will probably need to use the V8 profiler to see what's really going on. The easiest way to do that is with qualia:profile by @veered.
Looking at the new source code, I may be missing something, but it looks like the lazy callback function you're passing to inputFile.addJavaScript here isn't doing any expensive work, since the result has already been computed? If that's the case, it's actually very good news, since there are potentially still some massive improvements to make, by moving more work into that callback function. Specifically, it would be great to call tsBuild.emit(filePath) lazily, though that may require some refactoring.
@yorrd I tried your adornis:typescript and it is much faster than barbatus:typescript.
Since my app has changed I tried all three ways. I also only reported the time when the system is warm (which means at least the second change on the same file, because the first change is a bit slower...)
I changed a file that is shared between client and server.
Note the Top leaves numbers have quite some variations and since the candidates are so close, the make not much sense. I just took a random sample.
Note For the wall clock time I used a simple stop watch and change the file a few times and created a kind of average.
For the project I have been testing the three approaches, it does not make much of a difference which tool to use: it take 5-7 seconds to update the application. I think the main difference is to use meteor 1.8 (kudos to @benjamn!!!) ! The bad numbers I have measured in June was with meteor 1.7.
Since running tsc --watch and dealing with the generated .js files is a pain, I am ready to switch back to an atmosphere package (provided, it allows me to choose the typescript version)
The watcher uses typescript 3.0.3 and I guess both adornis:typescript and barbatus:typescript use 2.8.3.
I wonder if there is a way to control the version of typescript that is used by the atmosphere packages...
tsc watcherReal time between save and the app updating is about 5-6 seconds
| Top leaves:
| Babel.compile..............................................398 ms (313)
| other bundler writeFile....................................296 ms (107)
| other JsImage#write........................................289 ms (1)
| files.readFile.............................................178 ms (470)
|
| (#7) Total: 2,632 ms (Rebuild App)
barbatus:typescripReal time between save and the app updating is about 6-7 seconds
| Top leaves:
| other compileUnibuild (the app)............................532 ms (3)
| plugin barbatus:typescript.................................435 ms (2)
| other bundler writeFile....................................430 ms (110)
| other ClientTarget#write...................................404 ms (1)
|
| (#7) Total: 2,869 ms (Rebuild App)
adornis:typescriptReal time between save and the app updating is about 5-6 seconds
| Top leaves:
| other compileUnibuild (the app)............................594 ms (3)
| plugin adornis:typescript..................................544 ms (2)
| other bundler writeFile....................................275 ms (110)
| other Target#_runCompilerPlugins...........................217 ms (2)
| files.readFile.............................................174 ms (491)
| Isopack#getUnibuildAtArch..................................128 ms (5161)
|
| (#7) Total: 3,092 ms (Rebuild App)
@benjamn, is there any progress being made in native support? Or sketches of functionality that will be added?
I still believe in a world where typescript in Meteor is supported out of the box, with support for babel plugins. The last part is crucial for me.
I would also be very curious about the MDG typescript plugin that was mentioned in the blog post announcing Meteor 1.8:

Any news on this?
For those interested: Typescript support for path mapping with root imports is coming: https://github.com/Microsoft/TypeScript/pull/27980
Im really interesting in typescript. I like type checking. Even in scripts language i think it's a good idea.
any update?
This silence is terrible and so frustrating. @benjamn, I know you work your ass off. So this is not on you. But this issue does remind me to why I'm migrating away from Meteor.
Is there something that's holding this off? Can the community help?
What’s next
An officially supported typescript package
We will finally be able to share the typescript plugin we’ve been dog-fooding with our Engine app for the past few months.
Until we get the better TS support, is there a simple way to just bump the typescript version barbatus:typescript is using?
@arthurtse have been working on hacking barbatus even further and getting the typescript dependency out of the package so that it uses the project version of typescript. Will update adornis:typescript when I'm done
EDIT: this can only be a temporary measure though since I don't really understand a word of the package, I'm just hacking in what I can to fix the immediate issues
alright here we go. New update released to atmosphere, featuring:
1) chaotic log (cant figure out when to line break), which at least shows you which files are being rebuilt at the moment. I don't think it fits barbatus' log philosophy, but it makes sense to be verbose about what's taking time. That way I found many issues with my code that invalidated caches and dragged out rebuild time
2) typescript 3.2 :tada: well, actually, just any typescript version. You're not forced into what the package is bundling anymore, it will just do a npm require. Make sure you have a version available, there is no fallback or helpful error message if you don't
3) I moved the meteor-typescript npm package into the typescript-compiler package. That's just out of convenience. I'm sure there was a good reason for barbatus doing it this way, but I'm too lazy to maintain and overlook several packages. It's copy / pasta'ed into the typescript-compiler package, no cleaning done.
Guys, make sure your imports are without errors. I just saved like 3 seconds on a reload because I had an .scss-import which couldn't be resolved by the compiler (doesn't matter for running it), but then not only that file, but all depending files are invalidated every time you recompile.
One last thing: I'm trying to figure out the difference in speed to tsc. One thing that stuck out to me was that barbatus:typescript compiles files one by one (using getEmitOutput in meteor-typescript/compile-service.js). Unfortunately, I have NO idea about the typescript compiler. Does it do parallelization? Does it compile whole directories at once?
If anyone knows how the typescript API works, I'd be very thankful for any help we can get while finding the performance bottlenecks and bringing our projects up to speed! :smiley:
@yorrd What's the name of the package?
@yorrd What's the name of the package?
https://atmospherejs.com/adornis/typescript adornis:typescript, just renamed from barbatus:typescript. I do have some weird issues with 3.2.2, but not in every project. Maybe someone with more knowledge can help out when they encounter it.
@yorrd thanks so much for the update, im going to try to use your package immediately, as I hate being stuck to barbatus' ts-version.
Even if I really hope the day we can have non-hacky first-class typescript support in meteor is getting closer, my project rebuild time goes from a few seconds to minutes and even if I am still happy to have my codebase in typescript, it's getting really frustrating to work with
I tried it, unfortunately it doesn't work for me.
It succeeds the web-browser phase in 2minutes (normally takes max 10seconds) but then it crashes:
TypeError: ts.getRegularExpressionForWildcard is not a function
W20190109-11:11:11.559(1)? (STDERR) at getExcludeRegExp (packages/adornis:typescript-compiler/meteor-typescript/ts-utils.js:234:13)
W20190109-11:11:11.559(1)? (STDERR) at typescript-compiler.js (packages/adornis:typescript-compiler/typescript-compiler.js:26:31)
W20190109-11:11:11.560(1)? (STDERR) at fileEvaluate (packages/modules-runtime.js:336:7)
W20190109-11:11:11.560(1)? (STDERR) at Module.require (packages/modules-runtime.js:238:14)
@MastroLindus so you're saying it takes 12 times longer? o.o that's weird
I've also had that exception when I don't have it checked out locally. Does anyone know how to resolve an npm package from the project scope in a package? I think it just doesn't want to load typescript from the outside if it isn't bundled within the package.
EDIT: never mind, typescript is resolved correctly when it compiles earlier. Then it's not resolved anymore when the log in the server scope occurs. I'm not sure why it needs the compiler there, why it is even called there. But I'm even less sure why it can't resolve typescript there anymore. Anyone with experience in compiler plugins?
@yorrd unfortunately yes, the compilation is definitely slower. But it could also be because of the typescript version involved, as ts > 3.x does more checks and work than 2.8, and I use fairly advanced types in my project, so I wouldn't be sure that we need to blame your package for it.
@MastroLindus by no means, blame the package, I only changed some versions and logging. Please try the new version, maybe it's just a matter of the cache not being built yet.
With the new version, there is a chance that the exception is gone. I've tried to depend on it in a different way, maybe that's it.
@yorrd
tried new version, error gone, and compilation back to 6 seconds :)
I'll test it a little bit more and let you know if something comes out, but so far, it's very promising, great job!
@MastroLindus do you have reliable numbers for the comparison? Is it really 10 vs 6 or is that just a guessed value?
@yorrd no, just a guessed value sorry, as barbatus' version unfortunately didn't output the time taken.
Now it feels kind of similar to before.
When I mentioned 10seconds was because it was very different from the first value I got with your plugin (120seconds), but that it was probably caused by the error.
Just tried to measure some times with the new adornis:typescript version and here is what we got (to be honest we did change some imports while changing the version):
note: We measured the time from saving to browser reload
adornis:[email protected] (4 reloads average): 11.36s
adornis:[email protected] (6 reloads average): 8.29s
tried new version, error gone, and compilation back to 6 seconds :)
I'm looking quite jealous now. Building on Windows, with default compiler, takes me easily 2 minutes between recompiles.
@smeijer I am on linux on quite a fast machine (i7 7700, 16gb ram, ssd), so that might already bring a lot of difference.
Also the initial build time has a lot of stuff already cached. If i change a file with a long dependency/import tree, it takes around 15seconds for recompiling it (x2 because of the web.legacy step).
Likely most of my changes only impact 2-4 files so recompilation is quite quick
What I'm working on next:
1) why are we recompiling every file twice (once for cordova)? Want to turn this off
2) bigger issue: what is Meteor doing before and after those ~.3s for each file that needs to be compiled. I'm quite happy with the compilation itself, but I don't get what takes so long before and after, leading to 6 second reloads while compilation only takes <1s
3) HMR? I would love it. I've found a cool but abandoned repo (our discussion at the bottom), now I'm trying to figure out how to do it for Meteor 1.8. This all is really blocked by my lack of understanding of the Meteor compile system.
@benjamn any chance you can give me a few quick pointers where I need to look to implement HMR in Meteor 1.8? Is this something that can even be done in the current state of Meteor? What are the concepts from the build system I need to understand to get working on this?
Thanks all for your feedback on the new version! :smiley:
Update
meteor remove-platform android. Duh. This is quite confusing.
Barbatus modules and @types/meteor package don’t look to be supported by their authors (even though they show up first wherever one search for ‘meteor typescript’
@yorrd points to some Adornis modules hacked/forked off of barbatus.
Official Meteor communication on TypeScript isn’t helping much.
I’d more than happily contribute to any project aiming at improving Meteor/TypeScript integration (tsc integration and transformers, as well as up to date and useful @types definitions)
@PopGoesTheWza the Adornis:typescript works well for me and is imho the best option at the current point of time, until the official Meteor support is available.
The current status is indeed a bit frustrating. @benjamn is a really hard worker but it seems that a lot of his time is now also dedicated to Apollo like for the rest of MDG and the already slow meteor progress is now really going forward at a glacial pace.
I don't blame them but I am not a real fan of graphql in general so I don't want to migrate to it, the simplicity of meteor is what attracted me in the first place.
It's even more sad since it looks like there's plenty of people in the community willing to contribute, but without some support from the official maintainers its quite hard. Also in the meteor blog update it has been mentioned that internally they already have better support for typescript, and it's a pity that the community needs to wait this long for it.
However, at the same time, we are not in a terrible place.
Adornis:typescript works quite well, even if there's much more potential to exploit
The @types/meteor definitions are not terrible, they are a good starting point.
In my own projects I had to override a few:
-allowing Meteor.users collection to be of a type that extends Meteor.user so I can use my custom fields
-the mongo types could be slightly improved
but overall they are ok.
The situation is different for types of atmosphere packages (alanning:roles, validatedMethod, etc) that are in really bad shape or completely absent.
However most of them have minimal APIs so to have your own declaration files is not a lot of work.
In general I managed to use successfully typescript with meteor for several months now, things could be better, but the situation is already much better than a few months ago and eventually we will get to that better state.
I'll contribute to @yorrd 's Adornis forked module for TypeScript compilation.
Regarding the DefinitelyTyped types, I'll try to ping the maintainers and see how it can be updated or if a new set of maintainers is needed.
In the same situation here, what I've been doing in the last few months is push all new logic to node (npm) packages written in TS and compiled separately. Some are public, like https://github.com/fgm/meteor_server_info or https://github.com/fgm/filog but most are private. In that approach, the packages are built and tested in isolation, and the application just brings them in using the compiled version like any contributed node_module, the core application logic remaining in ES6 for now. Definitely not ideal, but it avoid the extra-long TS compilation times and issues with the barbatus package and encourages decoupling within the application.
@PopGoesTheWza since it doesn't seem like barbatus is maintaining his stuff anymore at all, I'm considering taking the project on and moving it over into a new repository to allow for separate issue tracking. What do you think? Assuming Meteor doesn't release anything in the near future. We are certainly willing to put time into this, too, as we have done already.
@benjamn it would really help to know how many things are on your todo list before typescript. Just let us know if this is not something you're working on in the next months, then we'll find a sustainable solution. I just don't want to invest days after days into a solution that is going to be replaced very soon anyways
cc @fgm @MastroLindus , didnt see the new replies, sorry.
the meteor-types is from barbatus as well as far as I can see
@yorrd I don't use meteor-types, i use definitelyTyped definitions:
https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/meteor
@yorrd as soon as the next repo for barbatus/ardonis:typescript is settled, I'll start contributing. Likely to first simplify dependencies (typescript-runtime should be merged into typescript-compiler imho) and better support TypeScript 3.2 feature and compiler.
@MastroLindus I was referring to DefinitelyTyped (where barbatus is listed among the maintainers) which could do with some/much improvements.
@yorrd One thing I noticed recently is that I don't see anymore errors in the command line , I am using visual code as a IDE with the typescript version set to my workspace one, and if I open the file with it I do see the errors correctly, but not when meteor/adornis compile those files... I didn't notice this previously..
@PopGoesTheWza finishing the move to a new repo and some minor cleanup today
@MastroLindus yeah. We had loads of warnings and I didn't have the nerve to only show fatal errors. You're right, that's high up on the todo list. Feel free to contribute once we got the repo. Sorry for not communicating this
@MastroLindus fixed in the last version, syntax errors are shown now. For the rest, use your IDE :P (logging is kind of a mess right now, whatever, later)
@everyone new github repos @ https://github.com/Adornis/typescript and https://github.com/Adornis/typescript-compiler, please use the former for issues. Pull requests absolutely encouraged. Let's move the discussion there.
Hi @benjamn !
When using the official Typescript support in Meteor, which will hopefully be publicly available soon, can you provide information, if it is (would) be possible to run babel transform plugins on the generated JS code from TS files in the Meteor build system? It would be an important feature. (Or if not to use babel plugins generally, to use babel macros (with babel-plugin-macros), which might be easier because of the no configuration needed compared to using babel plugins)
My workaround for using typescript in meteor has been to use the tsc --watch command, and then output all of my typescript target es6, which meteor then sees and does it's normal build process.
It's not perfect, but it's actually pretty fast and lets me use typescript without having to wade into meteor's build system.
You will need to declare some modules in order to import Meteor packages into typescript files for everything to play nicely together.
we managed to make the typescript version variable in adornis:typescript. You can now "link" your project's typescript version into the package WITHOUT cloning it locally. Especially important because TypeScript 3.4 has a 20x performance regression in our projects...
@yorrd In the adornis typescript readme it states that
TYPESCRIPT_EXTERNAL_PATH can be set to the path of a typescript node package anywhere on your computer to be able to use a different version that is used in the package by default -- only works when you clone locally, ask Meteor why, I don't know
Here though you mention that it works without cloning it locally.
Which one is it? :)
I am really interested as indeed 3.4 has a huge performance issue that should be fixed in typescript@next, and would like to adopt it without having to mess up with local cloning..
@MastroLindus sorry, I thought we could do it. It seems Meteor doesn't forward env vars to the compiler by default. Maybe someone else knows more about this?
In our team, we currently just downgrade the adornis:typescript version to 0.9.8 which still uses 3.3.4000
@yorrd that's too bad, thank you anyway for trying and sorry I cannot help too much, my knowledge of meteor internals is also very limited.
If you have access at least to the meteor root folder of the project, would it be possible, even without the need for an env var, to check if there's a typescript version installed in METEOR_ROOT/node_modules/typescript and use it if found?
as I would expect 99% of people that would like to use a specific version of typescript would just install it there with meteor npm install typescript. It wouldn't really be a flexible design as with an env-var, but it would still be better than getting stuck with a fixed unchangeable version..
Of topic: In my pursue to move away from some meteor core stuff an be more compatible with standard components, I switched from adornis:typescript to ardatan:webpack with all it takes and I am pretty happy with compilation times, hot loading and such. Boopup time increased, but I am using typescript 3.4.1, so that might be related.
@MastroLindus I agree. Played around with using the typescript version from the hosting project folder but didn't succeed so far. To be honest, I forgot what I have tried, it's been a few months. Honestly, at the moment I'm happy with just pushing the version manually, don't think it's worth the hassle. If someone wants to submit a pull request, I'll gladly accept.
@arichter83 we did try doing webpack in meteor, it just doesn't feel like meteor anymore tbh. The no config build system is one of the biggest reasons we use meteor.
@arichter83 we switched our main project from the standard build to webpack last year, and were happy with it in the beginning. Then we noticed recurring build time issues, extra machine load due to changes detection, then the package went unsupported, and fast-forward a few months, we're back on the standard Meteor build and getting all the improvements brought with the new versions. At this point, webpack no longer seems an worthy option for Meteor projects.
@yorrd thank you so much for your efforts anyway. Hoping that sooner or later we will get a more official typescript compiler from MDG, going forward in this way for a few months is not that bad, and your plugin has come a long way too!
@arichter83 I join the others in saying that for me too weback is not the answer. We already don't use blaze anymore, we already use many NPM packages instead of atmosphere, we already opt-out reactivity when we don't need it, if we stop using the meteor build tools tools in favor of webpack at that point the whole point of using meteor in my opinion would become questionable.
Hopefully some official input is still inbound.
In the meantime, we've been experimenting with using JSDoc typing. Perhaps not as clean, but seems to work well enough. There's some documentation scattered around the place on how to get started, e.g. on the TS Github wiki.
Biggest problem: there's nothing that warns you about type errors when running your application, so it can be tempting to ignore how correct your typings are.
When types hard to express in JSDoc format, you can drop down to .d.ts files like so:
// moduleUno/index.types.d.ts
export type MyFunc = <T>(param: T) => T
// moduleUno/index.js
// @ts-check
/** @typedef {import('./index.types.d.ts').MyFunc} MyFunc */
import { Meteor } from 'meteor/meteor'
/** @type {MyFunc} */
export let myFunc = param => {
return param
}
/**
* @template T
* @param {T} param
*/
export let myOtherFunc = param => {
return param
}
// moduleDos/index.js
import { myOtherFunc } from './moduleUno'
// ^^^^^^^^^^^ -- should grab the type info from the other module
// (and it should be `<T>(param: T) => T`)
So if you need typechecking, don't want to commit to writing actual TypeScript in Meteor yet, and don't mind the Ecmascript package's performance, this seems like an OK alternative solution.
@ceigey We've been doing exactly that for almost half a year now and I would recommend it to anyone that is unable to commit completely to TS.
Given that @benjamn talk at the next Meteor night is: _Reimplementing Meteor in TypeScript, Module by Module_
This looks quiet promising.
https://forums.meteor.com/t/bay-area-meteor-night-returns-july-9th/49297
So how are you guys handling this now? babel-typescript? ardonis:typescript? Make tsc compile to a single file, and feed that to meteor?
It would be interesting to know how you've handled this. And if there is a migration path, that allows for a ~slow~ gradual migration instead of a huge refactoring job.
So how are you guys handling this now?
@smeijer for my team, we're transitioning from using tsc manually and pointing Meteor to the build artefacts, to using ES6+ with JSDoc comments and .d.ts files (as hinted at in my above comment).
Both approaches require running tsc in --watch mode in the background, but the latter solution is far less intrusive (as there's no awkward situation where Meteor is requiring tsc to build the files first to run).
@smeijer well I'm biased (disclaimer, adornis:typescript is my baby).
That being said, one of Meteor's strengths is its easy to use compiler which doesn't need hours of configuration work. So the only real solution is to have a compiler plugin. Working on incremental at the moment, could use help...
Every other solution involves having a separate process we have to manage or essentially not writing .ts which sucks as a solution imho.
So how are you guys handling this now? babel-typescript? ardonis:typescript? Make tsc compile to a single file, and feed that to meteor?
@smeijer I'm still compiling my .ts and .tsx files into their .js and .jsx counterparts, which meteor then sees. It's not perfect but I think it's the best way to write typescript in an incremental fashion and doesn't involve getting into the meteor compilers core guts.
@yorrd I agree that one of the main reasons why I use meteor is that I don't want to get sucked into webpack configs and compiler settings, which is why it would be really nice to have first class support for typescript. Hopefully in a future release!
Cross-posting this comment:
If you update to the latest beta by running
meteor update --release 1.8.2-beta.16
you can then run
meteor add typescript
to try the new typescript package introduced by https://github.com/meteor/meteor/pull/10610. See that PR for a discussion of missing features and future plans.
Thanks to @scharf for starting this discussion, and to everyone else for investigating different strategies here. I know I didn’t comment much, but I was paying attention.
@benjamn Thank you. As I understand, the Meteor Typescript compiler has certain limitations. Can you clarify what advantages it brings compared to using the official Typescript compiler directly and having it generate js(x) files in a directory seen by Meteor build, so Meteor builds them into the final product (processing them through Babel)?
@alesn I believe the PR convo here https://github.com/meteor/meteor/pull/10610 will answer your questions.
@filipenevola This has been resolved, right? See previous comment.
@benjamn Thank you for your effort!
Since I opened it, I will also close it!
Most helpful comment
I've been writing more and more TypeScript lately, and I approve of this direction. I'm going to need some help validating the functionality of this
typescriptpackage, once it's ready, but in general I plan to follow the structure of thepackages/non-core/coffeescriptpackage: separating thetypescriptandtypescript-compilerpackages, non-core, delegating tobabel-compilerto avoid having to compileimportandexport, etc. The good news is that this doesn't have to be tied to any Meteor release, since doesn't need to be a "core" package.