Skip to content

Commit

Permalink
added: domGlobals and a bit more documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
GianlucaGuarini committed Aug 3, 2021
1 parent 6c8cbfb commit ec0796c
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 9 deletions.
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,48 @@ import render from '@riotjs/ssr'
const html = render('html', MyRootApplication)
```

### Better SSR control using the createRenderer

For a better control over your HTML rendering you might want to use the `createRenderer` factory function.
This method allows the creation of a rendering function receiving the `{getHTML, css, dispose, element}` option object.
- `getHTML`: give you the rendered html of your component as string
- `css`: the css of your component as string
- `dispose`: clean the memory used on the server needed to render your component
- `element`: the component instance you are mounting

For example

```js
import { createRenderer } from '@riotjs/ssr'

const logRendrer = createRenderer(({getHTML, css, dispose, component}) => {
const html = getHTML()

console.log('Rendering the component: %s', component.name)

dispose()
return { html, css }
})
```

### DOM Globals

`@riotjs/ssr` needs DOM globals (like `window`, `document` ...) to properly render your markup.
With the `domGlobals` exported object you can decide manually when the globals should be created and deleted from in your node applications.

```js
import { domGlobals } from '@riotjs/ssr'

domGlobals.create()

// global DOM object in your node environement are now defined
console.log(global.window, global.document)

// they will be cleared and will be undefined
domGlobals.clear()
```


#### Caveat

If you are rendering your whole HTML you will not be able to use multiple times the inline `<script>` `<style>` tags.
Expand Down
14 changes: 10 additions & 4 deletions src/dom.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import {parseHTML} from 'linkedom'

export function setup() {
export function create() {
// no need to recreate globals
if (global.window && global.document && global.Node) {
return
}

const {
window,
document,
Expand All @@ -12,11 +17,12 @@ export function setup() {
global.Node = Node
}

export function dispose() {
if (global.window === undefined) {
export function clear() {
if (!(global.window && global.document && global.Node)) {
return
}

global.window = undefined
global.document = undefined
global.Node = undefined
}
}
7 changes: 4 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function createRenderer(
componentAPI,
props = {}
) {
dom.setup()
dom.create()

const isRootNode = tagName === 'html'
const root = document.createElement(tagName)
Expand All @@ -51,7 +51,7 @@ export function createRenderer(
})
const dispose = () => {
// clear global scope
dom.dispose()
dom.clear()
// unmount the component
element.unmount()
// remove the old stored css
Expand Down Expand Up @@ -127,9 +127,10 @@ const renderComponentAsync = curry((renderer, rendererPayload) => {
})

export const asyncRenderTimeout = 3000
export const domGlobals = dom
export const renderAsync = curry(createRenderer)(renderComponentAsync(getOnlyHTMLFromRenderer))
export const renderAsyncFragments = curry(createRenderer)(renderComponentAsync(getFragmentsFromRenderer))
export const fragments = curry(createRenderer)(getFragmentsFromRenderer)
export const render = curry(createRenderer)(getOnlyHTMLFromRenderer)

export default render
export default render
22 changes: 20 additions & 2 deletions test/core.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const register = require('../register')
const {expect} = require('chai')
const ssr = require('../')
const render = ssr.default
const { renderAsync, renderAsyncFragments, fragments, asyncRenderTimeout } = ssr
const { renderAsync, renderAsyncFragments, fragments, asyncRenderTimeout, domGlobals } = ssr

describe('ssr', () => {
let unregister // eslint-disable-line
Expand All @@ -15,6 +15,24 @@ describe('ssr', () => {
unregister()
})

it('creates and deletes globals properly', function() {
expect(global.window).to.be.not.ok
expect(global.document).to.be.not.ok
expect(global.Node).to.be.not.ok

domGlobals.create()

expect(global.window).to.be.ok
expect(global.document).to.be.ok
expect(global.Node).to.be.ok

domGlobals.clear()

expect(global.window).to.be.not.ok
expect(global.document).to.be.not.ok
expect(global.Node).to.be.not.ok
})

it('raw components can be rendered', function() {
const SimpleComponent = require('./tags/simple-component.riot').default

Expand Down Expand Up @@ -115,4 +133,4 @@ describe('ssr', () => {
it('does not pollute global scope with dom implementation', function(){
expect(global.window).to.be.undefined
})
})
})

0 comments on commit ec0796c

Please sign in to comment.