From f5b467a1def29e347235562222be92d3716790e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=AD=E5=BC=80=E7=AE=B1?= Date: Fri, 24 Mar 2023 19:42:01 +0800 Subject: [PATCH] =?UTF-8?q?[=E6=89=8B=E5=8A=A8=E9=80=89=E9=A2=98][tech]:?= =?UTF-8?q?=2020230216.2=20=E2=AD=90=EF=B8=8F=E2=AD=90=EF=B8=8F=20Writing?= =?UTF-8?q?=20Javascript=20without=20a=20build=20system.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...️ Writing Javascript without a build system.md | 226 ++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 sources/tech/20230216.2 ⭐️⭐️ Writing Javascript without a build system.md diff --git a/sources/tech/20230216.2 ⭐️⭐️ Writing Javascript without a build system.md b/sources/tech/20230216.2 ⭐️⭐️ Writing Javascript without a build system.md new file mode 100644 index 0000000000..bd45ab0824 --- /dev/null +++ b/sources/tech/20230216.2 ⭐️⭐️ Writing Javascript without a build system.md @@ -0,0 +1,226 @@ +[#]: subject: "Writing Javascript without a build system" +[#]: via: "https://jvns.ca/blog/2023/02/16/writing-javascript-without-a-build-system/" +[#]: author: "Julia Evans https://jvns.ca/" +[#]: collector: "lkxed" +[#]: translator: " " +[#]: reviewer: " " +[#]: publisher: " " +[#]: url: " " + +Writing Javascript without a build system +====== + +Hello! I’ve been writing some Javascript this week, and as always when I start +a new frontend project, I was faced with the question: should I use a build +system? + +I want to talk about what’s appealing to me about build systems, why I +(usually) still don’t use them, and why I find it frustrating that some +frontend Javascript libraries require that you use a build system. + +I’m writing this because most of the writing I see about JS assumes that +you’re using a build system, and it can be hard to navigate for folks like me +who write very simple small Javascript projects that don’t require a build +system. + +#### what’s a build system? + +The idea is that you have a bunch of Javascript or Typescript code, and you +want to translate it into different Javascript code before you put it on your +website. + +Build systems can do lots of useful things, like: + +- combining 100s of JS files into one big bundle (for efficiency reasons) +- translating Typescript into Javascript +- typechecking Typescript +- minification +- adding polyfills to support older browsers +- compiling JSX +- treeshaking (remove unused JS code to reduce file sizes) +- building CSS (like [tailwind][1] does) +- and probably lots of other important things + +Because of this, if you’re building a complex frontend project today, probably you’re using a build system like webpack, rollup, esbuild, parcel, or vite. + +Lots of those features are appealing to me, and I’ve used build systems in the past for some of these reasons: [Mess With DNS][2] uses `esbuild` to translate Typescript and combine lots of files into one big file, for example. + +#### the goal: easily make changes to old tiny websites + +I make a lot [of][3][small][4][simple][5][websites][6], I have approximately 0 maintenance energy for any of them, and I change them very infrequently. + +My goal is that if I have a site that I made 3 or 5 years ago, I’d like to be able to, in 20 minutes: + +- get the source from github on a new computer +- make some changes +- put it on the internet + +But my experience with build systems (not just Javascript build systems!), is +that if you have a 5-year-old site, often it’s a huge pain to get the site +built again. + +And because most of my websites are pretty small, the _advantage_ of using a +build system is pretty small – I don’t really need Typescript or JSX. I can +just have one 400-line `script.js` file and call it a day. + +#### example: trying to build the SQL playground + +One of my sites (the [sql playground][5]) uses a build system (it’s using Vue). I last edited that project 2 years ago, on a different machine. + +Let’s see if I can still easily build it today on my machine. To start out, we have to run `npm install`. Here’s the output I get. + +``` +$ npm install +[lots of output redacted] +npm ERR! code 1 +npm ERR! path /Users/bork/work/sql-playground.wizardzines.com/node_modules/grpc +npm ERR! command failed +npm ERR! command sh /var/folders/3z/g3qrs9s96mg6r4dmzryjn3mm0000gn/T/install-b52c96ad.sh +npm ERR! CXX(target) Release/obj.target/grpc/deps/grpc/src/core/lib/surface/init.o +npm ERR! CXX(target) Release/obj.target/grpc/deps/grpc/src/core/lib/avl/avl.o +npm ERR! CXX(target) Release/obj.target/grpc/deps/grpc/src/core/lib/backoff/backoff.o +npm ERR! CXX(target) Release/obj.target/grpc/deps/grpc/src/core/lib/channel/channel_args.o +npm ERR! CXX(target) Release/obj.target/grpc/deps/grpc/src/core/lib/channel/channel_stack.o +npm ERR! CXX(target) Release/obj.target/grpc/deps/grpc/src/core/lib/channel/channel_stack_builder.o +npm ERR! CXX(target) Release/obj.target/grpc/deps/grpc/src/core/lib/channel/channel_trace.o +npm ERR! CXX(target) Release/obj.target/grpc/deps/grpc/src/core/lib/channel/channelz.o +``` + +There’s some kind of error building `grpc`. No problem. I don’t +really need that dependency anyway, so I can just take 5 minutes to tear it out +and rebuild. Now I can `npm install` and everything works. + +Now let’s try to build the project: + +``` +$ npm run build + ? Building for production...Error: error:0308010C:digital envelope routines::unsupported + at new Hash (node:internal/crypto/hash:71:19) + at Object.createHash (node:crypto:130:10) + at module.exports (/Users/bork/work/sql-playground.wizardzines.com/node_modules/webpack/lib/util/createHash.js:135:53) + at NormalModule._initBuildHash (/Users/bork/work/sql-playground.wizardzines.com/node_modules/webpack/lib/NormalModule.js:414:16) + at handleParseError (/Users/bork/work/sql-playground.wizardzines.com/node_modules/webpack/lib/NormalModule.js:467:10) + at /Users/bork/work/sql-playground.wizardzines.com/node_modules/webpack/lib/NormalModule.js:499:5 + at /Users/bork/work/sql-playground.wizardzines.com/node_modules/webpack/lib/NormalModule.js:356:12 + at /Users/bork/work/sql-playground.wizardzines.com/node_modules/loader-runner/lib/LoaderRunner.js:373:3 + at iterateNormalLoaders (/Users/bork/work/sql-playground.wizardzines.com/node_modules/loader-runner/lib/LoaderRunner.js:214:10) + at iterateNormalLoaders (/Users/bork/work/sql-playground.wizardzines.com/node_modules/loader-runner/lib/LoaderRunner.js:221:10) + at /Users/bork/work/sql-playground.wizardzines.com/node_modules/loader-runner/lib/LoaderRunner.js:236:3 + at runSyncOrAsync (/Users/bork/work/sql-playground.wizardzines.com/node_modules/loader-runner/lib/LoaderRunner.js:130:11) + at iterateNormalLoaders (/Users/bork/work/sql-playground.wizardzines.com/node_modules/loader-runner/lib/LoaderRunner.js:232:2) + at Array. (/Users/bork/work/sql-playground.wizardzines.com/node_modules/loader-runner/lib/LoaderRunner.js:205:4) + at Storage.finished (/Users/bork/work/sql-playground.wizardzines.com/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:43:16) + at /Users/bork/work/sql-playground.wizardzines.com/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:79:9 +``` + +[This stack overflow answer][7] suggests running `export NODE_OPTIONS=--openssl-legacy-provider` to fix this error. + +That works, and finally I can `npm run build` to build the project. + +This isn’t really that bad (I only had to remove a dependency and pass a slightly mysterious node option!), +but I would rather not be derailed by those build errors. + +#### for me, a build system isn’t worth it for small projects + +For me, a complicated Javascript build system just doesn’t seem worth it for +small 500-line projects – it means giving up being able to easily update the +project in the future in exchange for some pretty marginal benefits. + +#### esbuild seems a little more stable + +I want to give a quick shoutout to esbuild: I [learned about esbuild in 2021][8] and used for a project, and +so far it does seem a more reliable way to build JS projects. + +I just tried to build an `esbuild` project that I last touched 8 months ago on +a new computer, and it worked. But I can’t say for sure if I’ll be able to +easily build that project in 2 years. Maybe it will, I hope so! + +#### not using a build system is usually pretty easy + +Here’s what the part of [nginx playground][6] code that imports all the libraries looks like: + +``` + + + + + + + +``` + +This project is also using Vue, but it just uses a `