Skip to content

Commit

Permalink
fix: support serialization of RegExp (#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
qnighy authored Apr 10, 2021
1 parent f3c9b7f commit 3766560
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 4 deletions.
5 changes: 3 additions & 2 deletions src/WorkerPool.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down
21 changes: 21 additions & 0 deletions src/serializer.js
Original file line number Diff line number Diff line change
@@ -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;
}
5 changes: 3 additions & 2 deletions src/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -319,7 +320,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());
Expand Down
1 change: 1 addition & 0 deletions test/sass-loader-example/assets/color_palette.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$white: #FFFFFF;
1 change: 1 addition & 0 deletions test/sass-loader-example/style.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@import '_shared';
@import 'color_palette';

body {
background: red;
Expand Down
3 changes: 3 additions & 0 deletions test/sass-loader-example/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ module.exports = (env) => {
};
const sassLoaderOptions = {
sourceMap: true,
sassOptions: {
includePaths: [path.resolve(__dirname, 'assets')],
},
};
if (+env.threads > 0) {
threadLoader.warmup(workerPool, ['babel-loader', 'babel-preset-env']);
Expand Down
31 changes: 31 additions & 0 deletions test/serializer.test.js
Original file line number Diff line number Diff line change
@@ -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,
});
});

0 comments on commit 3766560

Please sign in to comment.