[HN Gopher] Insights from Adopting TypeScript at Scale ___________________________________________________________________ Insights from Adopting TypeScript at Scale Author : robpalmer Score : 102 points Date : 2020-11-10 07:25 UTC (1 days ago) (HTM) web link (www.techatbloomberg.com) (TXT) w3m dump (www.techatbloomberg.com) | coding123 wrote: | I've seen some shops do things like this. Making their own tools | to get around odd shitshows they've gotten themselves into. I | suspect that there are a number of people within the org that | aren't fans of Webpack or some other set of tools that would have | made some of their decisions end up with the consequences in the | article. They didn't quite state it but I suspect they're trying | to use a specific stack instead of a more obvious stack to make | typescript work. | | edit: just adding though, that this isn't surprising with a dev | base of 2000 js developers. | robpalmer wrote: | It's more about setting up the guard-rails ahead-of-time to | avoid falling into a hole, rather than getting out of one. We | know the way to do this is to stick to standards like | ECMAScript. | | ES Modules are the glue that binds the whole JS ecosystem | together. Whilst ESM is the standard, today a lot of people are | using ESM only as an authoring format that later gets converted | to CommonJS before being published or executed. Many of today's | tools rely on this, meaning the ecosystem is partially tied to | CommonJS. Migration is happening but it's slow and non-trivial. | | In a way, we bypassed the CommonJS era and skipped directly | from AMD to ESM. AMD and ESM are pretty much isomorphic and | differ only in syntax. You just run a codemod to get from AMD | syntax to ESM syntax - semantics are preserved. Whereas the | step from CommonJS to ESM does not fully preserve semantics. | CommonJS module initializers are always synchronous. ESM can be | asynchronous - you can use `await` in the module initializer. | | The article covers a few of the things we've done to retain a | very standard ES Module system that is ECMAScript compliant. I | think it is this pursuit of standards and desire for robust | interoperable packages that led to some of the surprising | discoveries. | kristaps wrote: | The article mentions they have around 2000 engineers, at that | scale investing in custom tooling can easily become a | significant net gain in productivity and stability, especially | when dealing with the JS ecosystem. | robpalmer wrote: | Agreed. The article touches on this. When you have hundreds | of projects that all target the same tightly-managed | evergreen runtime, there's not much justification for having | each project select and maintain a different toolchain. It | just leads to the same problems being solved over again, and | makes it harder for developers to switch between projects. | | The fact that we can consider high-quality sourcemaps a | solved problem (during both debugging and consolidated crash | telemetry) really helps developers focus on building | functionality rather than debugging a build system. | | I think most large companies have dedicated tooling teams for | these kinds of reasons. A related viewpoint in a related | thread: https://www.reddit.com/r/typescript/comments/jrgi8z/1 | 0_insig... | JonathonW wrote: | I think the key here is: | | > Back in 2005, the company started migrating those apps from | Fortran and C/C++ to server-side JavaScript | | Since their use of Javascript predates Node (and the rest of | that ecosystem, like Webpack or Babel or whatever), they've | built up their own Javascript environment that doesn't rely on | Node or Node conventions at all. Not so much a "get around odd | shitshows" situation as much as a parallel evolution. | robpalmer wrote: | Yes - you deduced correctly! | | There was a long period of parallel evolution. Over the last | few years we've been able to get back on the standards track. | The article describes this as one of the guiding principles. | It's why we participate in TC39. | | Nowadays our tooling stack now uses TypeScript, Babel, Rollup | & Terser which I regard as the most mainstream of choices. | And we go out of our way to keep things aligned with | ECMAScript, e.g. preventing the use of | "experimentalDecorators". | jgalt212 wrote: | Bloomberg often gets accused of "not invented here" | syndrome. But often times in the past, it's been the case | that what they need hasn't been invented yet. | Chris_Newton wrote: | Interesting how much emphasis they seem to place on treating TS | as precisely JS + types and nothing more, even to the extent of | excluding evolutionary TS features. | | That does seem a reasonable argument for avoiding enum types in | TS. Those have semantics that go beyond how enumerations work in | most languages and implementing them in the underlying JS is | going to introduce some runtime cost. | | I wonder whether their coding standards still permit _const_ | enums, though, as they are also new relative to JS but work more | like traditional enumerations in C-family languages. These ought | to be entirely compiled away, so it seems like the same arguments | around efficiency and portability /compatibility wouldn't apply. | robpalmer wrote: | There isn't much of a difference between regular `enum` and | const `enum` when it comes to the usage of the `enum` keyword. | The big difference is what they compile to - where const `enum` | evaporates by inlining the values into the usage sites. | | `enum` is a keyword that is reserved in ECMAScript and | therefore may one day clash with TypeScript. It's unlikely any | ECMAScript-defined semantics for enum would match today's | TypeScript `enum`. So it's not on any standards track. | | There is already a proposal for JS `enum` that has different | semantics to TS `enum`, and it was created by someone on the | TypeScript team: https://github.com/rbuckton/proposal-enum | | So the const form doesn't really change the hazard. | mgdev wrote: | I thought Bloomberg was into Bucklescript/ReasonML. Warring | factions?! | Scarbutt wrote: | Can't beat better ecosystem, better integration with the | ecosystem and let other company(Microsoft) do the work for you. | robpalmer wrote: | The TypeScript ecosystem is amazing - partly because of the | large number of users also also because of the sense of | community. It is run as a true OSS project. Roadmaps are | release plans are all public on GitHub. Even as outsiders | we've been able to contribute significant features, e.g. | Private Fields in TypeScript 3.8. | | https://devblogs.microsoft.com/typescript/announcing- | typescr... | agustif wrote: | Yeah TypeScript it's the only thing that makes me | hate/doubt M$ a little less... | robpalmer wrote: | What about VS Code? | mistersys wrote: | TypeScript was in the right place at the right time, and | the team prioritized the right features in the beginning, | allowing for the great adoption. | | But I'd still place TypeScript firmly in the "worse is | better" category (products that are technically inferior | then the state of the art, but succeed due to | circumstance), it's a band aid on top of a the broken JS | ecosystem. Its ad-hoc, Hodge-Podge type system and poor | meta-programming is sad to see for such a popular | language. | | I'd rather write TypeScript then JS, but as soon as | there's an opportunity to write software that works | across all platforms without dealing with JS, and with a | type system that's actually built on a solid foundation, | I'm taking it. | vamega wrote: | The bucklescript author now works for Facebook. | lemming wrote: | What is the proportion of JS libraries in the wild which provide | TS type declaration files, either via DefinitelyTyped or provided | by the lib itself? Is it normal to have to write your own | declarations, or do most libs provide them these days? | a_humean wrote: | Its actually quite rare to see a library without either first | or third party support these days. Many new libraries are | either written in typescript, or the authors have taken care to | create declaration files or contribute to definately-typed. If | a library reaches any degree of popularity it usually isn't | long before a third party declaration appears. | | Older libraries that are long abandoned by their maintainers | usually don't have anything. At work we pretty much ignore all | libraries that don't have types from somewhere these days, but | that doesn't eliminate many things. | horsawlarway wrote: | I agree on ignoring libraries without definitions. | | Having to write the definitions myself usually isn't a huge | pain, but it's a big red flag showing that it's probably | abandoned, and there's no community support around it anymore | (or possibly ever). | cutler wrote: | As an outsider I'm puzzled how any TS library repo keeps up | with the pace of change in TS. With JS you can more or less | write it once. | robpalmer wrote: | Whilst TS does technically contain breaks, these are normally | simple increases in the power of the type-checking. It's | finding more errors in code that previous seemed fine. Think | of it like adding more ESlint rules. | | It's rare for there to be a breaking change in the JS emit. | | The TypeScript team work hard to preserve compatibility. | Breaking changes are explicitly managed and communicated | ahead of time. There is a concept of a breakage-budget per- | release. This means if you stay up to date, the cost of each | upgrade should not be huge. Orta and Nathan on the TypeScript | team talk about this in this podcast episode: | https://dev.to/devteam/devnews-s1e4-typescript-4-0-gitee- | chr... | | So "keeping up" is not too hard. | lemming wrote: | Do the breaks tend to affect the TS declaration files, or | are they more to the language itself? | robpalmer wrote: | The majority of breaks are due to the checker getting | better. So code that passed now errors. Most of the time | pre-existing published DTS files still operate fine. | geewee wrote: | Almost all of them provide them, although sometimes they are | slightly out of date. I think I've had to write my own | declaration files (or type a library as any) for one or two | libraries in years | darksaints wrote: | Oh wow they went from C/C++ to JavaScript? That's just trading | one dangerous footgun for another. Glad to see they finally found | a better tool. I can't function in JavaScript without | Typescript...I constantly have to be looking up docs cause I | don't have intellisense, and once something works I'm terrified | to ever touch it again. Typescript made front end development | reasonable again...not perfect, but not so pathetically bad that | I want to rage quit like I did before. | sjroot wrote: | C++ is still very much used, along with Python. These languages | are generally used for the overwhelming majority of our backend | services. | | JS/TS are used in the Terminal's view layer. You _can_ make | services in these languages as well, AFAIK, but I don 't think | it is very common. | dboreham wrote: | Fashion. | Roboprog wrote: | That seems to be pretty common statement about JavaScript, but | strangely not one I share. | | I have been programming since the early 80s, and my experience | with JS has been pretty positive, especially compared to the | slog through the unreadable mud that is enterprise Java. (If I | was going to rage quit on something, it would be the verbose, | obtuse, repetitive Java sludge I've had to read the last decade | and a half) | | Typescript solves problems I don't have. The Jetbrains IDEs do | autocomplete just fine on vanilla JS, and the documentation | window automatically shows the initialization and any JSDoc for | most every symbol the editor cursor touches. I avoid writing | code with thousands of global symbols. | | OOP languages like Object Pascal and C++ are good for making | lemonade from the lemon of manual memory management, but if you | have efficient garbage collection, use functional programming | techniques rather than OOP bloat, and many self inflicted | problems go away. | | I hope TS doesn't turn JS into Enterprise Java, The Next | Generation. | | Nothing personal, most people seem to prefer that style. Just | understand, there is a reason some people run away from the C++ | / Java / C# / TS milieu. | nicoburns wrote: | Have you used TS much? In my experience idiomatic TS isn't | much different to idiomatic JS and a far cry from Java style | OOP code (the Angular ecosystem which was admitedly an early | adopter of TS is an exception and best avoided). | kingdomcome50 wrote: | > I hope TS doesn't turn JS into Enterprise Java, The Next | Generation. | | No chance. And frankly, I don't get the comparison you are | making to C++/Java/C#. TS is fundamentally different than | those languages. From structural typing to a default | functional/imperative paradigm, it really is just JS with | better static analysis. | | Your IDE is _not_ as good for JS as it would be for TS. The | entire impetus for TS is /was to provide better | tooling/ergonomics around JS. Whether or not you _need_ | better tooling is a subjective matter. | IshKebab wrote: | > The Jetbrains IDEs do autocomplete just fine on vanilla JS | | I find that hard to believe because it's not a solvable | problem without type annotations. | mirekrusin wrote: | "9. Generated declarations can inline types from dependencies" | | Why do they generate .d.ts files instead of publishing .ts files | alongside .js files? This should solve inlining issue, no? | robpalmer wrote: | That's an excellent suggestion! | | It's true you could just have every package publish the raw | TypeScript source-code. So that when an app imports a library, | it type-checks against the original source code of the library. | No need for DTS files from your dependencies! | | I have never seen this done in practice for a large system. | It's not as scalable as using bare-minimum type declarations | that you find in DTS files. It requires more parsing, and | potentially more time to accumulate the types. Whereas DTS emit | in TypeScript can flatten the resulting type into the DTS file. | | But if performance didn't matter, I think this would probably | work. And it would eliminate the class of bugs where the | generated DTS files are not 100% semantically identical to the | original source code. That's another edge-case finding I | omitted from the document but hope to write up another day. | mirekrusin wrote: | It works quite well, you can forget about src/ lib/ | directories, just structure package as you want (ie files at | the root), generate js files along ts in the same directory | (relative paths to assets stay the same, import paths are the | same in js/ts, very useful), add in vscode rule to auto hide | .js file if .ts with the same name exists | `{"files.exclude":{" __/ *.js":{"when":"$(basename).ts"}}}` - | coding is pleasure, you just see and work with ts, no need to | generate js files most of the time (on prepublish yes) etc. ___________________________________________________________________ (page generated 2020-11-11 23:01 UTC)