mithril.js: public API should not rely on presence of `window`

Description:

If I use mithril (1.0) serverside (mithril-node-render) it complains about undefined variable window

Steps to Reproduce:

create a file

// test.js
const m = require('mithril')

run it with

> node test.js

Expected:

It should not throw any errors.

Actual:

/Users/sh/Work/OS/mithril-node-render/node_modules/mithril/render.js:1
(function (exports, require, module, __filename, __dirname) { module.exports = require("./render/render")(window)
                                                                                                          ^

ReferenceError: window is not defined
    at Object.<anonymous> (/Users/sh/Work/OS/mithril-node-render/node_modules/mithril/render.js:1:107)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/sh/Work/OS/mithril-node-render/node_modules/mithril/index.js:4:21)
    at Module._compile (module.js:541:32)

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 4
  • Comments: 18 (17 by maintainers)

Commits related to this issue

Most upvoted comments

Here’s what I just did for our similar-to-node-but-not-exactly-the-same SSJS framework.

var m;

// Polyfill DOM env for mithril
global.window = require("mithril/test-utils/browserMock.js")();
global.document = window.document;

// Require the lib AFTER THE POLYFILL IS UP
m = require("mithril");

// Make available globally for client scripts running on the server
global.m = m;

// Export for normal server usage
module.exports = m;

Yes, it’s a bit silly but I don’t see an obvious alternative currently.

Is that a good way to go though? Having a mock window can trip some libraries up; this method seems to work: https://www.npmjs.com/package/detect-is-node, but still…

@StephanHoyer How will your getting started example for mithril-node-render look then? Will it be this?

require('mithril/test-utils/browserMock')(global);
var m = require('mithril');
var render = require('mithril-node-render');

render(m('span', 'huhu')).then(function (html) {
   	// html === '<span>huhu</span>'
})  

Ie: forced use of the mock?

Other option would be to utilize browser-field. But I don’t know if that’s feasible with the custom bundler. It it would require to have 2 different /render.js one that uses window and one that uses the mock.