Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node process object made available to browser client code

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!

like image 505
platypus Avatar asked Sep 05 '17 19:09

platypus


People also ask

What is the process object in a node js program?

The process object in Node. js is a global object that can be accessed inside any module without requiring it. There are very few global objects or properties provided in Node. js and process is one of them.

Can you run NodeJS code in browser?

Thanks to some creative engineers, it is now feasible to use Node. js modules in browsers, but not directly. Being able to call Node. js modules from JavaScript running in the browser has many advantages because it allows you to use Node.

What is process env browser?

The process. env global variable is injected by the Node at runtime for your application to use and it represents the state of the system environment your application is in when it starts. For example, if the system has a PATH variable set, this will be made accessible to you through process.

Does node js have the same objects as browser based js?

Both the browser and Node. js use JavaScript as their programming language. Building apps that run in the browser is a completely different thing than building a Node. js application.


1 Answers

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.

like image 138
Automatico Avatar answered Oct 14 '22 05:10

Automatico