From e6a3b94ffc0aff474d1c74e205b1ddcb7e288f1c Mon Sep 17 00:00:00 2001 From: liaohuanyu Date: Sun, 19 Dec 2021 15:42:47 +0800 Subject: [PATCH] feat: support function for loader sunch as css-loader #58 --- example/webpack.config.js | 12 ++++++++++++ src/WorkerPool.js | 25 ++++++++++++++++++++++++- src/serializer.js | 13 +++++++++++++ src/workerPools.js | 1 + 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/example/webpack.config.js b/example/webpack.config.js index 6fd4ecb..1ff66b5 100644 --- a/example/webpack.config.js +++ b/example/webpack.config.js @@ -12,6 +12,7 @@ module.exports = (env = {}) => { poolTimeout: env.watch ? Infinity : 2000, }; const workerPoolSass = { + workerAllowedFunctions: ['cssLoaderGetLocalIdent'], workers: +env.threads, workerParallelJobs: 2, poolTimeout: env.watch ? Infinity : 2000, @@ -50,6 +51,17 @@ module.exports = (env = {}) => { loader: path.resolve(__dirname, '../dist/index.js'), options: workerPoolSass, }, + { + loader: 'css-loader', + options: { + modules: { + getLocalIdent: function cssLoaderGetLocalIdent() { + console.log('getLocalIdent called'); + return null; + }, + }, + }, + }, 'css-loader', 'sass-loader', ].filter(Boolean), diff --git a/src/WorkerPool.js b/src/WorkerPool.js index ba4bd72..84717c8 100644 --- a/src/WorkerPool.js +++ b/src/WorkerPool.js @@ -21,6 +21,7 @@ class PoolWorker { this.activeJobs = 0; this.onJobDone = onJobDone; this.id = workerId; + this.allowedFunctions = options.allowedFunctions; workerId += 1; // Empty or invalid node args would break the child process @@ -106,9 +107,29 @@ class PoolWorker { }); } + getReplacer() { + return (key, value) => { + if ( + value instanceof Function && + Array.isArray(this.allowedFunctions) && + this.allowedFunctions.includes(value.name) + ) { + return { + __serialized_type: 'Function', + fnBody: value.toString(), + args: new Array(value.length).fill('a').map((i, dx) => `${i}${dx}`), + }; + } + return replacer(key, value); + }; + } + writeJson(data) { const lengthBuffer = Buffer.alloc(4); - const messageBuffer = Buffer.from(JSON.stringify(data, replacer), 'utf-8'); + const messageBuffer = Buffer.from( + JSON.stringify(data, this.getReplacer()), + 'utf-8' + ); lengthBuffer.writeInt32BE(messageBuffer.length, 0); this.writePipe.write(lengthBuffer); this.writePipe.write(messageBuffer); @@ -323,6 +344,7 @@ export default class WorkerPool { this.poolTimeout = options.poolTimeout; this.workerNodeArgs = options.workerNodeArgs; this.workerParallelJobs = options.workerParallelJobs; + this.workerAllowedFunctions = options.workerAllowedFunctions; this.workers = new Set(); this.activeJobs = 0; this.timeout = null; @@ -389,6 +411,7 @@ export default class WorkerPool { { nodeArgs: this.workerNodeArgs, parallelJobs: this.workerParallelJobs, + allowedFunctions: this.workerAllowedFunctions, }, () => this.onJobDone() ); diff --git a/src/serializer.js b/src/serializer.js index a27098a..883065b 100644 --- a/src/serializer.js +++ b/src/serializer.js @@ -15,6 +15,19 @@ export function reviver(_key, value) { if (value.__serialized_type === 'RegExp') { return new RegExp(value.source, value.flags); } + // eslint-disable-next-line no-underscore-dangle + else if (value.__serialized_type === 'Function') { + // eslint-disable-next-line no-new-func + return new Function( + ...value.args, + ` try { + return (${value.fnBody})(${value.args.join(',')}) + } catch(err) { + console.error("[Invalid Function call]", err); + } + ` + ); + } } return value; diff --git a/src/workerPools.js b/src/workerPools.js index 1ac2a04..5680e1b 100644 --- a/src/workerPools.js +++ b/src/workerPools.js @@ -22,6 +22,7 @@ function getPool(options) { poolTimeout: options.poolTimeout || 500, poolParallelJobs: options.poolParallelJobs || 200, poolRespawn: options.poolRespawn || false, + workerAllowedFunctions: options.workerAllowedFunctions || [], }; const tpKey = JSON.stringify(workerPoolOptions);