Code Monkey home page Code Monkey logo

comlink-loader's Introduction

comlink-loader

🛰 comlink-loader 📡

Offload modules to Worker threads seamlessly using Comlink.

Features

  • Offload almost any module into a Worker with little or no usage change
  • Supports arbitrary classes, objects & functions (await new Foo())
  • Works beautifully with async/await
  • Built-in code-splitting: workers are lazy-loaded

Installation

npm install -D comlink-loader

Usage

The goal of comlink-loader is to make the fact that a module is running inside a Worker nearly transparent to the developer.

Factory Mode (default)

In the example below, there are two changes we must make in order to import MyClass within a Worker via comlink-loader.

  1. instantiation and method calls must be prefixed with await, since everything is inherently asynchronous.
  2. the value we import from comlink-loader!./my-class is now a function that returns our module exports.

    Calling this function creates a new instance of the Worker.

my-class.js: (gets moved into a worker)

// Dependencies get bundled into the worker:
import rnd from 'random-int';

// Export as you would in a normal module:
export function meaningOfLife() {
  return 42;
}

export class MyClass {
  constructor(value = rnd()) {
    this.value = value;
  }
  increment() {
    this.value++;
  }
  // Tip: async functions make the interface identical
  async getValue() {
    return this.value;
  }
}

main.js: (our demo, on the main thread)

import MyWorker from 'comlink-loader!./my-class';

// instantiate a new Worker with our code in it:
const inst = new MyWorker();

// our module exports are exposed on the instance:
await inst.meaningOfLife(); // 42

// instantiate a class in the worker (does not create a new worker).
// notice the `await` here:
const obj = await new inst.MyClass(42);

await obj.increment();

await obj.getValue();  // 43

Singleton Mode

Comlink-loader also includes a singleton mode, which can be opted in on a per-module basis using Webpack's inline loader syntax, or globally in Webpack configuration. Singleton mode is designed to be the easiest possible way to use a Web Worker, but in doing so it only allows using a single Worker instance for each module.

The benefit is that your module's exports can be used just like any other import, without the need for a constructor. It also supports TypeScript automatically, since the module being imported looks just like it would were it running on the main thread. The only change that is required in order to move a module into a Worker using singleton mode is to ensure all of your function calls use await.

First, configure comlink-loader globally to apply to all *.worker.js files (or whichever pattern you choose). Here we're going to use TypeScript, just to show that it works out-of-the-box:

webpack.config.js:

module.exports = {
  module: {
    rules: [
      {
        test: /\.worker\.(js|ts)$/i,
        use: [{
          loader: 'comlink-loader',
          options: {
            singleton: true
          }
        }]
      }
    ]
  }
}

Now, let's write a simple module that we're going to load in a Worker:

greetings.worker.ts:

export async function greet(subject: string): string {
  return `Hello, ${subject}!`;
}

We can import our the above module, and since the filename includes .worker.ts, it will be transparently loaded in a Web Worker!

index.ts:

import { greet } from './greetings.worker.ts';

async function demo() {
  console.log(await greet('dog'));
}

demo();

License

Apache-2.0

comlink-loader's People

Contributors

developit avatar gingur avatar jackyef avatar nicomt avatar wellcaffeinated avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

comlink-loader's Issues

Node Support

It would be really great to add node support to this loader.

For example, respecting environment target the loader could change behavior to add a few extra lines. The original Comlink library already supports this. It would be nice to have it in the loader as well.

Or maybe, is there a workaround? Is there a way to make comlink-loader to work with node’s worker threads without modifying loader’s source code? I tried to add another loader on top, but it doesn’t look like a great idea. Any suggestions?

Use of onmessage

Hi, great library, I am so glad I found this, it works almost great with my vuejs app.

the only issue I am having trouble is trying to send a message to the main thread which I cant do myself nor find in the docs.

The thing is that I am sending an array of files to my worker which uploads one by one (that works perfectly)
but I am trying to send a "uploadCompleted" or "error" variable back to the client and I am not able to do it with a return since it takes too long.

here is a piece of my code:

//Component.vue
files = [...bunchOfFiles]
await WorkerUploader(files)

//worker.js
export const WorkerUploader = async files => {
  const { relativePath, file, putAction, headers } = fileObj
  files.map(file => {
     let xhr = new XMLHttpRequest()

  // handle error
  xhr.upload.onerror = function() {
    console.log(`Error during the upload: ${xhr.status}.`)
    return { status: xhr.status, relativePath }
  }

  // upload completed successfully
  xhr.onload = function() {
    console.log('Upload completed successfully.')
    return { status: xhr.status, relativePath }
  }

  // add custom url
  xhr.open('PUT', putAction)

  //add header
  Object.keys(headers).map(key => {
    xhr.setRequestHeader(key, headers[key])
  })
  })
}

Thank you!

Security Vulnerability Using Webpack 4.46.0

Description:
I have identified a security vulnerability . The comlink-loader package currently relies on Webpack version 4.46.0, which is known to have a security issue tracked under CVE-2023-28154.

Vulnerability Details:
Webpack 4.46.0 is affected by CVE-2023-28154, which is a critical security vulnerability. Webpack 5 before version 5.76.0 is susceptible to this issue, and it can potentially lead to cross-realm object access. Specifically, the ImportParserPlugin.js mishandles the magic comment feature, and an attacker who controls a property of an untrusted object can obtain access to the real global object.

Recommendation:
To address this security vulnerability, I strongly recommend updating the package to use a version of Webpack that is equal to or greater than 5.76.0. This will ensure that the security issue is resolved.

Note:
I understand that this issue may not be directly within the control of the package maintainers, but I believe it's important to bring it to their attention for the safety and security of the user community.

Thank you for your attention to this matter.

Shared Worker

I tried looking at the code but somehow I'm not sure how to revise the implementation a bit with support for SharedWorker. There is some material here that might help.

GoogleChromeLabs/comlink#485 (comment)

Can this be tweaked to also allow instantiating a SharedWorker on runtime?

Error: rawValue is undefined in comlink-loader

hello everyone.
I'm using the comlink-loader in ReactJS to load a class and call a function in off-thread.
it's a very basic function, only returns the given value (I'm gonna use it later to call API in off-thread), but I'm getting this error: Error: rawValue is undefined

here is my worker:

`//@todo: use writelog later to call API
// import { writeLog } from 'constants/Helpers/logHelpers';

export class LogWorker {
// offThreadLog: payload => writeLog(payload),
async offThreadLog(payload) {
return payload;
}
}`

and this is how I loaded and called it

`//some imports
import LogWorker from 'comlink-loader!constants/Workers/log.worker';
// some other imports

const Hoc = () => {
useEffect(() => {
const logWorker = new LogWorker();
window.addEventListener('click', async () => {
const response = await logWorker.offThreadLog({
medium: 'HOC',
detail: 'off thread log',
action: 'click',
});
console.log(response);
});
}, []);
}

export default Hoc;`
I also tried the example in docs, but the same error happened.
thanks.

Meaning of your comlink unclear

Let me get straight to the point:

The goal of comlink-loader is to make the fact that a module is running inside a Worker nearly transparent to the developer.

"Transparent" - this feels a bit too broad to me. Can you reword your goals (meaning of your life, ahem project), what sort of good this transparency brings?

Uncaugt TypeError: __webpack_require__(...) is not a function

Hey - I'm using customize-cra and react-app-rewired to override the webpack config usually abstracted away in a create-react-app.

I'm importing the random-int package to the worker file - which is the import that fails.

config-overrides.js

const { override, addWebpackModuleRule, babelInclude } = require("customize-cra");
const path = require('path')
module.exports = override(
  addWebpackModuleRule({
    test: /\.worker\.(js|ts)$/i,
    use: [
      {
        loader: "comlink-loader",
        options: {
          singleton: true,
        },
      },
    ],
  })
);

This is the correct syntax - but now it complains about that webpack doesn't have a require function - which is to be expected. Supposedly something wasn't transpiled by babel but I can't figure out where to even begin.

Do you geniuses have any idea?

worker.load is not a function

This is my App.js code when iam trying to run this iam getting this error "worker.load is not a fuction"!!

please resolve this !!

`import { useCallback, useEffect, useState } from 'react';
import { createWorker } from 'tesseract.js';
import './App.css';

function App() {
const [selectedImage, setSelectedImage] = useState(null);
const [textResult, setTextResult] = useState("");

const worker = createWorker();

const convertImageToText = useCallback(async () => {
if(!selectedImage) return;
await worker.load();
await worker.loadLanguage("eng");
await worker.initialize("eng");
const { data } = await worker.recognize(selectedImage);
console.log(data)
setTextResult(data.text);
}, [worker, selectedImage]);

useEffect(() => {
convertImageToText();
}, [selectedImage, convertImageToText])

const handleChangeImage = e => {
if(e.target.files[0]) {
setSelectedImage(e.target.files[0]);
} else {
setSelectedImage(null);
setTextResult("")
}
}
return (


Image to Text


Get words from image !!



upload image

  <div className='result'>
    {selectedImage && (
      <div className='box-image'>
        <img src={URL.createObjectURL(selectedImage)} alt="thumb" />
      </div>
    )}
    {textResult && (
      <div className='box-p'>
        <p>{textResult}</p>
        </div>
    )}
  </div>
</div>

);
}

export default App;`

[v2] comlink needs to be an external for server bundle

I was playing around with comlink-loader with an isomorphic react app. I used multi and inline options.

For the client bundle, everything works fine, but it failed when bundling the server bundle.

export 'expose' was not found in 'comlink'

After some digging, I found out that it is fixed after I add /^comlink/ to webpack externals. (My webpack externals config is a bit different, I do not use webpack-node-externals)

So, is it expected that comlink only work when externalised? It didn't throw any error on v1 though.

Using functions inside a typescript class - “TypeError: is not a function”

'm trying to setup comlink in a typescript project but can't work out why this doesn't work.

My calling method/ class

import Mehs from "@/myTest.worker";

export default class TestCalling{``

public async callMyTestMethod(): Promise {
const meh: Mehs = new Mehs();``
const ss: string = await meh.greet("Neil");
console.log(ss);
}
}`
My test class/method

export default class TestWorker{
public async greet(subject: string): Promise {
return new Promise((resolve) => {
resolve(Hello, ${subject}!);
});
}
}
This give me the following error : "TypeError: meh.greet is not a function"

However if i just export a function it works i.e.

export async function greet(subject: string): Promise {
return new Promise((resolve) => {
resolve(Hello, ${subject}!);
});
}
But i want to use a class as it may have multiple functions that i want to call. What am i doing wrong ?

[Typescript] NOT adding polyfill to the web worker scope

Reproduce:

  1. Create React App
npx create-react-app my-app  --template typescript
cd my-app
npm start
  1. Use react-app-rewired to customize Webpack

  2. In config-overrides.js, add the comlink-loader at the top of rules

/**
 * Config to override webpack config from create-react-app
 */
const { override } = require('customize-cra');
module.exports = override((config, env) => {
  config.module.rules.unshift({
    test: /\.worker.singleton\.(js|ts)$/i,
    loader: 'comlink-loader',
    options: {
      singleton: true
    }
  });
  config.module.rules.unshift({
    test: /\.worker\.(js|ts)$/i,
    loader: 'comlink-loader',
    options: {
      singleton: false
    }
  });
  return config;
});

  1. create a task.worker.singleton.ts
export async function test(): string {
  return "something".replaceAll('s', 'g')
}

Actual: In an old version browser (i.e. Android simulator), It will throw .replaceAll() is not a function

Expected: comlink-loader will bundle the polyfill to all .worker.ts to sync with the non-worker js file.

Solution

Add the Polyfill manaully.

import 'core-js';
import 'regenerator-runtime/runtime';

export async function test(): string {
  return "something".replaceAll('s', 'g')
}

How to start and stop web worker on different routes

I use comlink-loader in singleton mode.

Web workers inits on app start and not depend on which route open now.
How i can start web worker on certain route and stop it when i go to another one?

I know that i can use close method in worker for stop

export const terminate = () => { close(); };

But after call close() method i can't start worker again without refresh page.

Upgade to comlink 3

I think you only need to change the import syntax from

- import { Comlink } from 'comlinkjs'
+ import { proxy, ...} from 'comlinkjs'

Transferable support

Hello,

I'm trying to use "Transferable objects" but no luck. Should it work?

// worker
import rnd from 'random-int';
// Dependencies get bundled into the worker:

// Export as you would in a normal module:
export function meaningOfLife(): number {
  return 42;
}

export class MyClass {
    private value: number;

  constructor(value: number = rnd()) {
    this.value = value;
  }
  public increment() {
    this.value++;
  }

  public gimmeABuffer(value: Uint8Array) {
    return value;
  }

  // Tip: async functions make the interface identical
  public async getValue() {
    return this.value;
  }
}
// main
      async function init() {
        const inst = new worker2();
        // our module exports are exposed on the instance:
        await inst.meaningOfLife(); // 42

        const data = new Uint8Array([1, 2, 3, 4, 5]);
        await inst.gimeABuffer(Comlink.transfer(data, [data.buffer]));
        
        // instantiate a class in the worker (does not create a new worker).
        // notice the `await` here:
        const obj = await new inst.MyClass(42);
        
        await obj.increment();

        const value = await obj.getValue();  // 43
        window.console.log(value);
      }
      init();

The problematic line:

        const data = new Uint8Array([1, 2, 3, 4, 5]);
        inst.gimeABuffer(Comlink.transfer(data, [data.buffer]));

and the error:

  151 |   break;
  152 | case MessageType.APPLY:
  153 |   {
> 154 |     returnValue = rawValue.apply(parent, argumentList);
      | ^  155 |   }
  156 |   break;
  157 | case MessageType.CONSTRUCT:

Thanks!

Symbol and Proxy is not defined in IE11

I have added
import 'proxy-polyfill/proxy.min.js' import 'core-js/stable' import 'regenerator-runtime/runtime'
to my worker file.

However, it does not work properly and still get two error messages in IE11:
Symbol is not defined.
Proxy is not defined.

Could anyone provide a working example for IE11? Thanks.

Can not stop worker

I created a class and imported using this loader. I tried to call terminate on the instance initialized using the loader and I noticed it tries to call the instance method. So I implemented the method and inside it, it just calls close, to close the webworker. Here is the problem: After I do this, I cannot create another instance of this class.

// Terminator.js
export default class Terminator {
  terminate() {
    close()
  }
  
 ping() {
  return 'pong'
 }
}

// index.js
import Terminator from 'comlink-loader!./Terminator'

(async () => {
  let terminator = await new Terminator()
  console.log(await terminator.ping()) // logs 'pong'
  await terminator.terminate()
  terminator = await new Terminator() // freezes
  console.log(await terminator.ping()) // never called
})()

I need this behavior because I am running a process that can generate an infinite loop, so I need to be able to cancel the execution.

Usage question

Excited to try out this webpack loader!

  • How does this loader compare to workerize-loader?
  • Does this loader require a JS class export or can any other function be exported and used?

Typescript Support?

I see that Clooney has TS support, but this appears to not play well the TypeScript Linter. Is it even possible to add support for TypeScript given the mutation that occurs?

new Worker() will only be bundled if passed a String

I added comlink-loader to my Vue app via chainWebpack

// vue.config.js
module.exports = {
  chainWebpack: (config) => {
    config.module
      .rule('comlink-loader')
      .test(/\.worker\.js$/i)
      .use('comlink-loader')
      .loader('comlink-loader')
      .options({
        singleton: true,
      });
  },
};

I'm not doing anything exciting, it's just a hello-world code:

// ./hello.worker.js
export default async (subject) => {
  return `Hello, ${subject}!`;
};
// ./main.js
import hello from './hello.worker';

(async () => {
  console.log(await hello('dog'));
})();

The code compiles fine. The worker code executes as expected, but I'm getting compilation warnings:

new Worker() will only be bundled if passed a String.

Zrzut ekranu 2021-06-1 o 14 37 40


EDIT:

It turned out to be an issue on my end. I had worker-plugin installed. It was that plugin that was raising errors.

Issue with isolatedModules turn on in project

I'm using webpack 4.28.4 and typescript 3.5.1.

I tried to install the comlink-loader, everything seems fine, but it complain my worker is not a module.

All files must be modules when the '--isolatedModules' flag is provided.
// something.worker.ts

import { doSomething } from './util';

export const processSomething = async(payload) => {
  return doSomething(payload);
}

This is my webpack config for comlink-loader, it is basically copy and paste.

  {
    test: /\.worker\.ts$/i,
    use: [{
      loader: 'comlink-loader',
      options: {
        singleton: true
      }
    }]
  },

Do you see if I'm missing anything here ?

support for webpack 5

It seems that webpack 5 in production mode breaks the singleton mode (that was working fine for webpack 4). It throws an error that __webpack_exports__ is not defined . In development mode for webpack 5 everything works as expected, but only in production it generates the error. I identified that if I set in webpack optimization usedExports: false then the issue is resolved (however that is an undesirable option).

This is the config for webpack:

module.exports = merge(baseConfig, {
  target: 'electron-renderer',
  entry: {
    app: './src/client/app.tsx',
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            cacheDirectory: true,
            babelrc: true,
          },
        },
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.(gif|png|jpe?g)$/,
        use: [
          'file-loader',
          {
            loader: 'image-webpack-loader',
            options: {
              bypassOnDebug: true,
            },
          },
        ],
      },
      {
        test: /\.svg$/,
        use: ['svg-inline-loader?classPrefix'],
      },
      {
        test: /\.md$/i,
        use: ['raw-loader'],
      },
      // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
      {
        enforce: 'pre',
        test: /\.js$/,
        use: ['source-map-loader'],
      },
      {
        test: /\.worker\.ts$/i,
        use: [
          {
            loader: 'comlink-loader',
            options: {
              singleton: true,
            },
          },
          {
            loader: 'babel-loader',
            options: {
              cacheDirectory: true,
              babelrc: true,
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new ForkTsCheckerWebpackPlugin({
      typescript: {
        diagnosticOptions: {
          semantic: true,
          syntactic: true,
        },
      },
    }),
    new HtmlWebpackPlugin({ template: path.resolve(__dirname, 'src/client/index.html') }),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
      'process.env.STORE': JSON.stringify(process.env.STORE || ''),
    }),
    new CopyPlugin({
      patterns: [{ from: path.resolve(__dirname, 'static/'), to: path.resolve(__dirname, 'dist', 'static') }],
    }),
  ],
});

This is the babel config:

module.exports = (api) => {
  // This caches the Babel config by environment.
  api.cache.using(() => process.env.NODE_ENV);
  const developmentPlugins = ['@babel/plugin-transform-runtime', 'react-refresh/babel'];

  const productionPlugins = [
    // babel-preset-react-optimize
    '@babel/plugin-transform-react-constant-elements',
    '@babel/plugin-transform-react-inline-elements',
    'babel-plugin-transform-react-remove-prop-types',
  ];
  const development = api.env('development', 'test');

  return {
    presets: [
      ['@babel/preset-env', { targets: 'last 1 chrome version' }],
      '@babel/preset-typescript',
      '@babel/preset-react',
      '@emotion/babel-preset-css-prop',
    ],
    plugins: [
      ['@babel/plugin-proposal-decorators', { legacy: true }],
      ['@babel/plugin-proposal-class-properties', { loose: true }],
      '@babel/plugin-proposal-optional-chaining',
      '@babel/plugin-proposal-nullish-coalescing-operator',
      ...(development ? developmentPlugins : productionPlugins),
    ],
  };
};

It works fine in webpack 4 (dev and prod) and only in dev mode in webpack 5. Any ideas how can we improve comlink support for webpack 5 in prod?

put worker scripts into index.html at build time

Hi there,

is there an option to put the generated scripts for the workers inside index.html at build time? we use publicPath="#CDN#" and this placeholder is replaced when the server parses the generated index.html with a cdn url that i cannot know at build time. So my config looks :

config.module .rule("comlink worker") .test(/\.worker\.js$/i) .use("comlink") .loader("comlink-loader") .options({ singleton: true, name:staticV2/${buildNum}/js/[name].[hash:8].[ext] }) .end();

and it looks like this workers files are bundled in another script like so: return new Worker(r.p+"staticV2/TAG/js/formParser.worker.ea9dda30.js")}}

so this means that the server wont be able to replace that #CDN# placeholder and will result in an invalid path for this resource. e.g: #CDN#/staticV2/TAG/js/formParser.worker.ea9dda30.js'
I have tried to pass an option publicPath: "" at least to try to load them from the actual server that makes the initial GET but no success.

Is there a solution you can suggest for my use case?
Thanks

Not generating a web worker script

I have a setup with cra 3.4.3 with webpack 4.42.0 and storybook. I need the cra build to use comlink-loader and the storybook static build to ignore it (because when i run storyshots, the web worker loading fails with the following
Failed to construct Worker. Cannot be accessed from Origin null , logical since the page gets loaded using file:///

I changed my setup as follows to use singleton mode since i figured it would be easier to use different webpack configs for cra and storybook

the module that will become a worker

/* /src/workers/fuseSearch.worker.ts */

import Fuse from "fuse.js";
import { TRow } from "../types/Objects";

export async function fuseSearch(data: TRow[], options: any): Promise<TRow[]> {
    // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
    //@ts-ignore
    // eslint-disable-next-line
    if (typeof self === "object" && self.document !== undefined && self.document === document) {
        console.log("running on main thread");
    } else {
        //were this a web worker, self would be instanceof DedicatedWorkerGlobalScope and self.document undefined
        console.log("running in web worker");
    }
    const { field, term } = options;
    const fuse = new Fuse(data, {
        keys: ["data", field],
        useExtendedSearch: true,
    });
    const searchTerm = term
        .trim()
        .split(" ")
        .join(" '");
    return fuse.search(`'${searchTerm}`).map(({ item }) => item);
}

I then call my worker as outlined in the documentation, with await

import { fuseSearch } from "../workers/fuseSearch.worker";
...
useEffect(() => {
    async function runSearch() {
        const result = await fuseSearch(available, { field, term });
        setFilterResult(result);
    }
    runSearch();
}, [...]);

my cra webpack config (using react-app-rewired)

//config-overrides.js
module.exports = function override(config) {
    // fails when i append to the rules array, prepending seems to go through
    config.module.rules.shift({
        test: /\.worker\.(js|ts)$/i,
        use: [
            {
                loader: "comlink-loader",
                options: {
                    singleton: true,
                },
            },
        ],
    });
    return config;
};

and my storybook webpack config simply doesn't declare a comlink-loader therefore skipping the web worker wrapping altogether.

problem 1

I see no webworker in my sources tab, and fuseSearch runs on the main thread! comlink-loader does not generate a script for the worker.
Is the config i outlined above valid? why is not generating a web worker script?

problem 2

When i changed the config override to have cofing.modules.rules.push instead of cofing.modules.rules.shift I got the following error message

Uncaught Error: Module parse failed: Unexpected token (5:36)
File was processed with these loaders:
* ./node_modules/comlink-loader/dist/comlink-worker-loader.js
* ./node_modules/eslint-loader/dist/cjs.js
* ./node_modules/eslint-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
| import { TRow } from "../types/Objects";
|
> export async function runWorker(data: TRow[], options: any): Promise<TRow[]> {
| const { field, term } = options;
| const fuse = new Fuse(data, {
at Object../node_modules/comlink-loader/dist/comlink-worker-loader.js!./node_modules/eslint->
loader/dist/cjs.js?!./node_modules/eslint-loader/dist/cjs.js?!./src/workers/fuseWorkerImpl.worker.ts (bootstrap:83)

which i assume is logical? because the comlink-loader needs to run first?

Edit: specified webpack and react-scripts versions

Working fine locally but throwing a TypeError when deployed to production.

I was using this package to offload some CPU intensive calculations and stop browsers from saying the tab had crashed, and it was all working absolutely fine when hosting the site locally on my machine.

However, upon publishing the site to production (hosted on GitHub Pages using gh-pages), the web-worker no longer runs, and instead throws this error:

image

I have no idea where to start on debugging this. I would've assumed that, because it worked perfectly locally, it would also work perfectly when published live.

Any thoughts? I can provide more info if you know what would be helpful.

Using WASM modules in Comlink-ed Webworker

For my project I have a WASM (Rust based) module imported as a package using wasm-pack.
In the regular (non-Web Worker) workflow the package works just fine, but when I put everything under comlink-loader things start to break and I get

_wasm_bg_wasm__WEBPACK_IMPORTED_MODULE_0__.add_two_ints is not a function

initially coming from

callback
src/comlink.ts:312
  309 |   break;
  310 | case MessageType.APPLY:
  311 |   {
> 312 |     returnValue = rawValue.apply(parent, argumentList);
      | ^  313 |   }
  314 |   break;
  315 | case MessageType.CONSTRUCT:

is there a good way to keep comlink-loader and fix that?

support multiple instances via webpack options

When I try to use the options.multiple = true feature via my webpack config like so:

module: {
      {
        test: /\.worker\.js$/,
        use: {
          loader: 'comlink-loader',
          options: { inline: true, multiple: false }
        },
      },
}

I get this error:

Module build failed: ValidationError: Worker Loader Invalid Options
options['multiple'] is an invalid additional property

A workaround is to just delete that property in the options object after it is checked.

TypeError: Worker is not a function

I'm trying to implement comlink into a project. I'm currently getting a TypeError: Worker is not a function error thrown in the console but the code compiles fine without any warnings or errors.

"comlink": "^4.3.0"
"comlink-loader": "^2.0.0"

How I'm using comlink-loader:

import MyWorker from "comlink-loader!./assets/worker.js"

const worker = new MyWorker()

I also want to inline the workers so they are included within the webpack generated bundle. Is this possible?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.