tsconfig notes
#1291
Replies: 1 comment 1 reply
-
Thanks for writing up all of this knowledge to share! It is amazing what is possible. The challenge is to make that convenient to use, presumably with support tools support. Is there a practical starting point for that? |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I've been spending quite some time trying to get my typescript infrastructure sorted out. It's not easy... This (long!) post is mainly to record what I learned for future reference. Hopefully it helps others avoid some of the hours of frustration. If someone has suggestions or corrections please chime in!
Goal
manifest.json
s that work and properly type check typescript codetsconfig.json
for use in an editor (e.g. vscode) that properly type checks (and suggests) codetsconfig.json
for portabilityDifficulties
There are two parallel typing infrastructures:
both need to be (more or less) in sync but have different constraints
ECMA-419 uses colons in module names (e.g.
embedded:io/digital
) and Windows apparently doesn't like colons in file names so all those modules don't have a direct module name to filepath mapping and necessitatepaths
declarations in tsconfig files (this is not a problem per-se but compounds other problems)tsconfig files do not support any (environment) variable substitution, so anything outside of
.
necessitates absolute paths (or chains of../
which is similarly non-portable)tconfig files have an
extends
feature such that the firmware'stsconfig.json
can include the Moddable SDK'stsconfig.json
and thereby pick-up a lot defined there, except that stuff defined in the firmware tsconfig replaces the included parts. This is particularly annoying forpaths
because the Moddable SDK can have a nicely craftedpaths
clause but as soon as the firmware's tsconfig also has apaths
clause the SDK's one is effectively lost.When writing a host app and mods in typescript one has to refer to the
.ts
files when building the host (so the code gets built into the firmware) but one has to refer to corresponding.d.ts
files when building the mod otherwise the module gets loaded twice. E.g., suppose the host has a moduleutil
inutil.ts
then the hosts' firmware needs to include that file but if a mod also want to use the utils it should refer to autil.d.ts
so it gets just the type declarations and not all the implementation again.Solutions
The building of application firmware is relatively straight-forward thanks to the fact that mcconfig produces a tsconfig that merges all paths defined in all manifests.
Getting the tsconfig for the IDE to work properly is more tricky. First I created a base
tsconfig.json
located in the Moddable typings dir. Conveniently is has no absolute paths:Next, this can be included in an application's
tsconfig.json
, which can be as short as(The include isn't even necessary if you don't mind all
.ts
in the subtree being included.)But as soon as the application needs a
paths
declaration it has to repeat the SDK's paths and has to use absolute paths for that. For example, my app defines anembedded:network/something
module:Now mods are not obvious at all. First I tackled the compilation. For this, we need
.d.ts
files for all modules in the host firmware that may be used in the mod. For modules in the SDK this is easy because these files all exist in the typings dir (this would change if someday the SDK includes.ts
files). For typescript modules in the application one can ask the typescript compiler to produce.d.ts
files by adding this into the application's manifest:This provides a directory tree that the manifest for the mod can now include. The best way I found is to post-process all the
paths
in the manifest generated by mcconfig for the host because that lists everything in the host and thus everything the mod could import. The result is a manifest that the mod can include. The manifest for the mod looks something like this and expects theHOST
environment variable to be set appropriately:In my case the paths in
manifest_host.json
undergo a bunch of transformations to replace leading path components by$(MODDABLE)
or$(HOST)
and to deal with some cases where the.d.ts
file doesn't end up where it's needed. I also had to edit some of the generated.d.ts
files to remove a/// reference
line.The tsconfig for the IDE is a bit more tricky as it needs to reference the typings produced for the host firmware. This necessitates a
paths
declaration, which means that a repeat of all paths of the SDK and the host is necessary. I ended up with something like:Note the non-portable absolute paths, which could be substituted by
../
relative paths and mandating a parent directory layout.Tricks
extends
runtsc --noEmit --showConfig -p .
"listFiles": true
to the compilerOptions and runtsc --noEmit
"traceResolution": true
to compilerOptions"include": "./**/*.d.ts"
to the Moddable SDK's tsconfig. This works because all the files include adeclare module
statement which puts the declarations in the right place as "ambient modules", so even the ECMA-419 names with colons work. But this breaks down as soon as your app/mod has its own"include"
since that overrides the SDK's.Beta Was this translation helpful? Give feedback.
All reactions