Closed Niklas81 closed 5 years ago
I'm running it in a new project I started last week, and so far it works as expected for me. Which issues have you encountered?
I have multiple issues. They aren't all related to mithril-node-render, but still quite blocking.. Knowing it should work helped a bit in itself, though.
On a page that performs a Promise.all and then in the .then runs m.redraw
I get
ReferenceError: requestAnimationFrame is not defined
at Function.redraw (/home/node/app/node_modules/mithril/mithril.js:1326:4)
in server side. I use Axios instead of m.request, which is why I need to run that after data fetching.
I noticed that m.redraw()
is async now, but not sure how to best refactor to adjust to this. Using m.redraw.sync()
, makes it work, but what I can gather from the API this is only intended to make videos work on iOS.. What's the reccomended solution in my case? Does the choice stand between m.redraw.sync()
or process.browser ? m.redraw() : ''
or is there a better solution?
Loading the same page without m.redraw
, the page renders perfectly-server side, but then I have an issue with Mithril itself (or perhaps Webpack when loading module with specific version?) as I get Unhandled promise rejection TypeError: "m is not a function"
.
How can I solve this?
On the Node.js side I include a file with the following content:
// This mocks the browser on Node.js
require('mithril/test-utils/browserMock')(global)
// This is to make m.request work on Node.js, in case you use it
global.window.XMLHttpRequest = require('w3c-xmlhttprequest').XMLHttpRequest
// This is to avoid the requestAnimationFrame error
global.requestAnimationFrame = () => {}
Let me know if it helps.
The route we take is to create a custom server-side m
, since mithril-node-render pretty much only needs hyperscript to run.
// m.js
'use strict'
if (process.browser) {
module.exports = require('mithril')
} else {
module.exports = require('mithril/hyperscript')
module.exports.route = {
get: noop,
param: noop,
}
module.exports.redraw = noop
}
Usage
const m = require('/m.js')
This way you don't have any issues with browser stuff in node. You can also patch this as you like and also ad some custom helper functions like bss
or classnames
.
We use browserify
for bundling. I think this is also possible for other bundlers.
I really like that solution, saves a lot of process.browser conditional statements, and lets more aspects of Mithril be isomorphic. Presumably noop should be defined as () => {}
?
Thank you both! It works well with Webpack as well, the other issue was simply a result of Webpack loading Mithril's .mjs file by default; it was simply a matter of fixing the config.
Is there any way we can run mithril-node-render with Mithril 2.0.0-rc.3? If not now, are you planning to support Mithril 2.0 at some point in the future / when it's not in pre-release?