9 ms·
Starting a TypeScript Project in 2021
- nikivi 5y agoNice article, you could also just use https://github.com/formium/tsdx https://github.com/formium/tsdx
- metachris 5y agoAuthor of the post here. Thanks for the link; added it to the post in the "Notes" section.
- dagurp 5y agonpx create-react-app my-app --template typescript is also an option
- vohvae 5y agoI just tried out tsdx. The node_modules folder took ~180MB of space in a fresh project. I don't know if I am doing or judging things wrong, but this seems to be way too much if someone just wants to write some hobby project exploratory code. I am probably not the target demographic for tsdx or other bootstrap libraries in the ecosystem but I would love to have something "simple" with good defaults which I can debug if something breaks to make CLI scripts to familiarise myself with the language and ecosystem. Currently the best option for me is to manually setup the directory structure and build commands which is not fun for mostly simple throwaway code. golang and rust seem to have things right in this regard though rust build artifacts can get quite big.
- rossng 5y agoI looked at TSDX for a project and was rather put off by the fact that: * It hasn't been updated for six months * It doesn't appear to support TypeScript 4 properly[1] [1] https://github.com/formium/tsdx/issues/926 https://github.com/formium/tsdx/issues/926
- imjared 5y agoI just launched a React Component library from start => finish last week using TSDX and typescript 4.2.3. I was similarly concerned about the update cycle but have been trying to get over the mental hurdle that few updates = bad project. Few updates could simply mean that the baseline functionality is good enough and that was exactly the case for me and my team last week. Obviously, YMMV but just wanted to give a +1 to a tool that made my life a little bit easier recently!
- evv 5y agoI think the creator of TSDX has shifted focus to turborepo.com
- chatmasta 5y agoIf you are intending to make a relatively isolated library, in its own repo, that you publish to npm, tsdx might be a good starting point. In my case, that was not my requirement, and I started with tsdx and regretted it. It's way too much for an early project -- you should really add these things as you find out that you need them. In my case the main issue was I was using it in a monorepo and having duplicated tooling and watch scripts in each library was not great for memory usage nor build times nor hot reload times. (In fact, even by itself, tsdx had some really bad build times compared to compiling the code as part of a Next.js build). In terms of monorepo, FWIW I'm now using .tsconfig project references [0], Yarn Berry workspaces, next.js externalDir experimental flag, judicious usage of `extends:`, and a shared package with common development scripts. I'm fairly happy with the setup now, but it was a huge PITA to get there, and a lot of the features only became available in the last year. But I'm relieved to be relying on officially supported TypeScript features, operating under the assumption that the TS team is incentivized to keep improving build times for this use case (which, in fact, they use in their own repo). I've also been eyeing Rush [1] for monorepo management but haven't pulled the trigger yet. I think they are making all the right decisions. The real challenge with a monorepo, and one I haven't fully solved yet, is balancing the tradeoffs of "passive compilation" (importing from the source of sibling packages) vs. bundling each package separately. As a small team, passive compilation is somewhat okay, and tsconfig project references kind of enforce boundaries, but on a larger team it could become problematic. On the other hand, bundling each package separately is not a great dev experience when each bundler is eating 1gb of RAM and running its own hot reload process. [0] https://www.typescriptlang.org/docs/handbook/project-references.html https://www.typescriptlang.org/docs/handbook/project-referen... [1] https://rushstack.io/ https://rushstack.io/
- latchkey 5y agoI'm a pretty unhappy user of tsdx. While it kind of gets the job done, they've broken my project several times with upgrades. As also noted, the project has stalled. If I was doing another project, I'd avoid it if possible.
- hardwaresofton 5y agoI really recommend getting comfortable with make -- if you know just enough to be dangerous (PHONY targets, regular targets, ifeq, ?=), it can be an incredibly useful tool, and unify control/operations across projects. The complexity/required reading that comes with integrating ~5+ individual tools and libraries you have to be aware of across one language can be made a lot easier by using make to do the plumbing between these tools. Often I find that I need to do some of the following: - do just a tiny bit of pre-processing - use two disparate tools which might interact/have an ordering requirement - alias a simple command for a repetitive task And it's the case that: - The tools/libraries I'm using don't have the functionality built in - I'm not excited about writing a bash script - A <programming language> script/build-hook feels too heavy I find that Makefiles are a really good way to boil down and standardize my builds across projects. Here's a chunk from a somewhat recent project: psql: export DB_CONTAINER_NAME=$(shell $(KUBECTL) get pods -n $(K8S_NAMESPACE) -l component=db -o=name | head -n 1) psql: $(KUBECTL) exec -it $(DB_CONTAINER_NAME) -n $(K8S_NAMESPACE) psql -- --user $(DB_USER) And another that's a bit less trendy: image: check-tool-docker $(DOCKER) build \ -f infra/docker/Dockerfile \ -t ${IMAGE_FULL_NAME_SHA} \ . image-publish: check-tool-docker $(DOCKER) push ${IMAGE_FULL_NAME_SHA} image-release: $(DOCKER) tag $(IMAGE_FULL_NAME_SHA) $(IMAGE_FULL_NAME) $(DOCKER) push $(IMAGE_FULL_NAME) And earlier in the file is the actual language-specific stuff: lint: check-tool-yarn $(YARN) lint Yeah, all I'm doing is just calling through to yarn here but the nice thing is that `lint` is a pretty common target from project to project, so most places `make lint` will do what I think it is going to do. And if you're wondering what the check-tool-<x> targets are like: check-tool-yarn: ifeq (,$(shell which $(YARN))) $(error "yarn not installed (see https://yarnpkg.com)") endif I will warn that there are people with Makefile PTSD, but I am finding a lot of value from it these days, would encourage people to take a look. If you're really ready for some fun check out recursive make -- managing and orchestrating subprojects is really really easy (and you don't have to care what the sub project is written in at the top level).
- KajMagnus 5y agoHow do you pass arguments to your Make targets? Let's say you'd like to set `DB_USER` to "my_name", then, do you: make psql user=my_name # ? To me, having to type `user=` is very annoying, I want to do just `make psql my_name`. Agreed that Make is nice :- ) My Makefile is not as nice as Make though o.O > I'm not excited about writing a bash script Bash scripts almost could be illegal :- ) I'm thinking about writing scripts in Deno in the future, instead
- mark_and_sweep 5y agoIn 2021, I think it's safe to start a TypeScript project with Deno.
- christiansakai 5y agoDoes Deno work for frontend?
- halfmatthalfcat 5y agoNo it's a replacement for Node.
- andrew_ 5y agoPlease stop spreading this misnomer. It's an alternative platform. It's absolutely not a wholesale replacement, and its inner workings are vastly different to Node. Edit: Well, someone touched a nerve! Doubt me, downvoters? You need but google to find a wealth of information to support the statement. https://www.imaginarycloud.com/blog/deno-vs-node/ https://www.imaginarycloud.com/blog/deno-vs-node/ is the first result, and there are a litany of other articles explaining the same.
- wa1987 5y ago> Please stop spreading this misnomer. That's a fairly… direct way of putting it :-) Anyway: 1. What are the key differences in terms of usage and use cases? 2. Why isn't Deno a 'wholesale' replacement for Node? 3. In which respect are the vastly differently inner workings relevant in regards to usage of both products?
- andrew_ 5y agoI suspect the reply was snide, masked by a smiley face, but here ya go anyhow. First result on Google for "deno vs node" https://www.imaginarycloud.com/blog/deno-vs-node/#:~:text=What%20is%20Deno%3F,implementation%20is%20in%20C%2B%2B https://www.imaginarycloud.com/blog/deno-vs-node/#:~:text=Wh...) that covers the basics of all three asked points.
- meheleventyone 5y agoI’m curious about the value of eslint for TypeScript. I’ve not really found myself wanting from the coverage provided by tsc.
- halfmatthalfcat 5y agoTo be honest, I was really happy with TSLint. The amount of configuration and scaffolding around ESLint is a big turnoff from me compared to how easy it was to get TSLint going.
- WorldMaker 5y agoA lot of the most common TSLint "boxed" configurations have direct ESLint relatives at this point. For one opinionated example there is eslint-config-standard-with-typescript [1]. Using a prepared config like that is just as easy as using one built for TSLint. (It's an "extends" field that does most of the work.) Though I admit I've kind of moved more towards even more opinionated Prettier than ESLint lately. [1] https://www.npmjs.com/package/eslint-config-standard-with-typescript https://www.npmjs.com/package/eslint-config-standard-with-ty...
- city41 5y agoI use eslint for things like catching left behind debugger and console statements.
- andrew_ 5y agoThe larger the pool of engineers on a project (or the larger a team size) the more important consistent formatting becomes. It may not be relevant for individual projects (though I'd disagree with that as well), but it makes maintenance of projects under larger teams, including distributed teams, a heck of a lot easier.
- maga 5y agoprettier?
- madeofpalk 5y ago
- city41 5y agoCasting window to any in a pinch does work. But for longer term stuff, it's probably better to extend the Window interface.
- metachris 5y agoThanks, added a note to the post.
- andrew_ 5y agoAva (https://github.com/avajs/ava https://github.com/avajs/ava) gets too little love from the blogging machinery. It's a breeze to use with TS, faster than Jest (YMMV of course), and I love the snapshot output over any other snapshot producing unit test tool. Use with NYC for coverage is a breeze.
- metachris 5y agoAdded, thanks.
- exogen 5y agoAVA is great, I use it on a few projects and even developed a simple HTTP record/replay add-on for it. I'd say it's good for smaller projects. One huge benefit of Jest though is the built-in mocking, including module mocking. This stuff is BYO in AVA. Module mocks in particular can be quite annoying to set up, so it's really nice that Jest pulls them all together in one cohesive package.
- tobr 5y agoRelated: uvu[1] which I think is intended to be a barebones version of Ava. I like the idea of not having a big fragile graph of dependencies to be able to run some tests. Not sure if uvu is any good for Typescript though. 1: https://github.com/lukeed/uvu https://github.com/lukeed/uvu
- hardwaresofton 5y agoI've never moved past tape, have had ava on the list of things to look into for a very long time but seem to always just `yarn add -D tape bogota` (bogota is a library that runs tape in parallel), any real concrete reasons to use ava over tape? the ava guide says this: > Tape and tap are pretty good. AVA is highly inspired by their syntax. They too execute tests serially. Their default TAP output isn't very user-friendly though so you always end up using an external tap reporter. Nicer looking test output and serial execution seem to be the issues here, but I actually like the serial execution bit because it lets you write some messier tests (some that re-use a local test DB let's say) before you straighten up and write shared-nothing test-suites that can run in isolation (spin up a DB container/make a db-per-test-suite/etc).
- metachris 5y agoThis is the example repository: https://github.com/metachris/typescript-boilerplate https://github.com/metachris/typescript-boilerplate
- jherdman 5y agoTSLint is deprecated in favour of ESLint. See https://palantir.github.io/tslint/ https://palantir.github.io/tslint/.
- sod 5y agoWe should let linters written javascript die IMO. ESLint is soooo slow. My hope is that the ecosystem will slowly shift to deno, and we just gonna use `deno lint` (https://deno.land/manual/tools/linter https://deno.land/manual/tools/linter, based on swc, written in rust) for linting from then on. What tslint does in 6 seconds, `deno lint` does in 0.2 seconds.
- wereHamster 5y agoSame for build tools, esbuild is multiple orders of magnitude faster than babel.
- eliseumds 5y agoYes, but it does much less. There are still many projects out there relying on Babel plugins (Loadable Components, Styled Components, Tailwind, Apollo, etc). I love esbuild though, and use it a few of our packages, it flies
- twistedpair 5y agoHmm... a multi-threaded language would be nice. Always surprised when I see a single pegged core for eslint, prettier, or babel. Workers are coming to Node... so soon.
- tppiotrowski 5y agoesbuild sounds promising as one friction point was that the TS compiler would compile all your TS files into JS files but there was no way to bundle them together into one JS file you could include in your HTML and webpack takes a bit to setup. It looks like esbuild doesn’t have websocket auto-reload magic so will need to refresh the web browser to see the recompiled changes.
- vergessenmir 5y agoI have started looking at this for Svelte projects from a post yesterday on non-javascript build tools. Very promising indeed,
- lovelettr 5y ago> but there was no way to bundle them together into one JS file you could include in your HTML and webpack takes a bit to setup Maybe I am misunderstanding but this feels like it is provided via the `--bundle` flag in esbuild [1]. > It looks like esbuild doesn’t have websocket auto-reload magic so will need to refresh the web browser to see the recompiled changes. I have also noticed that it does not seem to have the auto-reload part [2]. It does however have a server so that is at least something (e.g., `--servedir=dist`). Though that seems like a very new development. [1] https://esbuild.github.io/getting-started/#your-first-bundle https://esbuild.github.io/getting-started/#your-first-bundle [2] https://github.com/evanw/esbuild/issues/802 https://github.com/evanw/esbuild/issues/802
- tppiotrowski 5y agoThanks. I meant that `tsc` has no `--bundle` flag
- WorldMaker 5y agoSnowpack is an option if you want a fancier auto-reload dev server oriented around ES Modules. It can use either esbuild or webpack under the covers, IIRC, for its bundling step when it comes time for that.
- austincheney 5y agoThat is a lot of boilerplate and reliance on external tooling that could probably be a single bash or PowerShell script. My preferred approach is to let thy primary modules be thy commands. That way everything is tidy, documented, and clear for your users. Example: // module commandName is a module to parse a command, exclusion list, and options apart from other arguments of process.argv import commandName from "./lib/terminal/utilities/commandName.js"; // module commandList is the list of modules that serve as commands for your application import commandList from "./lib/terminal/utilities/commandList.js"; // module command_documentation provides documentation to the terminal about your commands and each of their options import commands_documentation from "./lib/terminal/utilities/commands_documentation.js"; // module vars is a generic configuration store available across the application import vars from "./lib/terminal/utilities/vars.js"; (function terminal_init_execute():void { // command documentation vars.commands = commands_documentation; // supported command name vars.command = commandName() as commands; commandList[vars.command](); }()); What it looks like on the terminal: node myApplication myCommand
- TechBro8615 5y ago> probably be a single bash or PowerShell script The fact that it could be either bash or PowerShell is a primary reason why this tooling is there. Bash scripts work great (I use them) if everyone coding on the project shares an operating system. Not so much once you cross that boundary. To give a sense of the lengths the JS community goes to address these compatibility issues, consider that Yarn 2 actually implements its own shell for running `package.json` scripts in a cross-platform way.
- tompazourek 5y agoFYI PowerShell is pretty cross-platform these days. But I see having it all written in JS is still simpler.
- TechBro8615 5y agoI don't know about simpler :) My preference is to eliminate the OS discrepancy by making Docker images the building block of the stack in dev environments, CI pipelines, and production deployments. This means you pay a constant and predictable amount of operational complexity, but eliminate the entire class of constraints caused by cross-platform variability. Seems like a good deal, trading a variable cost for a constant one. Then you can use Bash! Or fish, or some hipster shell you found on lobste.rs. Just install it in the Docker image.
- revskill 5y agoI don't see the `node --watch bundle.ts` ? That's why most of boilerplate FAILED instead of just using Next.js. Hot reloading for both server and browser is what's important.
- 1_player 5y agoOne thing that is often mentioned in the Node community is "let's adopt the Unix Philosophy and have one tool do one thing and one thing only." And by being inflexible, this is one of the reasons there a bazillion tools and steps required just to have a basic project setup. They're not using the Unix tools anyway. It's not like they're using entr and make to watch and build, but let's reinvent the wheel and use nodemon and gulp/bower/webpack/esbuild/snowpack/...
- riskable 5y agoAt what point does the complexity outweigh the benefits? Just because someone wants to control a UI element to the nth pixel doesn't mean we should let them do that. At this point I'm thinking it might be less bandwidth, complexity, and easier to maintain to just present a web page as a giant imagemap. SVG, so it scales. With screen-ratio-based media queries rather than guessing DPI based on inaccurate factors like the number of pixels.
- sfvisser 5y agoGood luck building anything interactive this way.
- yakshaving_jgt 5y agoHow is an image map not interactive?
- mattwad 5y agoSeems pretty simple given it includes not only test setup and continuous integration, but also publishing to npm and documentation
- intergalplan 5y ago> At this point I'm thinking it might be less bandwidth, complexity, and easier to maintain to just present a web page as a giant imagemap. SVG, so it scales. SVG is XML, so you can do exactly that if you want to. Hook React up to it and go nuts. You can have the browser build a DOM tree out of it for you and use many of the same APIs you would on HTML, if you don't want to use React. Seriously, this is a thing you can actually do.
- mrweasel 5y agoThis is the best guides on how to get started with a modern JavaScript/TypeScript I’ve ever seen. Nice step by step, explaining what each tool does and how things work together. I’m still leaning towards just learning Elm and give up on the JavaScript ecosystem, but an article like this gives me a little hope that at least it seem realistic to get started with TypeScript.
- Xavdidtheshadow 5y agoI do this sort of thing often enough that I wrote a Yeoman generator to scaffold everything: https://github.com/xavdid/generator-xavdid https://github.com/xavdid/generator-xavdid Maybe overkill, but it's saved me from having to remember which recent project to reference to remember exactly how I like eslint set up, etc. Been a very smooth experience!
- joshghent 5y agoEver since watching Jonathan blows talk "Preventing the collapse of civilisation", I've been mulling over things like this. It feels like we have this defacto set of commands you have to run to start a new Node/Typescript project, without much understand of what it does. Then you get complier or lint errors and then spend ages googling around for the answer that tells you to change a specific flag. This isn't a complete thought but I hope someone knows what I'm getting at.
- vagrantJin 5y agoIn other words, the tooling and setup have become more complicated than the pieces of code we are writing? I feel like that sometimes. Not all bad though. I've learned that being spartan with your approach not only frees the mind of clutter but your stack wont be delicate shitshow of obscure tools 3-4 years down the line.
- xyzzy_plugh 5y agoI recently was trying to diagnose a bug with React state in someone else's project. Everything I found said "install the React extension". Okay but this thing boils down to just JavaScript right? I ultimately failed to find out how to inspect anything meaningful without the extension -- it's almost as if nobody knows how React works. The abstraction is bananas. Sure, JavaScript sucks but is this better? I swore off massive impenetrable abstractions like React eons ago and I'm saner for it. Abstractions are supposed to remove complexity, not treat users like morons.
- nicoburns 5y agoWhen you're trying to debug a JavaScript error do you use Chrome's built in JavaScript debugger, or do run Chrome in GDB? Or perhaps you get out your oscilloscope and try attaching it to your CPU? Debugging at multiple levels of abstraction is nothing new. The fact that there are debugging tools at the React level does reduce complexity. It means you don't need to understand the details of how React is implemented. You can just think in terms of React concepts (which are quite straightforward and have excellent documentation).
- NikhilVerma 5y agoVery much appreciate boilerplate tools, they often come with sane defaults and avoid configuration hell when you just want to get started. I just wish there was some easy way to version them, so you can migrate from an older boilerplate to a new one. I quite like how React Native does it. They have git diffs of a created project for each released version. So if you want to migrate from version A to B you just see the diff and apply those changes yourself. Not ideal but it really helps when you want a good mix of configurability while avoiding incompatible divergence.
- fiddlerwoaroof 5y agoI’d recommend just trying to set up a webpack 5 build from scratch: I’ve done it twice recently, and it’s been a pleasant surprise how much easier it was than it was four years ago. Also, parcel Just Works for a lot of problems.
- mikojan 5y ago...or (since it's 2021) you could just use snowpack and call it a day.
- BiteCode_dev 5y agoIf you haven't already, give a try to ViteJS. It's from the author of Vue, and support both Vue and React, including JSX and TS. It has the qualities of Vue: - it works out of the box - setup and usage are super easy - it's wicked fast - documentation rocks I talked about it to one of my client 3 days ago. They tried it 5 minutes and decided to spend a day migrated their project immediately. It's that good. And the migration took only 2 hours.
- skeletonjelly 5y agoSeconding this! Went from npm/vue2/ts to npx/vite/vue3/ts and it's so much better.
- seniorsassycat 5y agoI recommend adding `--transpile-only` to `ts-node` in npm scripts and any interactive workflows. If you have type checking in your editor or tsc --watch in a terminal you don't need to block unit tests or iterative development while ts-node runs type checks.
- naiyt 5y agoI disagree, I don't want my project to successfully build at all if I have type errors.
- seniorsassycat 5y agoI block commit, push, and release workflows by lint, type errors, and test, but I don't block running tests or running my program.
- lenkite 5y agoAs someone who has returned to webdev after a few years, I find deno to be far easier to setup and get started than all the mega-complex node stuff.
- wwweston 5y ago> cargo install deno ... Compiling swc_ecma_transforms v0.45.3 error[E0004]: non-exhaustive patterns: `MaxFilesWatch` not covered --> /Users/weston/.cargo/registry/src/github.com-1ecc6299db9ec823/deno_runtime-0.11.0/errors.rs:75:9 | 75 | match error.kind { | ^^^^^^^^^^ pattern `MaxFilesWatch` not covered
- lenkite 5y agoAdmittedly as someone who doesn't code Rust, I have never tried to use cargo to install deno. On macOS I use brew. brew install deno # works with no issues and much faster Though, at the bottom of https://deno.land/#installation https://deno.land/#installation, one sees the incantation: cargo install deno --locked I removed brew's deno, installed rust (via brew) and then tried this. No compile errors. And swc_ecma_transforms compiled successfully. ... Compiling swc_ecma_transforms_proposal v0.13.1 Compiling swc_ecma_transforms_optimization v0.15.3 Compiling swc_ecma_transforms_typescript v0.14.1 Compiling swc_ecma_transforms_react v0.14.1 Compiling swc_ecma_transforms v0.45.1 Compiling gfx-auxil v0.8.0 ... Installing /Users/i034796/.cargo/bin/deno Installing /Users/i034796/.cargo/bin/denort Installed package `deno v1.9.0` (executables `deno`, `denort`)
- wwweston 5y agobrew is nice. I have a rule for myself, though, that if I'm picking up something I'm likely to deploy on an environment that's not my mac, I don't use brew to install it. That can make some things harder up front, but I have my eyes open from the start and get fewer surprises between beta and deployment. On the other hand, having added `--locked` to the cargo invocation, it works for me now too, so apparently (a) I should look into what that means and (b) I should consider using brew for hints even in situations where I don't intend to rely on it. Thanks! (On the other other hand, even finding the way through this issue reinforces the point about a certain complexity/opacity to tooling that's supposed to make things easier.)
- nsonha 5y ago> Obviously, it is a wrong step but your preconceived biases are so strong using absolute language to accuse people of lack of benefit of doubt
- kevsim 5y agoThis is pretty decent advice. I'd also suggest that prettier should be in your setup in 2021. Let's stop fighting about formatting once and for all.
- haolez 5y agoI'm much more interested in ReScript[0] than TypeScript, but I guess that TypeScript is much more appealing to C# programmers and much more supported as a whole. Anyone here has some experience with ReScript (or ReasonML, for what it matters) to share with the rest of us? [0] https://rescript-lang.org/ https://rescript-lang.org/
- hermanradtke 5y agoIt has been a while, but BuckleScript is the pain point. TypeScript is much easier to use within the existing JS ecosystem.
- chrysoprace 5y agoFor me, the consistency with JavaScript's existing syntax is a great advantage of TypeScript. TypeScript's "allowJs" flag also makes it easier to convert an existing codebase. ReScript seems to have come a long way since I last looked at it (it was just called ReasonML at the time I think), so it'd be worth looking into.