4 ms·
YavaScript: Write shell scripts in JavaScript/TS instead of bash
- suchipi 3y agoI've been working on this project for a while, and it's still early days, but I've made a tiny (~3MB) custom cross-platform JavaScript runtime (not Node.js) which excels in places where you might normally use bash scripts (dev tooling, CI, etc). It's good at: - Manipulating files and data - Manipulating path strings - Running child processes and getting their stdout/stderr/etc - Fetching data over http(s) - Expanding globs - Working with environment variables - Printing styled text And it also has builtin bindings for common low-level POSIX C APIs like fputs, sprintf, isatty, strftime, etc. It's written in a combination of C and TypeScript, and targets Linux (both gnu and musl), macOS, and Windows. arm64 is supported on Linux and macOS. Your shell scripts can be written in JavaScript, JSX, TypeScript, TSX, CoffeeScript, or Civet. It's published on npm, Docker Hub, and GitHub releases. It supports the ES2020 standard with some newer ECMAScript features too, and a couple proposals (like String.dedent). It has native ESM/CommonJS interop without .mjs, can fetch packages from npm via the `npm:` package prefix, and the pragmas for its builtin JSX syntax parsing can be reconfigured on-the-fly. You can register your own import extension handlers and import resolver logic, and you can also mix and match ESM-isms (like import, import.meta.url, import.meta.resolve) with CJS-isms (require, __filename, require.resolve) in the same file with no problems. What do you think?
- throwaway888abc 3y agoWill check later. Looks similar to ZX (https://google.github.io/zx/getting-started https://google.github.io/zx/getting-started). Thanks
- suchipi 3y agoMain differences from zx: - YavaScript is waaaay smaller. zx and its dependencies are 16.3MB, and they depend on Node.js, which is 156MB. zx also requires a local node_modules folder which can be inconvenient in some cases. YavaScript is a single ~3MB file with no external dependencies. - YavaScript isn't based on Node.js; it uses a custom QuickJS-based engine for code execution. This allows it to hook deeper into the engine for additional features (like builtin support for TypeScript), and also means it is wayyy smaller. - YavaScript's APIs are generally synchronous, whereas zx's APIs are generally asynchronous. I did this because I believe synchronous APIs are more similar to normal shell scripting, and because peppering `await` everywhere feels silly when the script is going to execute things serially 95% of the time. There are still asynchronous APIs available in YavaScript, though, including Web Workers.
- jauntywundrkind 3y agoThe size equation is definitely different if you do/don't have nose.js installed & in your package cache. But for many devs that use this stuff anyhow, with some of the modern package manager techniques especially (as pioneered by yarn), the size isn't really a big penalty. Zx also does not require a node_modules folder at time of use. There is an --install option to avoid having to pre-install dependencies. https://google.github.io/zx/cli#install https://google.github.io/zx/cli#install There's the old shell.js, from Mozilla originally, which too was mostly synchronous. It has a bit of an impact for a while, but the lack of async support was, over the long term, imo, it's doom.
- jauntywundrkind 3y agoI really love writing with zx. https://github.com/google/zx https://github.com/google/zx We have some folks who have gone wild copy-pasting random fancy bash snippets into various developer helpers scripts. Zx did like 90% of that stuff out of the box, without being a pile of chaotic custom bash.