webpack: Webpack 4.0.1 | WebWorker `window is not defined`

Do you want to request a feature or report a bug?

Bug 🐛

What is the current behavior?

When requiring web-worker (using worker-loader) recieve error Uncaught ReferenceError: window is not defined.

First ~50 lines of built worker file
/******/ (function(modules) { // webpackBootstrap
/******/ 	var parentHotUpdateCallback = window["webpackHotUpdate"];
/******/ 	window["webpackHotUpdate"] = // eslint-disable-next-line no-unused-vars
/******/ 	function webpackHotUpdateCallback(chunkId, moreModules) {
/******/ 		hotAddUpdateChunk(chunkId, moreModules);
/******/ 		if (parentHotUpdateCallback) parentHotUpdateCallback(chunkId, moreModules);
/******/ 	} ;
/******/
/******/ 	// eslint-disable-next-line no-unused-vars
/******/ 	function hotDownloadUpdateChunk(chunkId) {
/******/ 		importScripts(__webpack_require__.p + "" + chunkId + "." + hotCurrentHash + ".hot-update.js");
/******/ 	}
/******/
/******/ 	// eslint-disable-next-line no-unused-vars
/******/ 	function hotDownloadManifest(requestTimeout) {
/******/ 		requestTimeout = requestTimeout || 10000;
/******/ 		return new Promise(function(resolve, reject) {
/******/ 			if (typeof XMLHttpRequest === "undefined")
/******/ 				return reject(new Error("No browser support"));
/******/ 			try {
/******/ 				var request = new XMLHttpRequest();
/******/ 				var requestPath = __webpack_require__.p + "" + hotCurrentHash + ".hot-update.json";
/******/ 				request.open("GET", requestPath, true);
/******/ 				request.timeout = requestTimeout;
/******/ 				request.send(null);
/******/ 			} catch (err) {
/******/ 				return reject(err);
/******/ 			}
/******/ 			request.onreadystatechange = function() {
/******/ 				if (request.readyState !== 4) return;
/******/ 				if (request.status === 0) {
/******/ 					// timeout
/******/ 					reject(
/******/ 						new Error("Manifest request to " + requestPath + " timed out.")
/******/ 					);
/******/ 				} else if (request.status === 404) {
/******/ 					// no update available
/******/ 					resolve();
/******/ 				} else if (request.status !== 200 && request.status !== 304) {
/******/ 					// other failure
/******/ 					reject(new Error("Manifest request to " + requestPath + " failed."));
/******/ 				} else {
/******/ 					// success
/******/ 					try {
/******/ 						var update = JSON.parse(request.responseText);
/******/ 					} catch (e) {
/******/ 						reject(e);
/******/ 						return;
/******/ 					}
/******/ 					resolve(update);
/******/ 				}
/******/ 			};
/******/ 		});
/******/ 	}

// More code... (think it's irrelevant)
screen shot 2018-03-01 at 23 12 59

What is the expected behavior?

To inject right template for web-workers that won’t include/use window element.

Please mention other relevant information such as the browser version, Node.js version, webpack version, and Operating System.

I’m using electron-render as webpack build target. Tried changing it to web and inspecting the worker file, but still didn’t work!

  • Webpack config (filtered):

    {
      mode: 'development',
      devtool: 'eval-source-map',
      target: 'electron-renderer',
      entry: [
        'react-hot-loader/patch',
        path.join(__dirname, 'src/index.js'),
        'webpack-hot-middleware/client?reload=true&path=http://localhost:3000__webpack_hmr&overlay=false'
      ],
      output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js'
        publicPath: 'http://localhost:3000'
      },
      module: {
        rules: [
          {
            enforce: 'pre',
            test: /\.js$/i,
            exclude: /node_modules/,
            use: {
              loader: 'eslint-loader',
              options: {
                fix: true,
                failOnWarning: false,
                failOnError: false
              }
            }
          },
          {
            test: /\.worker.js$/i,
            exclude: /node_modules/,
            use: [
              'worker-loader'
            ]
          },
          {
            test: /\.js$/i,
            exclude: /node_modules/,
            use: [
              'babel-loader'
            ]
          },
          // ...
        ]
      },
      resolve: {
        modules: [
          path.resolve('./src'),
          'node_modules'
        ]
      },
      plugins: [
    	new webpack.HotModuleReplacementPlugin(),
    	new webpack.NamedModulesPlugin(),
    	new webpack.DefinePlugin({
      	  'process.env.NODE_ENV': JSON.stringify('development')
    	})
      ]
    }
    
  • NPM Packages (filtered):

    "electron": "2.0.0-beta.1"
    "react-hot-loader": "4.0.0"
    "webpack": "4.0.1"
    "webpack-cli": "2.0.9"
    "webpack-dev-middleware": "3.0.0"
    "webpack-hot-middleware": "2.21.1"
    "webpack-merge": "4.1.2"
    "worker-loader": "1.1.1"
    
  • Operating System: OSX 10.12.6

  • Node.js: v9.5.0

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 35
  • Comments: 20 (2 by maintainers)

Commits related to this issue

Most upvoted comments

@Kuzirashi inside the output section of webpack config. Like this:

output: {
       path: path.join(__dirname, 'dist'),
       filename: 'bundle.js'
       publicPath: 'http://localhost:3000',
       globalObject: 'this'
},

#6525 will fix this.

As workaround with HMR: output.globalObject: "this"

disabling hot module replacement fixed this for me.

Changing output.globalObject like @zhihuilai suggested worked for me, but when using code splitting (via optimization.splitChunks), my output would start with the following invalid code:

("undefined"!=typeof self?self:this.webpackJsonp="undefined"!=typeof self?self:this.webpackJsonp||[]).push(/* ... etc. */)

I solved this by adding parentheses around the globalObject string as follows:

output: {
  // ...
  globalObject: `(typeof self !== 'undefined' ? self : this)`,
},

This makes the output look like this:

(("undefined"!=typeof self?self:this).webpackJsonp=("undefined"!=typeof self?self:this).webpackJsonp||[]).push(/* ... etc. */)

It’s not exactly pretty, but it does work. I’m aware of this possibly being an issue with Uglify’s optimization as well, since the globalObject string isn’t exactly what ends up in the code (although I doubt the optimization makes the code invalid in this case), but since that’s so pervasive I figured it was worth sharing.

I also want to mention that defining your own output.jsonpFunction may affect the outcome here, in which case you may need to play around with globalObject some more. If anyone runs into this, please share your outcome.

HMR is still broken.

Issue #6525 is being delayed.

This should be reopened and fixed. It’s a breaking change from 3.0 and universal mode is a feature, not a bug fix

@rettgerst Disabling new webpack.HotModuleReplacementPlugin() helped as a temporary fix.

In case this helps anyone, if you are hitting this error in your web worker itself (from your application code using window), you should either update the code to instead use self, or before your other imports in the web worker entrypoint file add an import "./setup" to a setup file that makes a window global: self.window = self

终于找到解决办法了!

I tried adding the global object and while running npm start it gives me this error: configuration.output has an unknown property 'globalObject'

I’m trying to implement Web Worker with Angular 5.

any help?