Settings

Theme

Starting a TypeScript Project in 2021

metachris.com

228 points by majodev 5 years ago · 189 comments

Reader

andrew_ 5 years ago

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.

  • tobr 5 years ago

    Related: 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

  • cakoose 5 years ago

    I actually started with Ava for a new project because it did a few things better than Jest. But ended up switching away because of this issue: https://github.com/avajs/ava/issues/2385

    Basically, if an assertion fails in the middle of an individual test, most test runners stop executing that test. Ava (by design) continues on with the rest of that test. This makes it harder to debug issues.

    (This not be a problem for everyone. I'm only mentioning it because it was a deal-breaker for me and wish I knew that going in.)

  • hardwaresofton 5 years ago

    I'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).

  • tegiddrone 5 years ago

    Came here to mention how slow and sometimes awkward ts-jest is. I'll have to try out Ava and the others. I think jest is a great asset over mocha/jasmine/sinon/chai but it gets awkward in the typescript realm. Also thinking about how since it really isn't type aware (especially for mocks) that it loses some points compared to the ecosystems like mockito, nsubstitute, etc.

    • cakoose 5 years ago

      I was surprised that every Jest+TypeScript guide says to use ts-jest. I already have my IDE, the TypeScript watcher, and ESLint parsing/compiling all the code! I don't want to add fourth one :-P

      I ended up just pointing Jest at my build output folder and that works. There are a couple minor annoyances but whatever.

      (I actually started with Ava because it more directly supports using the existing build output, but I ran into another issue and had to switch back to Jest: https://github.com/avajs/ava/issues/2385)

  • exogen 5 years ago

    AVA 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.

  • spinningarrow 5 years ago

    It's been a while (4 years) since I used Ava. Back then, it was impossibly slow - something about running tests in parallel even though they don't have any blocking operations being a significant overhead. Any idea if that's changed?

  • metachris 5 years ago

    Added, thanks.

jherdman 5 years ago

TSLint is deprecated in favour of ESLint. See https://palantir.github.io/tslint/.

  • sod 5 years ago

    We 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, based on swc, written in rust) for linting from then on. What tslint does in 6 seconds, `deno lint` does in 0.2 seconds.

    • twistedpair 5 years ago

      Hmm... 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.

    • wereHamster 5 years ago

      Same for build tools, esbuild is multiple orders of magnitude faster than babel.

      • eliseumds 5 years ago

        Yes, 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

joshghent 5 years ago

Ever 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.

  • zackify 5 years ago

    It’s interesting to see people feel this way about JS.

    Lately I’ve been trying to learn kotlin... and man... that stuff (gradle) adds a weird amount of boilerplate to everything.

    JS / TS on the other hand. It’s a package.json, or tsconfig. Not much else is required.

    Jump into deno and you don’t even need those. Feels like JS is one of the better languages in this regard

    • Groxx 5 years ago

      My interactions with Gradle have been with Android, and... oh boy do I hate it.

      It's a noticeably-more-concise-and-flexible option than what came before it, and the net result has probably been good. But it's next to impossible to understand and troubleshoot when things don't go perfectly. And similarly difficult to figure out what you need to do to achieve X, because who knows, it could be in any of thousands of locations, called anything, and there's not enough structure to let you infer what's reasonable and what isn't.

    • aphexairlines 5 years ago

      What's the weird amount of boilerplate in gradle compared to package.json + tsconfig (+ webpack.config.js or next.config.js, + jest.config.js, + babel.config.js, + workspaces) ?

    • jokethrowaway 5 years ago

      while I agree on kotlin (or java, or swift, or objective c), I think early releases of node.js or frontend development pre big frameworks were much better in that regard.

      We're still not as bad as mobile development, but things are getting worse.

      • nicoburns 5 years ago

        Have you tried esbuild. IMO it's a big step back in the right direction. We're not quite ready to switch to it on the frontend, but we're using it for our node.js (typescript) code. Configuration is 2 lines, and most of that's specifying which files to compile!

  • xyzzy_plugh 5 years ago

    I 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 5 years ago

      When 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).

      • TechBro8615 5 years ago

        It's a bit unfair to expect a framework not to provide new abstractions. That's required almost by definition.

        In React's defense, it's far from "impenetrable." In fact, its API exposes less than a dozen attachment points (considering render + lifecycle methods or their hook equivalents). It's a small and stable interface on top of a simple tree structure and an intuitive reconciliation algorithm. Most of the time you don't even need to reason about its logic, but when you do, it's understandable and debuggable.

        I'm also skeptical that we should consider framework-specific dev tools as evidence of an impenetrable abstraction. As long as the tools strictly enhance the debugging experience, they are a feature, not a smell. They are evidence of a problem when they only exist because it's impossible to debug the API without them.

        For example, Apollo Dev Tools "strictly enhances" the debugging experience. It provides a nice UI for GraphQL specific debugging sessions, but it doesn't break the "network" tab of Dev Tools. If you want to use apollo-client without its dev tools, you're no worse off than you were before adopting apollo-client. But you do gain something if you choose to use them.

        • spion 5 years ago

          React used to be simple, but now its indeed pretty much "impenetrable". Hooks are a strange API. Timeslicing and suspense add a lot of complexety for the benefit of very few. The processes for hooks-like funcitonality (algebraic effects) are supposed to be happening at TC39 (ESNext) level, but I can't see anything going on on that front; instead we have workaround hacks to make the API "look" like algebraic effects.

          Things just need to improve there, one way or another...

      • xyzzy_plugh 5 years ago

        Is React language or a library? Does it have its own virtual machine? If I'm debugging something that compiles down to assembly, sure, I can use GDB. Why shouldn't I be able to use the JavaScript debugger? Why does React go though so much effort to obfuscate its internals to such an extreme?

        There are a million other JavaScript libraries that do not have this problem, for what it's worth.

        > It means you don't need to understand the details of how React is implemented.

        Isn't this the topic of discussion? Why shouldn't it be as simple as "React stores state in this variable" and I can just poke at it like any other variable?

        Abstractions are great, but they all leak eventually. Being able to see through the abstraction is immensely valuable, regardless of where you are in the stack.

        Don't confuse simplicity for its pernicious cousin convenience, which usually does not actually reduce complexity, but heralds it.

        • nicoburns 5 years ago

          > Is React language or a library? Does it have its own virtual machine?

          It's a library, but it does provide a runtime. As such it IMO makes sense that it would have it's own debugging tools. This is pretty common for complex frameworks. Other frontend frameworks like Angular and Vue do it. As do backend frameworks like Rails and Laravel. Or as another example you could look at Unity (the game framework).

          You can still use the JavaScript debugger, and I do all the time with React code. But for React specific concepts the React specific tools provide a better experience.

          > Why does React go though so much effort to obfuscate its internals to such an extreme? There are a million other JavaScript libraries that do not have this problem, for what it's worth.

          It doesn't do it intentionally. It's internals are somewhat complex for performance reasons. Which other JavaScript libraries allow you to inspect their current state with the JavaScript debugger? That's what the React dev tools give you: state inspection. IME, lot's libraries make inspecting that quite difficult (unless they're using global variables).

          > Why shouldn't it be as simple as "React stores state in this variable" and I can just poke at it like any other variable?

          The problem is that you can't typically poke variables using the JavaScript debugger. To do so you need to get a reference to the variable. And you can only reasonably do that for globals.

          > Abstractions are great, but they all leak eventually. Being able to see through the abstraction is immensely valuable, regardless of where you are in the stack.

          I guess I've just never hit into the limitations of the React abstraction (and I've done pretty complex things). Nor have I ever hit a bug in the implementation. To me it's like my database or my filesystem: sure it's great to be able to peak under the hood if I really need to, but 99.9% of the time I'm super glad that I don't. I've had much worse experiences with Angular (1 and 2) where I frequently felt like the abstraction was leaking a lot.

          • xyzzy_plugh 5 years ago

            As someone who works on and fixes bugs in databases and filesystems, perhaps we don't look at things the same way.

            • hmsimha 5 years ago

              When you have to debug something in postgres, are you going to communicate with it by using netcat and writing your own TCP messages by hand, or use psql? Both should work, but you wouldn't say postgres is obfuscating things intentionally so that you have to use psql (or some other postgres client). The fact of the matter is that complex tools are much more useful if they also come with tools to pave over (some of) that complexity and provide a more useful interface for developer experience.

              You can debug React apps just fine without the React developer extension, but in some situations it will be much harder. And to elaborate, I work on React full-time and just use the javascript console and debug messages for 99% of my debugging.

              • xyzzy_plugh 5 years ago

                The Postgres protocol is documented extremely well such that it is actually trivial to write messages by hand, and yes, I have used netcat instead of psql.

                I honestly couldn't find anything remotely similar in my search for to unearth React runtime internals. Maybe I'm missing something but literally every answer was "just use the extension."

                • nicoburns 5 years ago

                  If you want to debug a performance issue in postgres, then the answer will be similar: "just use EXPLAIN ANALYZE". You could get out a C debugger and step through the source code, and there are cases where that is appropriate (e.g if you're working on Postgres itself, or you're trying to diagnose a bug in postgres), but if all you want to do is debug your query then you should use the postgres-specific debugging tool (EXPLAIN ANALYZE).

                  Same for React. If you are working on React itself, or you need diagnose an actual bug in the runtime then you'll want to use the JavaScript debugger and step through. If all you need to do is work out why your component isn't updating then you can use the React-specific tool (the extension) to make your life much easier.

                • fiddlerwoaroof 5 years ago

                  If you really wanted to, you could write your own renderer. there’s already several: react-dom, react-native, react-test-renderer. Also, I believe there’s at least one conference talk where a renderer was live coded

            • wonnage 5 years ago

              Maybe you're just not familiar enough with React? The core of it is actually quite simple, it's just a giant while loop tree traversal that gets triggered either imperatively (by calling one of the React.render* functions) or in response to a state change. The VDOM stuff is mostly orthogonal to this, it just improves performance in the browser, but you could technically skip it without losing anything.

              Your argument is basically the same as saying you'd rather view HTML as a giant string rather than in a tree view... the devtools basically present something that's linear (the tree traversal) in a tree view, it's not that bad.

            • coldtea 5 years ago

              Well, parent can find an error in a React app with a standard JS debugger, you can find an error in databases and filesystems with gdb or some such, but not vice versa.

              Can be as simple as that: familiarity.

              • kbenson 5 years ago

                I don't think that's quite it, at least not entirely. They were complaining about how everything they found on how to diagnose and inspect the problem started with downloading a third party tool.

                I read this as a complaint that React doesn't provide information on what's going on that you can see and inspect (whether true or not). The equivalent for Postgres would be if they didn't document their protocol and instead referred you to a special debugger they provided, and you had to rely on that instead, making use of gdb or the equivalent much more complicated.

                • nicoburns 5 years ago

                  Except the React devtools extension is a first-party tool maintained by the React team [0]. They don't distribute with the library, but given that it's a browser extension there's not really any way that they could.

                  Also, the react dev tools aren't really a debugger. There's no way to step through code or similar. It just provides an insight into React's internal state (the component tree, and any state contained within it). The equivalent would be Postgres providing a tool to inspect the contents of its caches or indexes, and the OP complaining that they can't read them when using GDB.

                  [0]: https://reactjs.org/blog/2019/08/15/new-react-devtools.html

                  • kbenson 5 years ago

                    > React devtools extension is a first-party tool maintained by the React team

                    Which makes my example more accurate barring two words...

                    > Also, the react dev tools aren't really a debugger.

                    All it takes to be a debugger is to provide additional info about a running process. Insight into React's internal state definitely qualifies IMO. Even if you think it doesn't quite qualify, Chrome Devtools are a debugger, and whether something that extends it to give better info is a debugger or an extension for a dubber is missing the forest for the trees.

                    That said, I'm not necessarily agreeing with the original premise, since I don't know how hard React is to introspect at this point (I know in the past some websites purposefully made it very hard on purpose). I'm just not sure the original comment's point of view can be boiled down to whether someone is familiar with the technology or not (and part of the reason I'm not sure might be lack of knowledge).

        • fiddlerwoaroof 5 years ago

          The difference between a language and a library is arbitrary: it’s all an artifact of programming ecosystems that place a hard division between the “language implementors” and the “programmers”: every library of sufficient complexity is an embedded language with annoying syntax.

      • agentwiggles 5 years ago

        I got a good chuckle at the silliness of the mental image of hooking up a scope to diagnose a JS error. Thanks for the laugh.

        (tl;dr: lol)

      • jorblumesea 5 years ago

        Debugging a popular library is not at all equivalent to those layers of abstraction. This argument is so flawed it almost feels malicious.

    • nawgz 5 years ago

      > Okay but this thing boils down to just JavaScript right

      I am not really sure I understand this stance. My JavaScript ultimately just boils down to C++, no? C++ ultimately just boils down to machine code, right? Yet you clearly wouldn't try to tackle those things at that layer.

      Without more statements on what this bug was and why there weren't error messages or why it was so hard to recreate you felt you could only look at it thru a debugger, I really completely fail to understand your point.

      > Abstractions are supposed to remove complexity

      React does remove a ton of complexity from writing frontend - good luck composing HTML & JS components with just jQuery - but in exchange it also introduces some, of course. So they make that new and different complexity easier to handle with their dev tools.

      > I swore off abstractions ... [that] treat users like morons

      I really have a tough time to read this charitably. What on earth are you on about?

    • azangru 5 years ago

      > I recently was trying to diagnose a bug with React state in someone else's project. Everything I found said "install the React extension"

      Really curious what you mean by that.

      There are two possible Chrome (not React) extensions for dev tools that I can think of — one is the "official" extension by React core team that helps visualise components better and also helps understand why they may have rerendered. The other is a redux extension that's very helpful to inspect all the actions that were dispatched against the store and the changes they caused in the redux state. None sounds like what you are describing. Bugs with React state should be easy to diagnose just with a handful of console logs.

    • diob 5 years ago

      Honest question though, what abstraction do you use in place of React?

      I don't disagree that it's pretty obtuse, despite loving working in it. I miss being able to look up the source of Backbone.js and gain a real understanding of why something was happening. Maybe I'll get to that point in React, but it seems much harder to grasp what the source is doing.

      • xyzzy_plugh 5 years ago

        I just write JavaScript? The concepts of Basecamp's Hotwire[0] are particularly simple and elegant enough for the 1% of stuff that isn't just a static page or can't be solved in a single JS function.

        I've never been like "boy I really need a virtual DOM" so I guess I've never really seen the appeal of React. It just seems like a bundle of complexity, obfuscation and anti-patterns.

        0: https://hotwire.dev

        • qudat 5 years ago

          > I just write JavaScript?

          This is the tell. If you are able to satisfy your business requirements with "just JavaScript" then you are in a completely different world than the people building production-grade web apps and there's absolutely nothing wrong with that. If you can be productive with "just JavaScript" then that's awesome!

          However, I'm sure you understand there's a massive difference between simple pages that need *some* interactivity and a full-blown app inside a web browser.

          I'm sure you've come across projects that probably didn't need the same tooling that I'm describing which ultimately boils down to a judgement call.

          > I've never been like "boy I really need a virtual DOM" so I guess I've never really seen the appeal of React. It just seems like a bundle of complexity, obfuscation and anti-patterns.

          That's because you've never needed it before. I've never been like "boy I really need a batteries-included web framework" so I guess I've never really seen the appeal of Rails. It just seems like a bundle of complexity, obfuscation and anti-patterns.

          • gmfawcett 5 years ago

            > ...than the people building production-grade web apps...

            Please don't co-opt the word "production" to mean what you're implying here. Production doesn't mean single-page, reactive, etc. applications, it just means "in production."

          • xyzzy_plugh 5 years ago

            I'm curious -- what is not possible with just JavaScript? Why do you assume "a full-blown app inside a web browser" isn't possible without React or something like it?

            Is client-side rendering strictly necessary? Do your websites actually run offline?

            I've built websites with React, used React Native -- none of it is necessary, nor the end-all-be-all. There's nothing truly novel going on. You can accomplish the exact same experience with server-side rendering and a tiny smattering of vanilla JS (you can use modern JS and polyfills and webpack/esbuild without React, you know).

            For 99.9% of the web, I'd argue you don't need it. I have yet to encounter the 0.1% personally.

            If you don't believe me, know that I'm not alone. Take a look at https://levels.io/deviance/ -- PHP and jQuery. What would React provide that isn't possible with his stack?

            There is a disturbing amount of kool-aid being consumed around React/Vue/etc. Sure, you can slap together a website in record time with massive boilerplate/templates -- but so can I.

            • __s 5 years ago

              Here's your 0.1%: a card game, https://etg.dek.im before React I was using PIXI.js, over the years it's transitioned from being fully rendered in canvas to not using canvas at all (& now uses webpack, but years ago I had my own bundler mkcjs https://github.com/serprex/mkcjs which was pretty vanilla js, using require let me share code for awhile between server/client until server was rewritten in Rust)

              react-motion made animating card transitions very straight forward

              During a game you can click on history items to look at previous game states, this is very straight forward with React's model

              Sure you could get this all by rolling your own state dom renderer, but that's like saying you can do everything Lisp does in C. Greenspun's tenth rule rephrased as "Any sufficiently complicated JavaScript UI contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of React."

          • flippinburgers 5 years ago

            Websites that are "production-grade" can be built without tools like react.

        • amenod 5 years ago

          While you don't _need_ React (or a similar powerful library / framework), it takes one's productivity to a whole different level.

          I have a feeling that you have already made up your mind not to like it, but if you ever give it a fair try, you might find it useful for some projects. It is very complex under the hood, of course, so if you want to have total control you might need to dig into the internals. But to a casual user it gives a very nice abstraction, very powerful, easy to use (granted - and abuse) and performant. The thing that sold it for me is the declarative programming. You have state, state translates to rendering... and that's pretty much it. Compared to thinking about transitions in native JS (or jQuery or whatever) it is like night and day in any non-trivial project.

          • xyzzy_plugh 5 years ago

            I've tried it. And yes, I want full control. The abstractions mostly work, but when they don't -- there you are again, thinking about transitions in native JS again. What was the point?

            • amenod 5 years ago

              Well, newsflash: you are always dealing with abstractions, no matter which layer you pick. You might just as well pick one that lets you develop more complex things faster and more reliably. That said, if you are set on actively fighting it (not installing react dev tools, being frustrated by not having visibility under the hood) then it's probably best to stay away from React.

              I have quite a lot of history with native JS, but was happy to relinquish control to webpack/babel/react... not at first (had the same reaction as you do), but once I gave it a fair chance I discovered that things just work. Never had any problem with React not performing the way it should.

      • axelf4 5 years ago

        I consider part of the blame to lie with React. The React source code structure is pretty obtuse. Compare that to the Inferno.js source code which is easy to understand and navigate for anyone familiar with how a VDOM library should work.

      • vaughan 5 years ago

        I miss Backbone too. You could just step through the code in the debugger and it was so compact.

        With React you can’t really do that. It’s always following an error message saying: “look near this component” which is often deep in the hierarchy of some third party package’s component hierarchy that is transpiled into a single line with no source maps.

        I think there is a huge benefit in making things easy to step-through in a debugger when something goes wrong.

        • arcanon 5 years ago

          That’s because Jeremy Ashkenas is a beast. Coffeescript started modern JavaScript.

    • apatheticonion 5 years ago

      Try to implement a website without React or Angular/Vue.

      When you hit your first list of elements and need to rerender the contents of just one of the elements, you will begin writing your own React.

      If you try to implement some kind of "two way databinding", you will first create React, then create Angular.

      However, unreadable and disorganised code can be written at any abstraction level. I have found React projects to be particularly hideous due to the fixation engineers have for tools like Redux.

      Angular tends to be a bit better because it's got some decent software design principles built in - but you know front end engineers. Any project with ngrx is a write off from an readability perspective.

      Isomorphic applications are also a meme that kill readability.

      I write most of my personal projects using Preact and some kind of reactivity helper (RIP `Object.observe`, I grieve for you).

    • lr4444lr 5 years ago

      You're not wrong, but I think you're missing the value of React: the simplicity is not having to worry about the correctness or efficiency of your render engine. You get to go back to a more declarative way of writing code that comes with a modular composable style. There's a cost to pay for this: surrendering control (and easy insight) of the DOM you once knew to React's core logic. You do get a variety of callbacks to hook into, and I always encourage people to learn more about their frameworks, but you're not buying a set of convenience methods like you were with jQuery: this is effectively an interpreter between your data and its rendering.

    • flippinburgers 5 years ago

      I have a deep love/hate relationship with react so I largely agree with you.

      The last time I used the extension, it was obnoxious to use to try to find "state" within the page. Using redux makes things easier to debug from this perspective but you do need yet another extension for that too...

      I really think this is a sign of young engineers who have no experience with older approaches just memorizing "how things are done". They have no perspective on the tooling or experience.

    • schwartzworld 5 years ago

      The react extension is pretty powerful. You can work without it, but it enables debugging techniques that would be much harder without it.

    • nsonha 5 years ago

      not a good example, knowing how things work is not a reason not to use debugger or similar tools

  • vagrantJin 5 years ago

    In 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.

  • knubie 5 years ago

    I’m reminded of Rich Hickey’s talk Simple made easy. The gist being that easy is not always simple (yarn install hairball) and simple may not seem easy at first (unfamiliar).

    Back then the comparison was made with rails, but it still holds true with modern web development now more than ever.

  • meheleventyone 5 years ago

    The nice thing is you don’t need all this stuff it’s just one persons opinion of what you need. It’s mostly that you get a bunch of extra functionality with it. Additive rather than required.

    I feel like I went through exponentially more faffing about setting up the web server and forwarding to the accompanying Go server on DigitalOcean than I did getting my project running in modern browsers just using tsc.

  • rglover 5 years ago

    Yep, understand this completely. Love that talk, too.

    What I've pinned it to is a cultural problem in the JavaScript realm: everybody wants to impress everybody else about how smart they are, and in the process of doing so, creates convoluted mazes. As a side-effect, motivation dips and then quality control falls in concert, leading to an "at least it works" mentality.

    That's my curmudgeon speculation/observation, at least.

  • bcrosby95 5 years ago

    I watched the talk and didn't find it that interesting. Worst case scenario you can experiment to figure it out. Experiments in software are cheap.

    Compare it to the hardware level. The technology required to build a modern CPU is fucking amazing compared to things like being aware of cache coherency when writing code. The amount of time and experimentation to regain the knowledge required for building the full supply chain a modern CPU would be monumental compared to learning to go from something like JS to C.

  • droobles 5 years ago

    I found it to be a really cool experience setting up Nodemon with TS myself with a few Medium guides – because of that I know my app's build system inside and out!

  • f00zz 5 years ago

    I can't even imagine how painful it must be for a curious kid to get started in programming these days. I feel so lucky to have started with a little 8-bit computer with a built-in BASIC interpreter. You turned it on and could start typing your program right away.

    • idolaspecus 5 years ago

      It’s about a million times easier today. Open a browser, open dev tools, open console tab, console.log(“hello world”).

      It’s even easier than that though.

      Open chrome, type “how to write computer programs” and go from there.

      • Sindisil 5 years ago

        Not sure how that's easier than: Turn computer (which boots close to instantly), print "hello world".

        It is certainly true that there are more informational resources available, but honestly, there was plenty of good info available at most decent libraries, and the manuals that came with computers were typically troves of information back in the 8-bit days.

        • fiddlerwoaroof 5 years ago

          Yeah, people forget (or just never experienced) how easy it was to learn something like Delphi pre-Internet: the software box had good manuals and you just hit F1 for context-sensitive help that was actually useful.

        • evan_ 5 years ago

          computers don't need to boot "close to instantly" because nobody ever turns them off now. The "open browser" step in the previous comment is probably a noop because who even closes their browsers?

    • twistedpair 5 years ago

      A ton easier!

      Sure, reading the two inch thick book on programming your TI-83+ was informative, but God help you if you got stuck.

      Now we've got Scratch (visual programming), Arduino (push button C compilation!), and StackOverflow full of the answer to most any problem of stacktrace you encounter.

      I don't have to read a tome for hours or wait a day or two for a response on a creeky BBS. Much easier.

    • tshaddox 5 years ago

      I’d be surprised if someone hasn’t emulated or otherwise cloned whatever 8-bit computer and BASIC interpreter you used as a JavaScript web app that can we loaded in a few seconds in any modern web browser.

  • twistedpair 5 years ago

    Is it really that hard?

    > npm init > npm i --save-dev typescript

    Add "build":"tsc" to your package.json "scripts" Add a tsconfig.json file

    > npm run build

    Finito - you've compiled a TS project to JS

    • dboreham 5 years ago

      What mystery meat is in that tsconfig.json though?

    • PetahNZ 5 years ago

      tsc doesn't bundle, or resolve imports, or transpile for cross browser though, does it?

      • TechSupportJosh 5 years ago

        Using something like Parcel means it's usually as easy as adding parcel serve or parcel build to package.json and it handles the transpile, module resolution, bundling, tree shaking and hot reload for development.

  • rbtprograms 5 years ago

    This has also become my biggest issue with Typescript, and a lot of the people I have talked to about it agree this is the biggest pain point. I am not sure what a better system for this would be, but I do hope the Typescript team takes a hard look at this because I could see it being Typescript's Achilles heel.

    • wonnage 5 years ago

      You don't actually need to do any of this stuff to run typescript. You could use Deno, ts-node, etc. to run code outside of a browser without a separate build step. And there's nothing wrong with using tsc to compile your code to JS for browsers, it's just slower for big projects.

      If you have an existing JS project that's being converted to TS, you likely have bundling, linting, and CI handled already; for the most part, you just add `preset: typescript` to your existing Babel config and you're done.

    • smt88 5 years ago

      This is an issue with JavaScript that TypeScript inherited. The many module systems and ES versions that need support are insane.

BiteCode_dev 5 years ago

If 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.

NikhilVerma 5 years ago

Very 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 5 years ago

    I’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.

mark_and_sweep 5 years ago

In 2021, I think it's safe to start a TypeScript project with Deno.

  • liminal 5 years ago

    Doesn't that depend on what libraries you need?

    • mark_and_sweep 5 years ago

      Any JS that runs in the browser runs in Deno, too - so that's quite a few libraries...

      If there is a Node-specific library, i.e. a lib that uses the require global, the fs module, etc., then you can, in many cases, use the Node compat module from the Deno std lib and just drop it into your project.

      That being said, there's of course a Deno-specific ecosystem of libs, too, i.e. libs that use the Deno global. So you might find a suitable replacement if your favorite Node lib is not compatible for some reason.

  • bfm 5 years ago

    This!

    After working with node.js for more than eight years I decided to give deno a try (https://github.com/bermi/genetic) and I’ve been gratefully surprised by the development experience.

    I’m just missing a simple way to include deno code on my existing node.js and browser projects.

  • lkesteloot 5 years ago

    Has anyone experimented with making a custom version of Deno that has its TS files built-in? I want to give my user exactly one binary that they can run to use the tool I'm writing, as if I'd compiled it in C/go.

  • christiansakai 5 years ago

    Does Deno work for frontend?

    • mark_and_sweep 5 years ago

      As always, depends on your use case.

      I'd say it has lower friction in general since Deno is using Web APIs, e.g. the fetch API is built-in (see https://deno.land/manual@v1.9.1/runtime/web_platform_apis).

    • danieka 5 years ago

      It's possible, but slightly cumbersome, to write isomorphic apps. Deno has a library that can bundle Typescript for the browser at runtime. But maybe look into Vite instead for frontend.

    • halfmatthalfcat 5 years ago

      No it's a replacement for Node.

      • andrew_ 5 years ago

        Please 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/ is the first result, and there are a litany of other articles explaining the same.

        • TechBro8615 5 years ago

          Deno as a "replacement for node" seems like a roughly accurate three word description. Neither Node nor Deno is a programming language. Both are runtimes, just like the browser. All three of them link with V8 which is the actual runtime (technically it's a JIT compiler, and only Chromium based browsers use V8 -- Firefox uses SpiderMonkey and Safari uses WebKit).

          So to answer the original question, "Does Deno work for frontend?", the premise of the question is inaccurate because Deno is an environment where you can run TypeScript code. It doesn't make sense to "run Deno in the frontend" (though maybe you could come up with some wasm monstrosity enabling an approximation of it). The better question would be, "can I share (as in re-use) TypeScript code in Deno and the Frontend?" to which the answer would be mostly yes -- but you'll still likely end up needing bundlers like webpack to help with it.

        • r0p3 5 years ago

          This article gives the distinct impression that Deno is an alternative to node and solves the same problems.

        • wa1987 5 years 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_ 5 years ago

            I 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=Wh...) that covers the basics of all three asked points.

            • mannanj 5 years ago

              I did not want to have to sift through a hefty article to get answers to the questions. Anyone can google search, but I see the points of the comments to share condensed information not just to "link" to google.

              Here's what I discovered as what I presume andrew_'s reasoning for why its not a node replacement (from the article)

              "Node has been under development for over a decade, which makes it more stable and battle-tested, making it the de facto standard for server-side JavaScript. Deno has only been under development for just two years and continues to be improved. Among other things, Deno is an excellent replacement for utility scripts that are usually written with bash or python."

        • KajMagnus 5 years ago

          I have in mind to use Deno instead of both Node and Bash scripts :- )

  • chrisjc 5 years ago

    Do you have any quickstart guides that you could recommend to get started with Typescript and Deno?

austincheney 5 years ago

That 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 5 years 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 5 years ago

      FYI PowerShell is pretty cross-platform these days.

      But I see having it all written in JS is still simpler.

      • TechBro8615 5 years ago

        I 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.

        • tompazourek 5 years ago

          I've read about NixOS here on HN which aims to do something similar.

          Does your approach with using docker heavily have some disadvantages you experienced? Just curious, it sounds interesting...

          • TechBro8615 5 years ago

            Yes, lots. You need to pay operational complexity early and often. A lot of tools don't work out of the box due to volume sharing, permission issues, etc. You need to figure out dev vs. prod images, how to do incremental builds locally (e.g. you switch branches) and in CI (new push). Lots of issues like this.

            Overall it's worth it in the end if you're making a long term investment, IMO. It forces you to build modular infrastructure from the beginning, so there are few surprises when pushing to prod.

    • austincheney 5 years ago

      But almost none of the instructions provided in the article are JavaScript. They are shell commands.

lenkite 5 years ago

As 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 5 years 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 5 years ago

      Admittedly 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, 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 5 years ago

        brew 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.)

    • wereHamster 5 years ago

        % nix-shell -p deno
          these paths will be fetched (18.39 MiB download, 57.83 MiB unpacked):
            /nix/store/vr6lw60nav6kd0qjkb61lbb78mpx4pry-deno-1.8.2
          copying path '/nix/store/vr6lw60nav6kd0qjkb61lbb78mpx4pry-deno-1.8.2' from 'https://cache.nixos.org'...
        [nix-shell:~]$ deno --version
        deno 1.8.2 (release, x86_64-apple-darwin)
        v8 9.0.257.3
        typescript 4.2.2
city41 5 years ago

Casting window to any in a pinch does work. But for longer term stuff, it's probably better to extend the Window interface.

nikivi 5 years ago

Nice article, you could also just use https://github.com/formium/tsdx

  • rossng 5 years ago

    I 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

    • imjared 5 years ago

      I 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 5 years ago

      I think the creator of TSDX has shifted focus to turborepo.com

  • latchkey 5 years ago

    I'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.

  • chatmasta 5 years ago

    If 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-referen...

    [1] https://rushstack.io/

  • vohvae 5 years ago

    I 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.

  • metachris 5 years ago

    Author of the post here. Thanks for the link; added it to the post in the "Notes" section.

    • dagurp 5 years ago

        npx create-react-app my-app --template typescript
      
      is also an option
mrweasel 5 years ago

This 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.

revskill 5 years ago

I 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 5 years ago

    One 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/...

Xavdidtheshadow 5 years ago

I do this sort of thing often enough that I wrote a Yeoman generator to scaffold everything: 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!

haolez 5 years ago

I'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/

  • chrysoprace 5 years ago

    For 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.

  • hermanradtke 5 years ago

    It has been a while, but BuckleScript is the pain point. TypeScript is much easier to use within the existing JS ecosystem.

meheleventyone 5 years ago

I’m curious about the value of eslint for TypeScript. I’ve not really found myself wanting from the coverage provided by tsc.

  • halfmatthalfcat 5 years ago

    To 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 5 years ago

      A 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-ty...

  • thealfreds 5 years ago

    It's useful if you have a custom eslint ruleset you want to apply to your ts projects. Some of those rules aren't always available on tslint.

    Mostly helpful to keep a shared ruleset across projects.

  • andrew_ 5 years ago

    The 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.

  • twistedpair 5 years ago

    To us, the biggest value is auto-refactoring the code to comply w/ styleguides and rules. There are many great rules in eslint that cover most known anti-patterns. For a start, just grab the .eslintrc.json from the microsoft/typescript repo.

    We've hooked up "eslint --fix" and "prettier --write" to "npm run fix".

    One command before committing and you comply with all our coding rules. Easy, peasy. We tie the combined checks into "npm run check", and run this in CI/CD, so we know only compliant code is merge. Check!

    Most other lang tools _won't_ do this. Take PMD or Checkstyle for Java. They'll just fail your build, but won't make your code compliant.

    Finally, if you decide you want to add a new code convention to your repos, it's just a one liner: "npm run fix". It doesn't get much easier.

  • metachris 5 years ago

    IDE integration is one benefit, as in VS Code showing the linting issues without compiling.

  • striking 5 years ago

    Have you tried some of the type info based rules in typescript-eslint? They're fantastic.

    No floating promises, no bad templating, etc.

    • meheleventyone 5 years ago

      No but the replies here make me think I should definitely give it a go. So thanks for the info everybody!

  • dtech 5 years ago

    Linting is not the same as typechecking. Take a look at the default available rules [1]. For example number == NaN is valid Javascript, but 99.9% of the time an error. Or you might want to require always using === over ==.

    Generally, linting is things that are valid in the language, but still better to do otherwise.

    [1] https://eslint.org/docs/rules/

    • meheleventyone 5 years ago

      I’m aware of the difference just wondering what benefits people have found. Catching == versus === is a good one.

      • ponyous 5 years ago

        import order, empty function bodies, leading underscores in different scenarios (if you have such conventions), sort object keys (not just alphabetically, but by use, eg. shorthands last { name: 'Jim', surname }...)

        There is some overlap and it's not as crucial to have a good linter as it used to be.

      • GORRILA 5 years ago

        Two common rules I like to enforce are no nested ternaries and no unused variables.

  • city41 5 years ago

    I use eslint for things like catching left behind debugger and console statements.

  • madeofpalk 5 years ago

    e.g. ban `any`, which you cannot do with tsc.

kevsim 5 years ago

This 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.

tppiotrowski 5 years ago

esbuild 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.

  • lovelettr 5 years 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 [2] https://github.com/evanw/esbuild/issues/802

  • WorldMaker 5 years ago

    Snowpack 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.

  • vergessenmir 5 years ago

    I have started looking at this for Svelte projects from a post yesterday on non-javascript build tools. Very promising indeed,

nsonha 5 years 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

hardwaresofton 5 years ago

I 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 5 years ago

    How 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

    • Spivak 5 years ago

      Huh? But bash is super powerful? I can go from zero to a script that's production ready in like an hour with option support, help text, man pages, shell completion, signal handling that's portable to any system.

      I also like Python for this but it's an absolute PITA to distribute scripts that support lots of different versions of python or need any dependencies not in your distro's repos.

      • KajMagnus 5 years ago

        Yes it's powerful, I agree about that. At the same time, it's not type safe (but Deno + Typescript would be), and the syntax is a bit funny, like the differences between `( (( [ [[` which I annoyingly often forget. One day, when I saw code like this:

            if [[ ${1:0:1} = '-' ]]; then
              ...
              set --
        
        I got a bit annoyed, and said to myself that Bash scripts almost should be forbidden. I didn't know that syntax `${1:0:1}` and there wasn't really anything to websearch for — just different symbols.

        Websearching for "bash bracket colon colon" something actually worked but it took a while. In a typed language, I'd just clicked a function and would have seen the docs, in an instant.

        > from zero to a script that's production ready in like an hour with option support, help text, man pages, shell completion, signal handling that's portable to any system.

        It seems you've been used Bash for quite a while. Then I'm guessing in your case, it's a good choice. Agreed that dependencies for Python or Deno or whatever else is annoying to have to include (the Deno runtime is sth like 50 - 60 MB if I remember correctly)

    • hardwaresofton 5 years ago

      Lots of ways! So this is one of those things that's subtly quite interesting -- Make will both take all variables from the environment, and make them Make variables. So this command:

          $ USER=my_name make psql
      
      The above example is the creation of a temporary ENV variable (assuming your shell supports this feature, it's equivalent to doing an export but only for that line), and the USER variable (accessed by using $(USER) or ${USER} in your makefile somewhere) will be automatically populated.

      That is distinct from the following:

          $ make psql USER=my_name
      
      What you've done there is actually make-specific, you're giving make a Make variable, so Make will know about $(USER)/${USER}, and it will also show up, because Make exposes it's variables to shells (each line is it's own shell) that is run[0]. So this Makefile:

         .PHONY: my-tgt
      
         my-tgt:
           echo -e "double dollar to print a bash var => $$MYVAR"
      
      Produces the same thing -- $$MYVAR is actually a way to use a shell variable (the $ has to be escaped), but you get the same result putting USER= before and after:

          $ MYVAR=from-the-shell make my-tgt                                                                                                            
          double dollar to print a bash var => [from-the-shell]
          $ make my-tgt MYVAR=from-make                                                                                                                 
          double dollar to print a bash var => [from-make]
      
      All that said, if you don't need to ever change the name then just make the target `psql-<username>` or `psql_username`, problem solved! For example, I use kubie on my kubernetes cluster, and I have explicitly named clusters, so when I want to enter a kubie context (just so I can avoid some typing), I run `make <cluster name>-kubie` and I'm off -- I didn't feel the need to do `make kubie CLUSTER=<cluster name>` though I easily could have. Here's what it actually looks like:

          mycluster-kubie:
           CLUSTER=mycluster $(KUBIE) ctx -f secrets/ansible/the.dns.name.of.my.server/var/lib/k0s/pki/admin.conf
      
      I don't strictly need that CLUSTER=mycluster there, but if the command cared, then it could be easily "hard coded".

      > Bash scripts almost could be illegal :- ) I'm thinking about writing scripts in Deno in the future, instead

      Bash is super powerful, and some people are good at it, but it just hasn't stuck enough for me to be comfortable. Plus, it still feels like another language to be wrangled while Make's only purpose is to do the things (whatever that thing is) that build your software.

      [EDIT] figured I might share some more nice pieces of software that I use and love (also so you don't think I'm just willy nilly checking in secrets to my repository):

      - direnv[1] for managing local ENV settings in a given folder (like your project folder)

      - git-crypt[2] for simple encryption of secrets in a git repository, with gpg support

      - entr[3] it re-runs a given command when files change, really good for reducing feedback loops when working with tooling that doesn't have --watch/fsnotify functionality

      [0]: https://www.gnu.org/software/make/manual/html_node/Environme...

      [1]: https://direnv.net/docs/hook.html

      [2]: https://www.agwa.name/projects/git-crypt/

      [3]: https://eradman.com/entrproject/

      • KajMagnus 5 years ago

        Thanks for the reply & all info :- )

        Actually, this: `USER=my_name make psql` and this: `make psql USER=my_name` I don't like that much: No command line completion of `USER=my_name`.

        Makefile targets like `mycluster-kubie` are nice, although they can result in a combinatorial explosion (if one needs two or more parameters).

        It seems to me that after all, it'll be Deno or maybe Rust "scripts" that I'll want to use, combined with Make — Make for building, and Deno for running things.

        (Running = often, nice with command line completion. Building = less often.)

        Thanks for the extra pieces of software :- ) Direnv looks nice, makes me nervous about security exploits though (seems it automatically parses a file in the current directory, sometimes provided by strangers, via a Git repo that maybe I just wanted to look at). Hmm, https://github.com/direnv/direnv/issues/23 "security considerations"

        Git-crypt seems like a nice way to maybe distribute secrets for accessing one's CI environment :- )

        Didn't know about entr. Currently I use inotifywait (from package inotify-tools in Debian)

        • hardwaresofton 5 years ago

          No worries, no one really talks about it, but you see makefiles all over.

          > Actually, this: `USER=my_name make psql` and this: `make psql USER=my_name` I don't like that much: No command line completion of `USER=my_name`.

          > Makefile targets like `mycluster-kubie` are nice, although they can result in a combinatorial explosion (if one needs two or more parameters).

          True, it's a bit inconvenient!

          > It seems to me that after all, it'll be Deno or maybe Rust "scripts" that I'll want to use, combined with Make — Make for building, and Deno for running things.

          This sounds wonderful -- the biggest downfall of make is when you start to try and do complicated things with it, so your usecase seems awesome. Make is good for that glue/orchestration in my opinion -- when you need to run pulumi/terraform right before you do some deno-scripted setup.

          > Thanks for the extra pieces of software :- ) Direnv looks nice, makes me nervous about security exploits though (seems it automatically parses a file in the current directory, sometimes provided by strangers, via a Git repo that maybe I just wanted to look at). Hmm, https://github.com/direnv/direnv/issues/23 "security considerations"

          Ahh so for that, I don't check in my `.envrc` folders but yeah that's certainly an issue -- whenever you encounter a `.envrc` you have to allow it though!

          Every time you enter a folder that direnv hasn't seen before, or the file in there changes, you have to run `direnv allow` for it to be taken up.

          > Didn't know about entr. Currently I use inotifywait (from package inotify-tools in Debian)

          Ahh then that's probably just as good -- A friend showed me entr like.... 10+ years ago now and it's been a trusted tool on projects ever since, whenever the language/framework doesn't really have it, or I feel like some bit of work needs to be more streamlined/shorter feedback.

          • KajMagnus 5 years ago

            > Every time you enter a folder that direnv hasn't seen before, or the file in there changes, you have to run `direnv allow` for it to be taken up.

            That sounds great, just like I would have hoped that it'd work. And, because of this: "or the file in there changes", in a way it's even safer than a Makefile — in that Make wouldn't notify me if the Makefile got changed, but Direnv does (and people might not remember to look at any Makefile diff after pulling from the repo). — Now I'm starting slightly thinking about if Direnv makes sense somewhere in my own project(s).

seniorsassycat 5 years ago

I 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 5 years ago

    I disagree, I don't want my project to successfully build at all if I have type errors.

    • seniorsassycat 5 years ago

      I block commit, push, and release workflows by lint, type errors, and test, but I don't block running tests or running my program.

metachris 5 years ago

This is the example repository: https://github.com/metachris/typescript-boilerplate

mikojan 5 years ago

...or (since it's 2021) you could just use snowpack and call it a day.

riskable 5 years ago

At 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.

  • intergalplan 5 years 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.

  • sfvisser 5 years ago

    Good luck building anything interactive this way.

  • mattwad 5 years ago

    Seems pretty simple given it includes not only test setup and continuous integration, but also publishing to npm and documentation

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection