Shumway Shiv: Scant Success
Tags: failure, shumway, flash, webdev
Published: 2019-01-04 13:04:12

---
title: Shumway Shiv: Scant Success
published: true
description: Documented failure to address Flash content on an old website with Mozilla Shumway.
tags: failure, shumway, flash, webdev
cover_image: https://thepracticaldev.s3.amazonaws.com/i/y5ctf3zirva6dd2szxc9.png
---

A little while ago Jermaine Oppong asked {% link https://dev.to/graphicbeacon/what-did-your-first-website-design-look-like-1oj9 %}

My first website, from 1998 to 1999, has quite a bit of Adobe Flash content, mostly used for navigation. I still have a mirror of my first website on the website that replaced it. So people can go back to the old days. Flash is still a bit supported by some browsers, but this will change in the future. So eventually the mirror of my first website is going to become broken.

So I can do a few things:

1. Nothing, and let it eventually die.
2. Recreate the content which is currently in Flash.
3. Try to convert the Flash content in some way.

Obviously #2 is out of the question. It's a mirror of an old site, it exists only for sentimental reasons. Thus I'm going to attempt #3. 


# Mozilla Shumway

Over 6 years ago, when Flash was still actively used on popular websites, Mozilla started the [Shumway project](https://mozilla.github.io/shumway/). Shumway is basically a Flash player written in JavaScript, making use of the latest HTML5 technology. Its main purpose was to work as an extension for Firefox, but it could also be used as standalone script in websites. 

About three years ago development of this project stopped. 


# Enter the Shiv

Despite development of Shumway was stopped it does not make the creation instantly useless. As my old site used Adobe Flash 4 and not the latest and greatest, no fancy or exotic features. Shumway will probably do a good job in rendering the content.

Last week I decided to give it a try. Making a simple JavaScript library which I could inject in my old website and it would replace all embedded Flash movies with Shumway.


# Not a modern front-end developer

I have been playing around with web technology since 1998. But in the past years I have been mostly involved with back-end technology. And not as much with the modern JavaScript front-end technology. But I do know my VanillaJS, and that is all that I need to make my shiv.

Of course I am going to try to use the current front-end technology create this project and package it up. The back-end is not the only place anymore which has powerful build tools.


# NPM, innit!

So where do we start? I want to create a simple single file JavaScript library, bundle it with the Shumway distribution and make a distributable archive of this.

I tried to search around for the best, current, way to start a project like this. I could not find anything useful besides the `npm init` action to create your `project.json` file. I can find loads of other tutorials on how to create a project for a website using some framework or the other. But that is not what I need.


## Where to put my files.

In the Java world we have maven which defines a standard project layout.

* src
   * main
      * java
      * resources
  * test
      * java
      * resources
* target

But I could not find a standard convention for the front-end/NodeJS world. Looking at some JavaScript projects it seems that files are just put wherever the developer wants. 

The only common layout I found was that the main JavaScript file is generally called `index.js` and often tests are put in a `test` directory.


# Dependencies

I only have one non-development dependency: Shumway, and it appears to be in the NPM repo. Perfect! 

But not really. It appears that the dependency in NPM is not the latest version of Shumway. Despite the latest version being 3 years old, an even older version was in the NPM repo.

This little detail cost me a lot of time trying to debug why some Flash movies produce absolutely no result.

So much for being able to use dependency management. Guess I will have to download the latest build of Shumway and store it in some arbitrary directory in my project.


# Testing

Time to test my code. Just open my test HTML file in the browser and ... it does not work. The JavaScript functionality Shumway needs is not allowed to run via de `file://` protocol, so I need to run it in a webserver. 

That cannot be too difficult, just install and start [Serve](https://zeit.co/blog/serve-7). Guess not. 

Serve enforces "clean urls" by default. This means that `http://localhost:5000/test/example` is actually referring to the file `test/example.html`. But for some odd reason they enforce this by also redirecting `http://localhost:5000/test/example.html` to `http://localhost:5000/test/example`. Which would not be a bad thing, except that their redirect code is broken and drops the query part of the location. This behavior breaks the Shumway viewer which expects the Flash file to be loaded as a query parameter. So `"cleanUrls": false` in my `serve.json`.

From my test HTML I link directly to `/src/index.js`, but from that script I expect the Shumway player to have its files in `./shumway-dist/`, so `/src/shumway-dist`. But because these files are not really part of my project's source code they live somewhere else. (Originally they lived in the node_modules directory before I found out about the outdated version.)

Luckily Serve has an option to rewrite the requests to a different location. Documentation on this is rather vague. I would have assumed a simple rewrite like

```json
{ "source": "/src/shumway-dist/**", "destination": "/build/shumway-dist/" }
```

Would rewrite a request for `/src/shumway-dist/foo/bar/quux.js` to `/build/shumway-dist/foo/bar/quux.js`. But that is clearly not the case. I could not figure out a proper single line configuration to rebase a path. So I ended up with this monstrosity:

```json
{ "source": "/src/shumway-dist/:x/:y", "destination": "/build/shumway-dist/:x/:y" },
{ "source": "/src/shumway-dist/:x/:y/:z", "destination": "/build/shumway-dist/:x/:y/:z" }
```

It works, but I am not really happy with it.


# Packaging

The idea of this JavaScript library is that users should be able to simply upload it to their webserver and include a `<script ... >` in the HTML pages which need it. So I want to package my single JavaScript file, and the Shumway distribution files in a single downloadable artifact. This library is not intended to be used as a dependency by other JavaScript packages.

[Webpack](https://webpack.js.org/) sounds like the tool I need to use. 

> webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging ...

I just need to tell it to take my `src/index.js` copy it to `shumway-shiv.js` and copy some files from the `shumway-dist` package. And then produce a nice zip archive which I can upload as a release package.

To do this I apparently need to program more JavaScript, in a configuration file. 

Doing the first part works out of the box. But getting the files from the shumway dist page to the output directory requires me to program the CopyWebpackPlugin. I would not expect to write `new CopyWebpackPlugin(...)` in a configuration file.

To create the ZIP file I had to program the ZIP webpack plugin. It was easy enough, except that I have not figured out how my output zip can also contain the version number as I defined in my package.json.

Running webpack welcomes be with its opinion about the size of files. Yes, Shumway contains some large files. I know, and I am not going to do anything about that. So `performance: { hints: false }`. 

Wait a minute... what is all this stuff in my `shumway-shiv.js`? It's the webpack loader. Despite that this output file only contains a single JavaScript source with no other inlined dependencies that loader is there. I will figure out how to get rid of this later.


# NPM tooling, or lack thereof

I now have Serve to start a test HTTP server, Webpack to package it up (and eslint). But instead calling all these tools manually, I should be able to simply call this from npm right? In the Java world I would simply call `mvn package` to compile, test, and package my project.

But npm appears to lack the concept of building projects. Instead I have to define "scripts" in my package.json which I can then execute with `npm run test`, `npm run package`. But there are no dependencies defined between those scripts.

If I want this, then I should use something like [Grunt](https://gruntjs.com/). Where I again have to program a configuration file. Basically it is the NodeJS equivalent for Java's Ant. (These big JSON files are not really much more readable than XML files.)


# Shiving my Site

Time to upload my new creation and check out how well it works to get my old site with Flash content working on a browser with no Flash.

It kind of works. The Flash content is properly replaced with the Shumway viewer. But the results are less than desired.

* Various links open a new tabs instead of opening in the right frame.
* Mouse-over replacements do not work correctly. The original content is gone, but the new content is not shown.
* Content does not scale to the maximum size. Something which should have been full screen is shown at the original size. Scaling down appears to work, but not scaling up.
* No alignment. Everything is rendered top-left instead of center-center.

The broken mouse-over behavior is quite the deal breaker. All this work, and the end result is not what I really wanted. I could have figured that out sooner if my test case used some Flash movies from the site instead of example from the Shumway project.

I could investigate if somebody else addressed some of the issues in a forked Shumway project. So far look it looks like attempt for *#3 Try to convert the Flash content in some way." has failed.

The result of this experiment is up on my [GitHub](https://github.com/elmuerte/shumway-shim). Any remarks on what I should have done, or should have read, to make this front-end project nicer to work with are welcome in the comments.