2016-12-15

Fetch from Browsers with System.js

The Fetch API does indeed work great from older browsers like Internet Explorer 10 with the help of the standard polyfills. I was able to compile the TypeScript tests for both the browser and Node.js and run them with the respective Mocha test runners. Here is the output from Internet Explorer 11 in IE 10 mode.


The same tests run fine on Node.js too.


The code is all in a fetch-from-browsers branch that you can take a look at or clone:

git clone https://github.com/ctaggart/blog.git --branch fetch-from-browsers --single-branch fetch-from-browsers

Packages

Here are the npm packages I used. I coded it using Visual Studio Code.

install.sh

In Browser

I setup added the polyfills the module loader, SystemJS, to load a tests.html page:

tests.html

I configured TypeScript to pick up the Promise API scripts from its ES6 lib definitions and the Fetch API from the @types/whatwg-fetch package. I had it target ES5 when building for browsers.

tsconfig.json

I figured out how to configure SystemJS so that Mocha, Chai and the tests load and run. There are two mocha.js files. This is the one for browsers. The lib/mocha.js is for Node.js.

tests.ts

To run the tests, I simply opened my browsers to http://127.0.0.1:8080/tests.html after starting `http-server`.

On Node.js

I made the mistake of trying to use SystemJS on Node.js to begin with. Don't. "SystemJS is a browser loader first and foremost." It isn't meant for Node.js. I couldn't get the lib/mocha.js to load because it required other modules in a way that SystemJS doesn't support. You can't currently configure SystemJS to fall back to the nodeRequire implementation for certain modules, unfortunately.

The simple solution that worked was to create a "node" subdirectory with its own tsconfig.json. This allowed VSCode to work right and the project can be compiled easily with `tsc -p node` and target the CommonJS module loader used by Node.js.

node/tsconfig.json

The test runner simply loads the fetch dependency from node-fetch before running.

node/tests.ts