Typescript: Target compiler flag should allow me to choose a Node.js version

Created on 2 Mar 2018  ·  17Comments  ·  Source: microsoft/TypeScript

Greetings folks! Little feature request. Today when I specify the compilation target, I choose an es level (2015, 2016, 2017, Next, etc). I primarily use TypeScript for Node.js apps, and what I'd really love is a way to target specific releases of node.js. Something like:

"target":  "node8"

This would take a lot of the guesswork out if I know my min-nodejs version, and I don't care about targeting the browser.

Declined

Most helpful comment

I started a doc page for this, https://github.com/Microsoft/TypeScript-wiki/pull/182 👍

All 17 comments

+1. Note that language levels don't precisely map to Node (or even browser) versions at all times. Node 6 has most everything, but not all, of ES2015. Node 7 and 8 have async-await but not all the rest of ES2017.

As a Node.js library developer I want to make sure that the code I am shipping matches the minimum Node.js version that I support. Any extra polyfills add debugging, cognitive and performance overhead.

Note that this issue isn't asking to allow users to pick and chose which language features to enable (which has been discussed in the past on this issue tracker). It is asking for target to support implementation levels rather the specification levels. The former is what people can actually target.

People have also asked for this for browser runtimes. We really don't have the resources to keep active tabs on every JS runtime's per-version progress. It's generally not problematic to over-downlevel syntactic features and non-syntactic features can be safely polyfilled through other means.

@RyanCavanaugh Node semver major versions are released twice a year, so I think the resource requirement would be quite low.

If that is still too much work, would you entertain external contribution and ownership of such a table for Node.js?

If you want to have a wiki page for "Recommended target and lib settings by Node version", sure, send a PR 👍

That wouldn't solve the problem at hand. Recommended target version for Node 8 would be ES6 which means that we don't get native async-await support. Debugging poly-filled async-await doesn't have the same user experience as native. So while it is not problematic functionally, it is problematic from a user experience point of view.

Your original push-back was lack of resources to maintain the table. I've offered to help maintain the table. Could you elaborate on where the remainder of your push back is coming from?

Your original push-back was lack of resources to maintain the table. I've offered to help maintain the table. Could you elaborate on where the remainder of your push back is coming from?

Hey @ofrobots, that is generous of you, and we appreciate the offer, but that work still needs to be overseen and verified by the team, and is still a non-zero cost on our side.

Additionally, the work here unfortunately isn't a matter of "just figure out which transforms to disable/enable" because our transforms typically downlevel an entire version of ECMAScript at a time (barring generators and module systems). This helps us not just by affording some flexibility in our implementation, but also helps speed certain things up (fewer individual passes). So there's also the current level of granularity we're willing explore within our emit pipeline.

@DanielRosenwasser Thanks for explaining. I guess the longer feedback in that case would be to consider that you're making a trade-off between 'flexibility of implementation' and 'out of the box user experience', specially for Node.js users. It is a fine to make the choice you're making, but it is important to recognize the trade-off.

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

Oh Hey all... is this something that could be revisited?

@MylesBorins no decision is ever permanently final, but I don't see any new data or use cases that would change our original thinking here

Is there any wiki for "Recommended target and lib settings by Node version"?

Is there any wiki for "Recommended target and lib settings by Node version"?

No, but we would be happy to host one if someone wants to contribute such doc.

I started a doc page for this, https://github.com/Microsoft/TypeScript-wiki/pull/182 👍

what about using browserlist? it supports node 10 or maintianed node versions queries
https://github.com/browserslist/browserslist#full-list

It may not work for everyone's use case, but now that @babel/preset-typescript is available, this functionality can be achieved using babel with @babel/preset-typescript and @babel/preset-env. Keep in mind that with this approach you still want to use tsc to do type checking, maybe with tsc -d --emitDeclarationOnly so that only declaration files are output (since babel will produce the .js).

This is a pretty good article discussing the marriage of these presets - https://iamturns.com/typescript-babel/

That solution, while possible, brings another set of tools (Babel) into the equation. For my projects I don't this much extra complexity. It would be nice if tsc had better built-in support for Node.js users.

Like I prefaced,

It may not work for everyone's use case

Regarding "this much extra complexity", the only change is

file babel.config.js

const TARGET_NODE_VERSION = '8.10'

module.exports = function(api) {
    return {
        presets: [
            [
                '@babel/typescript',
                '@babel/preset-env',
                { targets: { node: TARGET_NODE_VERSION } },
            ],
        ],
        plugins: [
            '@babel/proposal-class-properties',
            '@babel/plugin-proposal-object-rest-spread',
        ],
    }
}

Run

$ babel <src dir> --extensions ts && tsc -d --emitDeclarationOnly

Which seems pretty marginal ¯_(ツ)_/¯

Microsoft also provides a starter kit to help - https://github.com/Microsoft/TypeScript-Babel-Starter

Was this page helpful?
0 / 5 - 0 ratings