From 7e95afcaedd8ac12c37d55500dc496b3db579e1e Mon Sep 17 00:00:00 2001 From: Masaki Hara Date: Wed, 30 Sep 2020 12:01:37 +0900 Subject: [PATCH 1/2] fix: support serialization of RegExp --- src/WorkerPool.js | 5 +++-- src/serializer.js | 21 +++++++++++++++++++++ src/worker.js | 5 +++-- test/serializer.test.js | 31 +++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 src/serializer.js create mode 100644 test/serializer.test.js diff --git a/src/WorkerPool.js b/src/WorkerPool.js index 86d091c..ba4bd72 100644 --- a/src/WorkerPool.js +++ b/src/WorkerPool.js @@ -7,6 +7,7 @@ import asyncMapSeries from 'neo-async/mapSeries'; import readBuffer from './readBuffer'; import WorkerError from './WorkerError'; +import { replacer, reviver } from './serializer'; const workerPath = require.resolve('./worker'); @@ -107,7 +108,7 @@ class PoolWorker { writeJson(data) { const lengthBuffer = Buffer.alloc(4); - const messageBuffer = Buffer.from(JSON.stringify(data), 'utf-8'); + const messageBuffer = Buffer.from(JSON.stringify(data, replacer), 'utf-8'); lengthBuffer.writeInt32BE(messageBuffer.length, 0); this.writePipe.write(lengthBuffer); this.writePipe.write(messageBuffer); @@ -141,7 +142,7 @@ class PoolWorker { } this.state = 'message read'; const messageString = messageBuffer.toString('utf-8'); - const message = JSON.parse(messageString); + const message = JSON.parse(messageString, reviver); this.state = 'process message'; this.onWorkerMessage(message, (err) => { if (err) { diff --git a/src/serializer.js b/src/serializer.js new file mode 100644 index 0000000..a27098a --- /dev/null +++ b/src/serializer.js @@ -0,0 +1,21 @@ +export function replacer(_key, value) { + if (value instanceof RegExp) { + return { + __serialized_type: 'RegExp', + source: value.source, + flags: value.flags, + }; + } + return value; +} + +export function reviver(_key, value) { + if (typeof value === 'object' && value !== null) { + // eslint-disable-next-line no-underscore-dangle + if (value.__serialized_type === 'RegExp') { + return new RegExp(value.source, value.flags); + } + } + + return value; +} diff --git a/src/worker.js b/src/worker.js index f619d1d..7b8f475 100644 --- a/src/worker.js +++ b/src/worker.js @@ -6,6 +6,7 @@ import loaderRunner from 'loader-runner'; import asyncQueue from 'neo-async/queue'; import readBuffer from './readBuffer'; +import { replacer, reviver } from './serializer'; const writePipe = fs.createWriteStream(null, { fd: 3 }); const readPipe = fs.createReadStream(null, { fd: 4 }); @@ -93,7 +94,7 @@ function writeJson(data) { }); const lengthBuffer = Buffer.alloc(4); - const messageBuffer = Buffer.from(JSON.stringify(data), 'utf-8'); + const messageBuffer = Buffer.from(JSON.stringify(data, replacer), 'utf-8'); lengthBuffer.writeInt32BE(messageBuffer.length, 0); writePipeWrite(lengthBuffer); @@ -318,7 +319,7 @@ function readNextMessage() { return; } const messageString = messageBuffer.toString('utf-8'); - const message = JSON.parse(messageString); + const message = JSON.parse(messageString, reviver); onMessage(message); setImmediate(() => readNextMessage()); diff --git a/test/serializer.test.js b/test/serializer.test.js new file mode 100644 index 0000000..a39e444 --- /dev/null +++ b/test/serializer.test.js @@ -0,0 +1,31 @@ +const { replacer, reviver } = require('../src/serializer'); + +test('round-trips plain objects', () => { + const json = JSON.stringify( + { + a: 1, + b: 'foo', + c: [null, false], + }, + replacer + ); + expect(JSON.parse(json, reviver)).toEqual({ + a: 1, + b: 'foo', + c: [null, false], + }); +}); + +test('round-trips regular expressions', () => { + const json = JSON.stringify( + { + r: /hoge/g, + s: /^(\w\s)+$/m, + }, + replacer + ); + expect(JSON.parse(json, reviver)).toEqual({ + r: /hoge/g, + s: /^(\w\s)+$/m, + }); +}); From 45126bd4f6bf606d5162062bbc6f373bab4ebce7 Mon Sep 17 00:00:00 2001 From: Masaki Hara Date: Thu, 18 Mar 2021 19:46:44 +0900 Subject: [PATCH 2/2] test: add tests against 'rule.test is not a function' --- test/sass-loader-example/assets/color_palette.scss | 1 + test/sass-loader-example/style.scss | 1 + test/sass-loader-example/webpack.config.js | 9 ++++++++- 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 test/sass-loader-example/assets/color_palette.scss diff --git a/test/sass-loader-example/assets/color_palette.scss b/test/sass-loader-example/assets/color_palette.scss new file mode 100644 index 0000000..f84acf0 --- /dev/null +++ b/test/sass-loader-example/assets/color_palette.scss @@ -0,0 +1 @@ +$white: #FFFFFF; diff --git a/test/sass-loader-example/style.scss b/test/sass-loader-example/style.scss index f4daeb7..ba183c6 100644 --- a/test/sass-loader-example/style.scss +++ b/test/sass-loader-example/style.scss @@ -1,4 +1,5 @@ @import '_shared'; +@import 'color_palette'; body { background: red; diff --git a/test/sass-loader-example/webpack.config.js b/test/sass-loader-example/webpack.config.js index ae38278..5bab1f4 100644 --- a/test/sass-loader-example/webpack.config.js +++ b/test/sass-loader-example/webpack.config.js @@ -47,7 +47,14 @@ module.exports = (env) => { options: workerPoolSass, }, 'css-loader', - 'sass-loader', + { + loader: 'sass-loader', + options: { + sassOptions: { + includePaths: [path.resolve(__dirname, 'assets')], + }, + }, + }, ].filter(Boolean), }, ],