broadcastchannel-polyfill icon indicating copy to clipboard operation
broadcastchannel-polyfill copied to clipboard

ReferenceError: self is not defined

Open emulienfou opened this issue 4 years ago • 2 comments

Hello, trying to use this package on a React based project, using Next.js framework.

However, I get this error since you are using self but who is not defined:

ReferenceError: self is not defined
    at Object.<anonymous> (/home/david/PhpStorm/davidsanchez.me/node_modules/broadcastchannel-polyfill/index.js:85:4)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)

Do you have a work around to be able to use your package?

Related to this issue here: https://github.com/FormidableLabs/spectacle/issues/868

emulienfou avatar Oct 31 '20 15:10 emulienfou

First, you need to install it: yarn add broadcastchannel-polyfill or npm i broadcastchannel-polyfill Then, You just need to import it like this:

import "broadcastchannel-polyfill";

So, it should be working now.

image

if you had any issue, which it didn't work, so you copy the whole index.js and use it like this in your code(i just add replaced self with window):

(function(global) {
    var channels = [];

    function BroadcastChannel(channel) {
        var $this = this;
        channel = String(channel);

        var id = '$BroadcastChannel$' + channel + '$';

        channels[id] = channels[id] || [];
        channels[id].push(this);

        this._name = channel;
        this._id = id;
        this._closed = false;
        this._mc = new MessageChannel();
        this._mc.port1.start();
        this._mc.port2.start();

        global.addEventListener('storage', function(e) {
            if (e.storageArea !== global.localStorage) return;
            if (e.newValue == null || e.newValue === '') return;
            if (e.key.substring(0, id.length) !== id) return;
            var data = JSON.parse(e.newValue);
            $this._mc.port2.postMessage(data);
        });
    }

    BroadcastChannel.prototype = {
        // BroadcastChannel API
        get name() {
            return this._name;
        },
        postMessage: function(message) {
            var $this = this;
            if (this._closed) {
                var e = new Error();
                e.name = 'InvalidStateError';
                throw e;
            }
            var value = JSON.stringify(message);

            // Broadcast to other contexts via storage events...
            var key = this._id + String(Date.now()) + '$' + String(Math.random());
            global.localStorage.setItem(key, value);
            setTimeout(function() {
                global.localStorage.removeItem(key);
            }, 500);

            // Broadcast to current context via ports
            channels[this._id].forEach(function(bc) {
                if (bc === $this) return;
                bc._mc.port2.postMessage(JSON.parse(value));
            });
        },
        close: function() {
            if (this._closed) return;
            this._closed = true;
            this._mc.port1.close();
            this._mc.port2.close();

            var index = channels[this._id].indexOf(this);
            channels[this._id].splice(index, 1);
        },

        // EventTarget API
        get onmessage() {
            return this._mc.port1.onmessage;
        },
        set onmessage(value) {
            this._mc.port1.onmessage = value;
        },
        addEventListener: function(/*type, listener , useCapture*/) {
            return this._mc.port1.addEventListener.apply(this._mc.port1, arguments);
        },
        removeEventListener: function(/*type, listener , useCapture*/) {
            return this._mc.port1.removeEventListener.apply(this._mc.port1, arguments);
        },
        dispatchEvent: function(/*event*/) {
            return this._mc.port1.dispatchEvent.apply(this._mc.port1, arguments);
        },
    };

    global.BroadcastChannel = global.BroadcastChannel || BroadcastChannel;
})(window);

SeyyedKhandon avatar Nov 08 '20 07:11 SeyyedKhandon

Not sure if this will cause problems down the line, but I ended up making self equivalent to window prior to importing:

const globalObj = global as any
globalObj.self = window

import 'broadcastchannel-polyfill'

dchambers avatar Nov 25 '20 22:11 dchambers