Reputation: 15390
I have a client-side application which makes use of some browser global properties like Element
or document
.
I'd like to run my application in node.js as well and currently I am overriding those globals with the domino dom implementation in my server like so:
const domino = require("domino");
const domimpl = domino.createDOMImplementation();
const document = domimpl.createHTMLDocument();
Object.assign(global, Element: domino.impl.Element, document};
const myApp = require('my-app');
I am currently using rollup to bundle different versions of my-app
, how can I have rollup do this for me automatically for the _server
version of my-app
so consumers of my-app
don't have to do that?
I was thinking of writing my own rollup plugin but I feel like overriding globals seems like a common practice.
Upvotes: 4
Views: 658
Reputation:
TLDR; Use separate entry file instead of a rollup plugin.
Simply add the following instead of a rollup plugin
if (typeof window ==== "undefined") {
const domino = require("domino");
const domimpl = domino.createDOMImplementation();
const document = domimpl.createHTMLDocument();
Object.assign(global, Element: domino.impl.Element, document};
}
// my-app code
You might be worried about domino
entering client side code. To fix this, use separate bundles for server and client, wrap the above mocking code in a separate file and use the following in your my-app
’s main file meant for the server bundle, an approach similar to how React ships production and development bundles - conditional imports.
Server main file
require(‘./globals-mocking’);
// my-app client code
Client main file
// my-app client code only
package’s main file
if (SERVER_ONLY) {
module.exports = require('./my-app-server.js');
} else {
module.exports = require('./my-app-client.js');
}
Use rollup's replace plugin and define SERVER_ONLY
(https://github.com/rollup/rollup-plugin-replace#usage) for server entry only. If you use UglifyJS or simlilar tool that eliminates dead code, you wont have domino
and duplicated server code.
EDIT: Noticed a minor issue. Condition should be if (SERVER_ONLY) {
. Use the following definition along with it for the server entry file.
plugins: [
replace({
SERVER_ONLY: JSON.stringify(true)
})
]
Upvotes: 2