mock-server / mockserver-client-node

MockServer javascript client for browsers, Node.js or any grunt build
http://mock-server.com
Apache License 2.0
72 stars 34 forks source link

Using in browser: fs.existsSync is not a function #47

Closed carlobeltrame closed 4 years ago

carlobeltrame commented 4 years ago

Describe the issue When I try to use mockserver-client-node in the browser, I get the error:

fs.existsSync is not a function

This is because the check to distinguish browser from node.js environment does not consider browser bundle build systems (i.e., using require or import in browser-based environments), which is common practice by now.

What you are trying to do I want to use mockserver in Cypress.io end-to-end tests. To dynamically set my mocks depending on the tests I am running, I want to use mockserver-client-node. In Cypress, we can easily require or import CommonJS modules which are then transpiled to run in the browser, but we cannot easily add a script tag to the page.

MockServer version latest (5.11.1)

To Reproduce Steps to reproduce the issue:

  1. I use MockServer in a Docker container, and Cypress with mockserver-client-node installed in another container
  2. Code:
    // In the cypress container in commands.js
    // or, alternatively, in any browser-based JS application that is built with Webpack etc.
    import { mockServerClient } from 'mockserver-client'
    mockServerClient("e2e-mock", 1080)
    .mockAnyResponse({...})
  3. Error message:
    fs.existsSync is not a function
    node_modules/mockserver-client/sendRequest.js:31:1

Expected behaviour I expected the check in https://github.com/mock-server/mockserver-client-node/blob/master/mockServerClient.js#L27 to detect that I am running in a browser and use the XHR-based makeRequest function instead of require('./sendRequest').sendRequest(tls, caCertPemFilePath).

MockServer Log Not relevant, as it doesn't get far enough to talk to MockServer

carlobeltrame commented 4 years ago

"Workaround" is to use the REST API with cy.request, instead of using this package:

cy.request('PUT', 'e2e-mock:1080', {...})
jamesdbloom commented 4 years ago

A PR to fix the check to distinguish browser from node.js environment would be gratefully appreciated. Are you able to provide such a PR or suggest some good code to implement this?

carlobeltrame commented 4 years ago

If you are fine with adding a single dependency, it could be done using the browser-or-node package. I could submit a PR for that.

If you want to do it manually, without a dependency, I could replicate the logic from the package, but I'm not enough of an expert on node.js code to maintain that piece of code.

jamesdbloom commented 4 years ago

Sorry for the slow response, yes your suggestion of using the browser-or-node package sounds good.

OliverJAsh commented 3 years ago

Even though the require('fs') never runs, webpack will still pick it up for bundling, and thus webpack will error because there's no fs module that can be bundled for browser usage. For this reason I think we need to add this to package.json:

"browser": {
  "fs": false
}

As per https://github.com/pugjs/pug-loader/issues/8#issuecomment-328331541.

Until then, we can workaround this with the following webpack config:

node: {
  fs: 'empty',
},