Packaging SaxonJS for the browser

By Norm Tovey-Walsh on August 16, 2024 at 03:20p.m.

Over the years, there have been several requests to improve the way that SaxonJS is packaged for the browser. In the run up towards SaxonJS 3.0 (real soon now, I promise), I’ve spent a few hours trying to see if that’s possible.

For SaxonJS on Node.js, things seem to be working the way users expect. You can install SaxonJS, and xslt3.js, the command-line XSLT processor, with npm install. Then you can use them as you would other Node.js modules and applications.

For the browser, things are a little less clear.

I’ll start out by observing that SaxonJS is a large(ish) collection of mostly plain JavaScript files. There are a mixture of techniques used, as you might expect from a code base that stretches back seven or eight years (roughly ∞ in JavaScript years). This code is compiled by the Closure Compiler to produce the release artifacts.

Aside: Producing TypeScript instead of JavaScript is almost certainly impractical. And the answer to the question, “can you make it an ESM module?” appears to be “no”. But maybe I’m wrong?

Almost anything is possible in software, but there some things are probably impractical because of how SaxonJS is built.

What I’ve come to realize after several hours is that I don’t actually understand what problem I’m trying to solve. That usually makes problems harder.

For example, it would be easy to package the browser versions of the SaxonJS libraries into the saxon-js npm package. That would allow you to use npm install to install it. Once installed, you could refer to it in HTML like this:

<script src="node_modules/saxon-js/SaxonJS3.rt.js"></script>

That’s a non-zero usability improvement over downloading the browser release yourself and adding it to your project, but it’s an awfully small improvement. So small, that I conjecture that the request to “put it in the npm package” means more than that. But I don’t know what more.

Another request that’s come up a couple of times is whether we should provide a version that’s been packaged up with webpack. Well. Okay. I spent a bit of time on that and eventually I managed to get

npx webpack --config webpack.config.js

to take src/SaxonJS3.js, chew on it for a while, and produce dist/SaxonJS3.js. That was a little, uh, underwhelming. I started with a JavaScript library that I could load in the browser and ended with…a different one, I guess?

Then there are suggestions that instead of webpack I should be trying vite or bun or something else and do I also need browserify? I don’t know. I’m about to give up, at least in the short term, but before I do, I thought I’d see if anyone out there can tell me what I’m missing.

If you would like to see SaxonJS for the browser packaged up in some different way, can you tell me how? And why? A small test case would be ideal: something that isn’t too complicated, that doesn’t work with SaxonJS as it’s distributed today, that would work if we packaged it in some other way.