Can't use mockttp in the browser without a CommonJS bundler
In the Readme, you have an in-depth tutorial that gives an example of the browser code in the format const mockttp = require('mockttp').getLocal(); which would work in Node.js but not in Chrome.
I know that AMD works in the browser, but the commonJS fashion of var = require('package') isn't browser-friendly. The guide shows that the browser and nodeJS code are of the same kind.
Is there a way to load commonJS properly in a browser like that? RequireJS vomits when I attempt that. Or can I simply rebuild the project to AMD?
What's missing?
Ah, yes, right now it's not built for AMD I'm afraid.
Building for Common JS like this means it works out of the box in both Node & with tools like Webpack/Browserify/Parcel/etc, but no, not with RequireJS (which, to be fair, has rather fallen out of popularity in recent years). You can see an example of this in Mockttp's tests if you're interested: within the Karma config there's an embedded webpack configuration, which both compiles all the TS, and bundles all required CommonJS modules into something that'll run in a browser en route.
Adding built-in AMD support is harder to do than you'd think I'm afraid. It's very easy to get TypeScript to output AMD code, but Mockttp itself requires various other modules internally, and you'd need all of them to be AMD-compatible as well, and their dependencies too, and for all of that to consistently use module identifiers throughout that will resolve happily with your final downstream require config too.
Imo, the easiest solution to all that would be to define a single prebuilt browser bundle here, which uses webpack or similar to bundle up all the necessary dependencies into one single UMD file, which anybody not using a CommonJS-capable build tool can use. Would that solve your problems? I'm unlikely to get to that soon myself, but I'd happily accept a PR to do so.
I see you originally posted this with an error where Mockttp wasn't building too btw. I assume you've fixed that - out of interest, what was the issue? If there's any extra steps that it would've been useful to have in the readme to get you started, just let me know.
Ah. Yes, for commonJS to work in any form, I'd need all the modules downloaded before the require calls are run. I have not learned Webpack yet.
I was trying to build it with AMD, but then I saw that its dependencies didn't afford me the opportunity to compile them to AMD - they shipped in commonJS. So I saw what you are saying.
I could venture into webpack. See if I can set up a bundled script.
Well, I had typescript errors, but I noticed they were based on missing modules, so I made sure then to npm install.
At first, I was trying to build it from a node_modules folder int he project for which I wish to use it, but then I noticed among other things, that the npm install mockttp didn't copy over tsconfig.json among others. So I cloned it into its own folder and once I made sure to install typescript and rimraf and run an npm install, it worked.
-
note for requiring a full clone of mockttp
-
Note for npm install -g rimraf typescript
-
Note for regular npm install
-
Note for npm run build
(If you would believe, at my company, I work on an advertising web player, and to keep size down I use plain old file concatenation. AMD adds a lot of fluff for all its niceties)
Ok, sounds like a plan! Let me know if you have any questions.
Yes, you'll need to npm install first. You shouldn't need to separately install typescript or rimraf I think - a single npm install should give you everything.
I've worked in those kind of environments too. Simple tools like that can be useful sometimes, but they do get limiting once you start trying to do anything more complicated.
I got a bundle built with this command
mxp-sea-0261:mockttp cthomas$ webpack-cli --entry ./dist/main-browser.js --output lib/mockttp-browser.js --mode development
I had to modify main-browser.ts to have a creation of window.Mockttp = {} with the getLocal, getRemote, and getStandalone functions attached to it though. It doesn't have anything fancy to tie it down to AMD or another module framework.
function getLocal(options: MockttpOptions = {}): Mockttp { return new MockttpClient(options); }
function getRemote(options: MockttpOptions = {}): Mockttp { return new MockttpClient(options); }
function getStandalone(options: any = {}): never { throw new Error('Cannot set up a standalone server within a browser'); }
declare global { interface Window { Mockttp: any; } }
window.Mockttp = window.Mockttp || {};
window.Mockttp.getLocal = getLocal; window.Mockttp.getRemote = getRemote; window.Mockttp.getStandalone = getStandalone;
Nice! That looks promising.
You should be able to get webpack to generate those last bits itself for you too. Take a look at https://webpack.js.org/configuration/output/#output-librarytarget. I've never tried it, but in principle you can build with libraryTarget: 'umd' in your config and it should work out how to create a UMD module that'll automatically work with AMD, CommonJS or global variables, depending on the environment.