Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running Angular 5 app inside webworker causes window object to be undefined

I am trying to upgrade this (ngx-admin) free Angular template to Angular 5 and then trying to run the whole app inside WebWorker as mentioned in this SO Post.

I successfully upgraded the app to Angular 5 and it is working fine but when I try to configure the app to run inside Webworker it gives me following error:

enter image description here

enter image description here

The complete code (modified to Angular 5 and webworker) can be found here

I tried to add DefinePlugin in my webpack config but no luck.

webpack.config.json:

new DefinePlugin({
  window: undefined,
  document: undefined
}),

I was able to run new empty angular-cli application inside webworker but I am unable to run this template inside webworker. I guess there is some node package which is creating issue.

Package.json:

{
  "scripts": {
    "ng": "ng",
    "conventional-changelog": "conventional-changelog",
    "e2e": "protractor ./protractor.conf.js",
    "docs": "compodoc -p src/tsconfig.app.json -d docs",
    "docs:serve": "compodoc -p src/tsconfig.app.json -d docs -s",
    "release:changelog": "npm run conventional-changelog -- -p angular -i CHANGELOG.md -s",
    "build": "webpack",
    "start": "webpack-dev-server --port=4200",
    "test": "karma start ./karma.conf.js",
    "pree2e": "webdriver-manager update --standalone false --gecko false --quiet"
  },
  "dependencies": {
    "@agm/core": "1.0.0-beta.2",
    "@angular/animations": "5.1.2",
    "@angular/common": "5.1.2",
    "@angular/compiler": "5.1.2",
    "@angular/core": "5.1.2",
    "@angular/forms": "5.1.2",
    "@angular/http": "5.1.2",
    "@angular/platform-browser": "5.1.2",
    "@angular/platform-browser-dynamic": "5.1.2",
    "@angular/platform-server": "5.1.2",
    "@angular/platform-webworker": "^5.1.2",
    "@angular/platform-webworker-dynamic": "^5.1.2",
    "@angular/router": "5.1.2",
    "@asymmetrik/angular2-leaflet": "^2.2.1",
    "@nebular/auth": "2.0.0-rc.3",
    "@nebular/theme": "2.0.0-rc.3",
    "@ng-bootstrap/ng-bootstrap": "1.0.0-beta.5",
    "@swimlane/ngx-charts": "^7.0.1",
    "angular2-chartjs": "0.3.0",
    "angular2-leaflet": "^0.1.0",
    "angular2-toaster": "4.0.0",
    "bootstrap": "4.0.0-beta.2",
    "chart.js": "2.5.0",
    "ckeditor": "4.6.2",
    "classlist.js": "1.1.20150312",
    "core-js": "2.5.1",
    "d3": "4.8.0",
    "font-awesome": "4.7.0",
    "intl": "1.2.5",
    "ionicons": "2.0.1",
    "leaflet": "^1.2.0",
    "nebular-icons": "1.0.6",
    "ng2-ckeditor": "1.1.9",
    "ng2-smart-table": "1.1.0",
    "ng2-tree": "2.0.0-alpha.10",
    "ngx-charts": "^3.0.2",
    "ngx-echarts": "1.2.2",
    "normalize.css": "6.0.0",
    "pace-js": "1.0.2",
    "roboto-fontface": "0.8.0",
    "rxjs": "5.5.6",
    "socicon": "3.0.5",
    "tether": "1.4.0",
    "tinymce": "4.5.7",
    "typeface-exo": "0.0.22",
    "web-animations-js": "2.2.5",
    "zone.js": "0.8.19"
  },
  "devDependencies": {
    "@angular/cli": "1.5.0",
    "@angular/compiler-cli": "5.1.2",
    "@angular/language-service": "5.1.2",
    "@compodoc/compodoc": "1.0.5",
    "@types/d3-color": "1.0.4",
    "@types/jasmine": "2.5.54",
    "@types/jasminewd2": "2.0.3",
    "@types/leaflet": "^1.2.4",
    "@types/node": "8.5.2",
    "codelyzer": "3.2.1",
    "conventional-changelog-cli": "1.3.4",
    "husky": "0.13.3",
    "jasmine-core": "2.6.4",
    "jasmine-spec-reporter": "4.1.1",
    "karma": "1.7.1",
    "karma-chrome-launcher": "2.1.1",
    "karma-cli": "1.0.1",
    "karma-coverage-istanbul-reporter": "1.3.0",
    "karma-jasmine": "1.1.0",
    "karma-jasmine-html-reporter": "0.2.2",
    "npm-run-all": "4.1.2",
    "protractor": "5.1.2",
    "rimraf": "2.6.1",
    "stylelint": "7.13.0",
    "ts-node": "3.2.2",
    "tslint": "5.7.0",
    "tslint-language-service": "0.9.6",
    "typescript": "2.6.2",
    "webpack-dev-server": "~2.9.3",
    "webpack": "~3.8.1",
    "autoprefixer": "^6.5.3",
    "css-loader": "^0.28.1",
    "cssnano": "^3.10.0",
    "exports-loader": "^0.6.3",
    "file-loader": "^1.1.5",
    "html-webpack-plugin": "^2.29.0",
    "less-loader": "^4.0.5",
    "postcss-loader": "^1.3.3",
    "postcss-url": "^5.1.2",
    "raw-loader": "^0.5.1",
    "sass-loader": "^6.0.3",
    "source-map-loader": "^0.2.0",
    "istanbul-instrumenter-loader": "^2.0.0",
    "style-loader": "^0.13.1",
    "stylus-loader": "^3.0.1",
    "url-loader": "^0.6.2",
    "circular-dependency-plugin": "^3.0.0",
    "webpack-concat-plugin": "1.4.0",
    "copy-webpack-plugin": "^4.1.1",
    "uglifyjs-webpack-plugin": "1.0.0"
  }
}
like image 220
Saurabh Palatkar Avatar asked Dec 30 '17 15:12

Saurabh Palatkar


2 Answers

Web workers does not run in a window and does therefore not have the window object. However, if you are using libraries that use the window object, you can assign it yourself using the self variable at the top of your code.

const window = self;

From MDN:

A worker is an object created using a constructor (e.g. Worker()) that runs a named JavaScript file — this file contains the code that will run in the worker thread; workers run in another global context that is different from the current window. Thus, using the window shortcut to get the current global scope (instead of self) within a Worker will return an error.

The worker context is represented by a DedicatedWorkerGlobalScope object in the case of dedicated workers (standard workers that are utilized by a single script; shared workers use SharedWorkerGlobalScope). A dedicated worker is only accessible from the script that first spawned it, whereas shared workers can be accessed from multiple scripts.

like image 145
jornare Avatar answered Nov 15 '22 01:11

jornare


You have to add this to the webpack config file:

output: {
...
globalObject: "this"
}

Edit: The previous solution is a little bit tricky. If you really make a webworker bundle, you'll have to use webpack multiple targets. (Webpack version >= 4.12.0)

export.module= [
         {
           target: 'web',
           // Webpack config here for bundle that will work in UI thread.
         },
         {
           target: 'webworker',
           // Webpack config here for bundle that will work in the worker.
         }
]
like image 31
Serginho Avatar answered Nov 15 '22 03:11

Serginho