Hi,
I'm using pino in the browser, in an Angular 7 app that's built with ng build (which uses webpack under the hood). It builds fine, but when I run the application and want to log something, I get this error:
Uncaught ReferenceError: global is not defined
at Object.../node_modules/pino/browser.js (vendor.js:197635)
This is the line it points to: var _console = global.console || {}
I could work around this by using a hack like window.global = window or something. But I'm sure there must be a cleaner way. Am I missing something? Is there a setting I should be using?
Thanks!
Johannes
We are not really Angular users.
The browser implementation worked well for some time, but it's definitely possible to improve it. Would you like to send a PR to fix this?
from a technically pure perspective we should change it to globalThis https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis
but ie/edge don't support it (of course.)
if we remove global it will break node based tests. Also if we just change it to window that limits possibilities of web worker logging (self). The globalthis polyfill on npm looks like it will add a lot of payload weight.
So I think we should @mathiasbynens outrageous polyfill from https://mathiasbynens.be/notes/globalthis:
(function() {
if (typeof globalThis === 'object') return;
Object.defineProperty(Object.prototype, '__magic__', {
get: function() {
return this;
},
configurable: true
});
__magic__.globalThis = __magic__;
delete Object.prototype.__magic__;
}());
Although I would do it like this:
function polyfillGlobalThis () {
if (typeof globalThis !== 'undefined') return globalThis
Object.defineProperty(Object.prototype, 'globalThis', {
get: function () {
delete Object.prototype.globalThis
this.globalThis = this
},
configurable: true
})
return globalThis
}
just to make it clear: polyfillGlobalThis will both return and set globalThis in the global scope
The fact we return globalThis is what triggers the getter which is what triggers the setting of .. the global.. globalThis. It's absolutely wild.
+1 for the approach
@mcollina @davidmarkclements Thank you guys for working on this so quickly! Awesome!
馃憤 thanks for reporting :D
In case, if your target is node in webpack (target: 'node'), because you want to fix "Can't resolve 'fs'. Then you're getting the following error Fix: "Uncaught ReferenceError: global is not defined" do it as follows node: { global: true, fs: 'empty' }. Bonus: if you got error "Uncaught ReferenceError: exports is not defined". simply add libraryTarget: 'umd'. The complete webpack config code is below.
const webpackConfig = {
node: { global: true, fs: 'empty' }, // Fix: "Uncaught ReferenceError: global is not defined", and "Can't resolve 'fs'".
output: {
libraryTarget: 'umd' // Fix: "Uncaught ReferenceError: exports is not defined".
}
};
module.exports = webpackConfig; // Export all custom Webpack configs.
Most helpful comment
from a technically pure perspective we should change it to
globalThishttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThisbut ie/edge don't support it (of course.)
if we remove
globalit will break node based tests. Also if we just change it towindowthat limits possibilities of web worker logging (self). The globalthis polyfill on npm looks like it will add a lot of payload weight.So I think we should @mathiasbynens outrageous polyfill from https://mathiasbynens.be/notes/globalthis:
Although I would do it like this: