在Webworker中运行Angular 5应用会导致窗口对象未定义 [英] Running Angular 5 app inside webworker causes window object to be undefined

查看:70
本文介绍了在Webworker中运行Angular 5应用会导致窗口对象未定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将

完整的代码(已修改为Angular 5和webworker)可以在此处

我试图在我的webpack配置中添加DefinePlugin,但是没有运气.

webpack.config.json:

 新的DefinePlugin({窗口:未定义,文件:未定义}), 

我能够在Webworker中运行新的空angular-cli应用程序,但无法在Webworker中运行此模板.我想有些节点包正在造成问题.

Package.json:

  {脚本":{"ng":"ng",常规更改日志":常规更改日志","e2e":量角器./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运行常规更改日志--p angular -i CHANGELOG.md -s","build":"webpack","start":"webpack-dev-server --port = 4200","test":业力启动./karma.conf.js","pree2e":"webdriver-manager update --standalone false --gecko false --quiet"},依赖关系":{"@ 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-b​​rowser":"5.1.2","@ angular/platform-b​​rowser-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/茉莉花":"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",茉莉花芯":"2.6.4","jasmine-spec-reporter":"4.1.1",业力":"1.7.1",业力铬发射器":"2.1.1","karma-cli":"1.0.1",业力报废的伊斯坦布尔记者":"1.3.0",业力茉莉花":"1.1.0","karma-jasmine-html-reporter":"0.2.2","npm-run-all":"4.1.2",量角器":"5.1.2","rimraf":"2.6.1","stylelint":"7.13.0","ts-node":"3.2.2","tslint":"5.7.0","tslint语言服务":"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"}} 

解决方案

Web worker不在窗口中运行,因此没有window对象.但是,如果使用的是使用window对象的库,则可以使用代码顶部的self变量自行分配它.

  const window = self; 

来自 MDN :

worker是使用构造函数(例如Worker())创建的对象,运行一个命名的JavaScript文件-该文件包含的代码将在工作线程中运行;工人在另一个全球环境中工作与当前窗口不同.因此,使用窗口快捷方式在工人内部获取当前的全球范围(而非自身)返回错误.

工作者上下文由 DedicatedWorkerGlobalScope 表示专门工作人员(标准工作人员,由单个脚本使用;共享的工人使用SharedWorkerGlobalScope).只能从以下位置访问专职工作人员最初生成它的脚本,而共享工作程序可以是从多个脚本访问.

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:

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"
  }
}

解决方案

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.

这篇关于在Webworker中运行Angular 5应用会导致窗口对象未定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆