Sunday, September 17, 2017

Node process object made available to browser client code

Leave a Comment

I'm trying to understand how webpack uses DefinePlugin. I have:

new webpack.DefinePlugin({   'process.env.NODE_ENV': JSON.stringify('development'), }), 

and a function:

export const foo = () => {   console.log(process)   console.log(process.env.NODE_ENV) } window.foo = foo 

when I print foo, I see the following in my browser console:

ƒ foo() {   console.log(process);   console.log("development"); } 

It seems like the variable "development" was injected while webpack was compiling the input file. At the same time webpack also injected the process object into the JavaScript code, and the browser did print out the process object when foo was called:

{title: "browser", browser: true, env: {…}, argv: Array(0), nextTick: ƒ, …} 

My question is, how can the process object, which is a Node concept, be made available to the browser?

In fact, if I do:

window.process = process 

I can use process.nextTick right inside the browser console! I thought the nextTick function was a Node-specific implementation! Could anybody explain this?

Thank you!

2 Answers

Answers 1

As mentioned here https://webpack.js.org/configuration/node/#node-process, the webpack can make polyfills for different node functions, but it appears as the node.process is a "mock";

"mock": Provide a mock that implements the expected interface but has little or no functionality.

Have you tested it to see if it actually works? It might just be an empty shell.

If it works I assume that the plugin actually uses something like node-process as shown in this blog-post: http://timnew.me/blog/2014/06/23/process-nexttick-implementation-in-browser/

Copied from that blogpost:

process.nextTick = (function () {     var canSetImmediate = typeof window !== 'undefined'     && window.setImmediate;     var canPost = typeof window !== 'undefined'     && window.postMessage && window.addEventListener;     if (canSetImmediate) {         return function (f) { return window.setImmediate(f) };     }     if (canPost) {         var queue = [];         window.addEventListener('message', function (ev) {             var source = ev.source;             if ((source === window || source === null) && ev.data === 'process-tick') {                 ev.stopPropagation();                 if (queue.length > 0) {                     var fn = queue.shift();                     fn();                 }             }         }, true);         return function nextTick(fn) {             queue.push(fn);             window.postMessage('process-tick', '*');         };     }     return function nextTick(fn) {         setTimeout(fn, 0);     }; })(); 

It is a bit hard to know for sure from the info you provided. If it truly works I think it is very likely you have Browserify enabled in your node app. Perhaps you find some of what you need here: https://webpack.js.org/loaders/transform-loader/#src/components/Sidebar/Sidebar.jsx

Hopefully you find this answer somewhat helpful.

The bottom line is that I believe it is a polyfill from somewhere.

Answers 2

I am going to assume you are experimenting with this on your local webpack dev server and not in your production build. Webpack dev server utilizes websockets for real time communication between the underlying node processes and the front-end bundle. If you wanted to utilize this in a production environment you would need to set up a socket between your front end JS and your node instance to send commands. From a security perspective it sounds like a nightmare, but may have some valid use cases.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment