localvoid / ivi

Lighweight Embeddable Web UI Library
MIT License
723 stars 22 forks source link

Any working SSR example #8

Closed katyo closed 5 years ago

katyo commented 5 years ago

I tried to render app as html string, but it seems the server-side rendering not fully supported at this moment.

(global as any).__IVI_DEBUG__ = true;
(global as any).__IVI_TARGET__ = "ssr";

import {writeFileSync} from 'fs';
import {renderToString} from 'ivi';
import {main} from './main';

writeFileSync('dist/client.html', renderToString(main()));

I get an error which means that it still requires browser environment despite of actual __IVI_TARGET__ value:

node_modules/ivi/src/dom/feature_detection.ts:38
  KeyboardEvent.prototype.hasOwnProperty("key")
  ^
ReferenceError: KeyboardEvent is not defined

The KeyboardEvent proto usually defined by DOM API which is missing in Node or any other server environment.

Of course, I can import KeyboardEvent from jsdom package or create myself, but I think this is completely wrong way.

localvoid commented 5 years ago

but I think this is completely wrong way

Yes, it should work without jsdom.

The ideal solution would be to completely separate browser-specific code into a separate package, but the main issue with this approach is that it will be hard to write custom attribute directives, so I've decided to rely on global variables and use bundlers/minifiers with dead code elimination to produce optimized output for node.js that removes feature detection/runtime checks/etc. But it should also work without bundlers/minifiers and I've published 0.21.1 that fixes this issues, here is an example: https://github.com/localvoid/ivi-examples/tree/3da4c7db883b4249698ac18a4c728352bb98b679/packages/tutorial/08_ssr

Also, right now there is no hydration. I can implement it, but I am not sure that it is worth to use hydration and in many use cases it is better to just remove all dom nodes and rerender everything.

katyo commented 5 years ago

Thanks! It works fine now