A collection of plugins for improving the developer experience with Web Workers and Worker Threads across different bundlers and environments.
- Node.js: >=20.0.0
- pnpm: >=8.0.0 (for development)
- @easythread/core - Core transformer with strategy pattern for different environments
- @easythread/vite - Vite plugin for browser environments (Web Workers)
- @easythread/rollup - Rollup plugin for Node.js environments (Worker Threads)
npm install @easythread/vite
# or
pnpm add @easythread/vitenpm install @easythread/rollup
# or
pnpm add @easythread/rollup// vite.config.jsimport{defineConfig}from'vite'importeasythreadPluginfrom'@easythread/vite'exportdefaultdefineConfig({plugins: [easythreadPlugin()],})// rollup.config.jsimporteasythreadPluginfrom'@easythread/rollup'exportdefault{plugins: [easythreadPlugin()],}/** @easythread */functionheavyComputation(data: number[]){letresult=0;for(leti=0;i<data.length;i++){result+=Math.pow(data[i],2);}console.log("Result",result);}// Use the function as if it's running on the main threadconstdata=[1,2,3,4,5];heavyComputation(data);// Main thread continues execution immediatelyconsole.log("Main thread is not blocked!");/** @easythread */asyncfunctioncomplexCalculation(x: number,y: number): Promise<number>{// Simulate a time-consuming calculationreturnPromise.resolve(x*y+Math.sqrt(x+y));}// Use the function and handle the returned promisecomplexCalculation(10,20).then((result)=>{console.log("Calculation result:",result);});console.log("This will be logged immediately, before the calculation completes.");/** @easythread */(()=>{console.log("This is an anonymous function running in a worker thread");// Perform some heavy computation herefor(leti=0;i<1000000000;i++){// Simulating complex work}console.log("Anonymous function completed its work");})();console.log("Main thread continues execution immediately");Easythread can automatically detect and pass variables that are defined outside the function's scope:
constmultiplier=2;constmessage="Calculation complete!";/** @easythread */functionoutOfScopeExample(x: number): Promise<number>{constresult=x*multiplier;console.log(message,result);returnPromise.resolve(result);}outOfScopeExample(10).then((result)=>{console.log("Result:",result);});In this example, multiplier and message are automatically detected and passed to the worker thread.
Easythread now supports using imported functions and values within worker threads:
import{calculateHash}from'crypto-lib';importutilsfrom'./utils';/** @easythread */asyncfunctionprocessData(data: string): Promise<string>{consthash=calculateHash(data);constresult=utils.transform(hash);returnresult;}// The function will automatically import the required modules in the workerconstresult=awaitprocessData("some data");- Named imports:
import { func } from 'module'✅ - Default imports:
import module from 'module'✅ - Namespace imports:
import * as module from 'module'✅ - Relative imports:
import { func } from './local-module'✅ - Dynamic loading: Imports are loaded dynamically when the worker starts
While Easythread can handle most primitive values and plain objects, there are some limitations on what can be passed to a worker thread:
- Functions: Worker threads cannot receive functions as arguments or use functions from the outer scope.
- DOM elements: Workers don't have access to the DOM, so DOM elements can't be passed or used.
- Complex objects: Objects with circular references or those that can't be cloned (like Symbols) cannot be passed to workers.
- Class instances: Instances of custom classes may lose their methods when passed to a worker.
- Some node_modules: Not all npm packages are compatible with Web Workers (e.g., those requiring Node.js APIs or DOM access).