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
Uh oh!
There was an error while loading. Please reload this page.
-
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.jsons that work and properly type check typescript codetsconfig.jsonfor use in an editor (e.g. vscode) that properly type checks (and suggests) codetsconfig.jsonfor 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 necessitatepathsdeclarations 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
extendsfeature such that the firmware'stsconfig.jsoncan include the Moddable SDK'stsconfig.jsonand thereby pick-up a lot defined there, except that stuff defined in the firmware tsconfig replaces the included parts. This is particularly annoying forpathsbecause the Moddable SDK can have a nicely craftedpathsclause but as soon as the firmware's tsconfig also has apathsclause the SDK's one is effectively lost.When writing a host app and mods in typescript one has to refer to the
.tsfiles when building the host (so the code gets built into the firmware) but one has to refer to corresponding.d.tsfiles when building the mod otherwise the module gets loaded twice. E.g., suppose the host has a moduleutilinutil.tsthen the hosts' firmware needs to include that file but if a mod also want to use the utils it should refer to autil.d.tsso 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.jsonlocated 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
.tsin the subtree being included.)But as soon as the application needs a
pathsdeclaration it has to repeat the SDK's paths and has to use absolute paths for that. For example, my app defines anembedded:network/somethingmodule:Now mods are not obvious at all. First I tackled the compilation. For this, we need
.d.tsfiles 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.tsfiles). For typescript modules in the application one can ask the typescript compiler to produce.d.tsfiles 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
pathsin 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 theHOSTenvironment variable to be set appropriately:{ "include": ["$(MODDABLE)/examples/manifest_mod.json", "$(HOST)/manifest_host.json"], "modules": { "*": ["./*.ts"], } }In my case the paths in
manifest_host.jsonundergo a bunch of transformations to replace leading path components by$(MODDABLE)or$(HOST)and to deal with some cases where the.d.tsfile doesn't end up where it's needed. I also had to edit some of the generated.d.tsfiles to remove a/// referenceline.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
pathsdeclaration, 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
extendsruntsc --noEmit --showConfig -p ."listFiles": trueto the compilerOptions and runtsc --noEmit"traceResolution": trueto compilerOptions"include": "./**/*.d.ts"to the Moddable SDK's tsconfig. This works because all the files include adeclare modulestatement 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