Friday, July 27, 2018

Do Things Right with TypeScript

A collection of pointers for the present and future.

Print the whole error

`tsc --noErrorTruncation`

Why tsconfig.json is hard

tsconfig.json is important, because the TS compiler does way more, way more flexibly, than the Java compiler does. It's both a transpiler and a typechecker.

What kind of JS do you want outputted? Choose your level of ECMAScript compatibility (as ancient as ES3 or as modern as ESnext) and also your module system compatibility (commonjs, amd, or several more).

What will be magically be available in your runtime? Bring in the type declarations for these things (such as the DOM) with the `"lib": ["DOM"]` compiler option, or in `"types": ["@types/node"]` (node module globals like `__filename`, or node built-ins like `fs`).

Also choose how stringent the typechecking is, with "strict" and its various suboptions.

Choose where your input files are, and where your output files go.

Choose what to output: only JS? sourcemaps? type declarations? type declaration maps?  ... and for those maps, choose relative paths to the source.

The good news is: even if compilation has errors, tsc will output JS. So you can test even when tricky compile errors that you can't figure out plague you.

Iterate through objects and arrays

There exists both `for (const a of array)` and a similar construct which shall not be named but contains the work `in` instead of `of`. Do not use that one.

To iterate through an array: for (const a of array) { ... }

... ok I can't stand it anymore I'm moving this post to Medium. Google clearly does not care about this platform, it may go away like Google Reader, and it is super painful to put code here.

Wednesday, July 25, 2018

Do Things Right with npm install

Lately I've been wrestling with npm. Here are some rules I've learned:

Use `npm ci` rather than `npm install`

`npm ci` will bring down exactly the dependencies specified in package-lock.json. `npm install` does more than that; it also tries to update some libraries to a more recent version. Sometimes it updates URLs or nonsense in package.json so that it my `git status` is dirty. Sometimes it does deduping. Sometimes it sticks the version you have lying around. I haven't figured it out. It seems to be pretty dependent on the current circumstances on my file system.

Now I only use `npm install` if I specifically want to change the dependencies in my filesystem.

Use `npm install --save-exact`

Especially for snapshots. Semver does not work for snapshots or branches or anything but releases. And npm only works with semver. If you are not using a release; if you publish with build tags or branch tags or anything like that; do not give npm any sort of flexibility. It will not work. Specify a precise version or else it will give you nasty surprises, like deciding some alphabetically-later branch is better than the master-branch version you specified.

Use `npm view` to check the status of a library

This is quite useful. Try `npm view <lib-name>` and it brings to your command line the info you can get from the npm website. You can ask it for specific fields. To get the latest version of chalk:

$ npm view chalk dist-tags.latest

If you want to do anything programmatic with this info, the "do things right" flag for `npm view` is `--json`.

Try `npm ls` but then dig around on the filesystem

Exploring the dependency tree, `npm ls` is really cool; it shows it to you. You can see where you're getting a specific library with `npm ls <lib-name>` except that it doesn't always work. In the end, I dig around in my node_modules directory, using `find -name <lib-name> .` to look for the real thing.

Other times I use my little node-dependency dungeon explorer game to see what version of stuff is where. 

These are just a few of the nasty surprises I've found moving from Java to TypeScript, from maven dependencies to npm. Dependency management is an unsolved problem, and the people working on npm have made huge improvements in the last few years. I look forward to more.