Working on this project - uhop/tape-six GitHub Wiki

This project uses git submodules, so the correct way to get it is:

git clone --recursive [email protected]:uhop/tape-six.git
cd tape-six

For older versions of git:

git clone [email protected]:uhop/tape-six.git
cd tape-six
git submodule update --init --recursive

Don't forget to install dependencies and run a build:

npm install
npm run build

Details

When this project started (circa 2020), ES6 modules were still in their infancy — surprising given that they had been around for about 5 years. To wit: ES6 In Depth: Modules written in 2015.

Even if we disregard for a moment CommonJS modules and consider just ES6 ones, modules that happily work on Node fail in browsers and vice versa. While Node relies on a local repository of dependencies created by npm and has a notion of a package, which can be delivered, unpacked, and installed, browsers have no such infrastructure. They rely on canonical URLs meaning that someone who publishes a package should take care of serving them using HTTP. It brings forward a multitude of well-known issues:

  • Uptime: availability.
  • Bandwidth: it should be fast.
    • (Pre)compression.
  • Geographic distribution.
  • And more...

Alternatively, all dependent packages should be copied and served locally. Unfortunately, it doesn't solve the problem of libraries: if a library has dependencies, developers should know them recursively to copy and arrange properly. Likely a source code should be modified locally to accommodate the placement of referred dependencies. It breaks updating/upgrading that dependencies and introduces too much burden on developers.

Of course, there are solutions specifically for browsers: npm + webpack + babel or similar toolchains. While they clearly work, they require a complicated setup, and introduce even more dependencies with their hell: constant security warnings, updates, upgrades, deprecations, not supporting new versions of other tools, and so on. They make life hard for simple things. Like running a test.

Internally tape-six uses files from deep6. I wanted tape-six to be used in browsers without requiring transpilers, bundlers, or any other tools. That's why I decided to use a time-tested technique of git submodules. Yet, because I provide modules transpiled to CommonJS, so you don't have to do it, I have to transpile the dependency (deep6) selectively.

So I decided to do the following:

  • The only dependency is a git submodule outside of a source tree.
    • Submodule controls what version of the dependency we use.
  • I copy relevant files from deep6/src to a separate directory in a source tree.
  • That directory is excluded from saving in the git repository (.gitignore).
  • Files in this directory are referred by sources.
  • When I run the CommonJS conversion, all files, including the dependency, are converted properly.

The second step (copying files from a submodule to the source tree) is done by a small utility scripts/copyFolder.js, which is used as a part of "build". Hence npm run build.