Different from ServiceWorker.
Running heavy processing in a separate thread from the UI thread prevents the UI from freezing during processing
Information is exchanged through message passing
When creating a WebWorker, it is necessary to create a separate JS from the main body.
var myWorker = new Worker('worker.js');But I want to share the code with the mainframe.
It's done.
----memo 2020-03-16-2
import Worker from "worker-loader!./webworker";Uncaught TypeError: Failed to execute 'postMessage' on 'DedicatedWorkerGlobalScope': No function was found that matched the signature provided.
2020-03-16
ts
(this["webpackJsonplaern-ww-wp-cra-t"] = this["webpackJsonplaern-ww-wp-cra-t"] || []).push([["webworker"],{
/***/ "./src/webworker.ts":
/*!**************************!*\
!*** ./src/webworker.ts ***!
\**************************/
/*! exports provided: onmessage */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "onmessage", function() { return onmessage; });
console.log("webworker");
const onmessage = function (e) {
console.log("Message received from main script", e);
console.log("Posting message back to main script");
postMessage(e, "*");
};
/***/ }),
/***/ 2:
/*!************************************************************!*\
!*** multi (webpack)/hot/dev-server.js ./src/webworker.ts ***!
\************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
__webpack_require__(/*! /Users/nishio/learn-ww-wp-cra-t/node_modules/webpack/hot/dev-server.js */"./node_modules/webpack/hot/dev-server.js");
module.exports = __webpack_require__(/*! /Users/nishio/learn-ww-wp-cra-t/src/webworker.ts */"./src/webworker.ts");
/***/ })
},[2,"runtime-webworker",2](/en/2%2C%22runtime-webworker%22%2C2)]);
//# sourceMappingURL=webworker.chunk.js.map
2020-03-10 After yesterday's discussion, we decided it would be a good idea to delve into webpack
Entry points can be specified in the webpack configuration (e.g. index.ts)
module.exports = {
entry: {
index: "./src/index.ts",
webworker: "./src/webworker.ts"
},
...
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist")
},
:
$ ~/node_modules/webpack-cli/bin/cli.js
Hash: def769ed43f728038706
Version: webpack 4.42.0
Time: 808ms
Built at: 2020/03/16 18:02:28
Asset Size Chunks Chunk Names
index.js 4.1 KiB 0 [emitted] index
webworker.js 4.4 KiB 1 [emitted] webworker
Entrypoint index = index.js
Entrypoint webworker = webworker.js
[0] ./src/common.ts 53 bytes {0} {1} [built]
[1] ./src/index.ts 82 bytes {0} [built]
[2] ./src/webworker.ts 265 bytes {1} [built]
I'm getting two JS outputs from three ts, each containing what I've defined in common.ts. If you're building a project from scratch, this looks like a good idea. In the project created with create-react-app, the entry is an array, so we need to do something about that.
What happens when you pass an array to entry? Passing an array of file paths to the entry property creates what is known as a "multi-main entry". This is useful when you would like to inject multiple dependent files together and graph their dependencies into one "chunk".
webpack.config.js
entry: [
isEnvDevelopment &&
require.resolve("react-dev-utils/webpackHotDevClient"),
// Finally, this is your app's code:
paths.appIndexJs
].filter(Boolean),
output: {
...
filename: isEnvProduction
? "static/js/[name].[contenthash:8].js"
: isEnvDevelopment && "static/js/bundle.js",
It's a mess of conditional branches packed into a configuration file, but in a production environment, the file names are hashed to prevent them from being cached. I need a way to get the name of this file.
---2020-03-09
I'm using create-react-app to create templates, so webpack is now a black box.
EJECT first so that the settings can be rewritten.
Let's try it on a new project.
$ npx create-react-app --typescript learn-webworker
$ cd learn-webworker/
$ npm run eject
:
> learn-webworker@0.1.0 eject /Users/nishio/learn-webworker
> react-scripts eject
NOTE: Create React App 2+ supports TypeScript, Sass, CSS Modules and more without ejecting: https://reactjs.org/blog/2018/10/01/create-react-app-v2.html
? Are you sure you want to eject? This action is permanent. Yes
Ejecting...
Copying files into /Users/nishio/learn-webworker
Adding /config/env.js to the project
...
Adding /config/webpack.config.js to the project
...
Updating the dependencies
Removing react-scripts from dependencies
...
Adding webpack to dependencies
...
Updating the scripts
Replacing "react-scripts start" with "node scripts/start.js"
Replacing "react-scripts build" with "node scripts/build.js"
Replacing "react-scripts test" with "node scripts/test.js"
Configuring package.json
Adding Jest configuration
Adding Babel preset
...
Ejected successfully!
Staged ejected files for commit.
Please consider sharing why you ejected in this survey:
http://goo.gl/forms/Bi6CZjk1EqsdelXk1
$ git status
:
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: config/env.js
...
new file: config/webpack.config.js
...
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: package-lock.json
modified: package.json
modified: src/react-app-env.d.ts
$ git add -u
$ git commit -m "eject"
$ npm install worker-loader --save-dev
https://github.com/nishio/learn-webworker/blob/04fe485/config/webpack.config.js#L362-L392
{
test: /\.worker\.js$/,
loader: "worker!babel?presets[]=es2015"
}
https://github.com/nishio/learn-webworker/blob/4d426fe/config/webpack.config.js#L363 → Cannot find module: 'worker-loader!babel-loader'. Make sure this package is installed.
Hmmm, I wonder if it's a problem with the way webpack rules are written. It's possible that the information you referenced is out of date and needs to be written differently in the current webpack.
babel/babel-loader: 📦 Babel loader for webpack webpack-contrib/worker-loader: A webpack loader that registers a script as a Web Worker
-----Past notes
const worker = new Worker(workerPath);import * as workerPath from "file-loader?name=[name].js!./test.worker";import/no-webpack-loader-syntax// eslint-disable-next-line import/no-webpack-loader-syntaxUncaught SyntaxError: Unexpected token 'export'All files must be modules when the '--isolatedModules' flag is provided. TS1208// eslint-disable-next-line no-restricted-globals
addEventListener("message", message => {
console.log("Message received from main script");
console.log("in webworker", message.data);
postMessage("this is the response " + message.data * 2);
});
OK, it worked.
But when I try to import other files, error
Uncaught SyntaxError: Cannot use import statement outside a module...
This page is auto-translated from /nishio/WebWorker using DeepL. If you looks something interesting but the auto-translated English is not good enough to understand it, feel free to let me know at @nishio_en. I'm very happy to spread my thought to non-Japanese readers.