New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement an official TypeScript compiler plugin. #10610
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
# typescript | ||
[Source code of released version](https://github.com/meteor/meteor/tree/master/packages/typescript) | [Source code of development version](https://github.com/meteor/meteor/tree/devel/packages/typescript) | ||
*** | ||
|
||
This plugin package enables the use of | ||
[TypeScript](https://www.typescriptlang.org) modules with `.ts` or `.tsx` | ||
file extensions in Meteor applications and packages, alongside `.js` | ||
modules (or whatever other types of modules you might be using). | ||
|
||
## Usage | ||
|
||
The `typescript` package registers a compiler plugin that transpiles | ||
TypeScript to plain ECMAScript, which is then compiled by Babel for | ||
multiple targets (server, modern browsers, legacy browsers, cordova). | ||
By default, the `typescript` package is included in the `.meteor/packages` | ||
file of all new Meteor applications. | ||
|
||
To add the `typescript` package to an existing app, run the following | ||
command from your app directory: | ||
|
||
```bash | ||
meteor add typescript | ||
``` | ||
|
||
To add the `typescript` package to an existing package, include the | ||
statement `api.use('typescript');` in the `Package.onUse` callback in your | ||
`package.js` file: | ||
|
||
```js | ||
Package.onUse(function (api) { | ||
api.use('typescript'); | ||
}); | ||
``` | ||
|
||
## Supported TypeScript features | ||
|
||
Almost all TypeScript syntax is supported, though this plugin currently | ||
does not attempt to provide type checking (just compilation). | ||
|
||
Since the Meteor `typescript` package runs the official TypeScript | ||
compiler before running Babel, it does not suffer from the same | ||
[caveats](https://babeljs.io/docs/en/babel-plugin-transform-typescript#caveats) | ||
known to affect the Babel TypeScript transform. In particular, | ||
`namespace`s are fully supported. | ||
|
||
However, as of this writing, the Meteor `typescript` package compiles | ||
TypeScript modules individually, using the `transpileModule` function, | ||
which means that certain cross-file analysis and compilation will not | ||
work. For example, `export const enum {...}` is not fully supported, | ||
though `const enum {...}` works when confined to a single module. | ||
|
||
Unlike the Babel implementation of TypeScript, there is nothing | ||
fundamentally preventing Meteor from compiling all TypeScript modules | ||
together, rather than individually, which would enable full support for | ||
features like `export const enum`. That's an area for future improvement, | ||
though we will have to weigh the performance implications carefully. | ||
|
||
As of this writing, `tsconfig.json` files are ignored by the plugin. | ||
There's nothing fundamentally preventing the Meteor `typescript` plugin | ||
from accepting configuration options from `tsconfig.json`, but for now | ||
we've kept things simple by avoiding configuration complexities. You may | ||
still want to have a `tsconfig.json` file in your application root | ||
directory to configure the behavior of editors like VSCode, but it will | ||
not be respected by Meteor. | ||
|
||
Finally, since the TypeScript compiler runs first, syntax that is not | ||
understood by the TypeScript compiler, such as experimental ECMAScript | ||
proposals, may cause the TypeScript parser to reject your code. You can | ||
use `.babelrc` files to configure Babel compilation, but TypeScript still | ||
has to accept the code first. | ||
|
||
## Areas for improvement | ||
|
||
* Compile all TypeScript modules at the same time, rather than compiling | ||
them individually, to enable cross-module analysis and compilation. In | ||
the meantime, if you need this behavior, consider using | ||
[`adornis:typescript`](https://atmospherejs.com/adornis/typescript). | ||
|
||
* Use the version of `typescript` installed in the application | ||
`node_modules` directory, rather than the one bundled with | ||
`meteor-babel`. We will attempt to keep `meteor-babel`'s version of | ||
`typescript` up-to-date, but it would be better to leave this decision | ||
to the application developer. | ||
|
||
* Generate `.d.ts` declaration files that can be consumed by external | ||
tools. In particular, a Meteor package that uses TypeScript could | ||
generate `.d.ts` files in the `/node_modules/meteor/package-name/` | ||
directory, which would allow tools like VSCode to find the right types | ||
for the package when importing from `meteor/package-name`. | ||
|
||
* Cache the output of the TypeScript compiler separately from the output | ||
of Meteor's Babel compiler pipeline. The TypeScript compiler does not | ||
compile code differently for different targets (server, modern, legacy, | ||
etc.), so its results could theoretically be reused for all targets. | ||
|
||
* Make the `typescript` plugin look up `tsconfig.json` files (similar to | ||
how `babel-compiler` looks up `.babelrc` files) and obey (some of) the | ||
configuration options. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
Package.describe({ | ||
name: "typescript", | ||
version: "3.5.2", | ||
summary: "Compiler plugin that compiles TypeScript and ECMAScript in .ts and .tsx files", | ||
documentation: "README.md" | ||
}); | ||
|
||
Package.registerBuildPlugin({ | ||
name: "compile-typescript", | ||
use: ["babel-compiler"], | ||
sources: ["plugin.js"] | ||
}); | ||
|
||
Package.onUse(function (api) { | ||
api.use("isobuild:compiler-plugin@1.0.0"); | ||
// The following api.imply calls should match those in | ||
// ../ecmascript/package.js. | ||
api.imply("modules"); | ||
api.imply("ecmascript-runtime"); | ||
api.imply("babel-runtime"); | ||
api.imply("promise"); | ||
// Runtime support for Meteor 1.5 dynamic import(...) syntax. | ||
api.imply("dynamic-import"); | ||
}); | ||
|
||
Package.onTest(function (api) { | ||
api.use("tinytest"); | ||
api.use("es5-shim"); | ||
api.use("typescript"); | ||
api.mainModule("tests.ts"); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
Plugin.registerCompiler({ | ||
extensions: ["ts", "tsx"], | ||
}, function () { | ||
return new TypeScriptCompiler({ | ||
react: true, | ||
typescript: true, | ||
}); | ||
}); | ||
|
||
class TypeScriptCompiler extends BabelCompiler { | ||
processFilesForTarget(inputFiles) { | ||
return super.processFilesForTarget(inputFiles.filter( | ||
// TypeScript .d.ts declaration files look like .ts files, but it's | ||
// important that we do not compile them using the TypeScript | ||
// compiler, as it will fail with a cryptic error message. | ||
file => ! file.getPathInPackage().endsWith(".d.ts") | ||
)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { Tinytest } from "meteor/tinytest"; | ||
|
||
Tinytest.add("TypeScript - basics", test => { | ||
test.equal(2 + 2, 4); | ||
}); | ||
|
||
Tinytest.add("TypeScript - const enum", test => { | ||
const enum Kind { | ||
NORMAL, | ||
WEIRD, | ||
} | ||
test.equal(typeof Kind.NORMAL, "number"); | ||
test.equal(typeof Kind.WEIRD, "number"); | ||
test.equal(Kind.NORMAL + 1, Kind.WEIRD); | ||
}); | ||
|
||
Tinytest.add("TypeScript - constructor member parameters", test => { | ||
class Test { | ||
constructor( | ||
private a: number, | ||
public b: string, | ||
) {} | ||
} | ||
const t = new Test(1234, "asdf"); | ||
test.equal((t as any).a, 1234); | ||
test.equal(t.b, "asdf"); | ||
}); | ||
|
||
Tinytest.add("TypeScript - namespaces", test => { | ||
function foo() { | ||
return foo.bar; | ||
} | ||
|
||
namespace foo { | ||
export const bar = "oyez"; | ||
} | ||
|
||
test.equal(foo(), "oyez"); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,3 +27,4 @@ underscore@1.0.10 | |
import-local-json-module | ||
akryum:vue-component | ||
dummy-compiler | ||
typescript |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export class Test<T> { | ||
constructor(public readonly value: T) {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See meteor/babel#25 for details about how this is implemented in
meteor-babel
.