citizen conn
citizen conn

Reputation: 15390

Define globals when bundling to umd or commonjs

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

Answers (1)

user2065736
user2065736

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

Related Questions