Skip to content

Commit 3766560

Browse files
authoredApr 10, 2021
fix: support serialization of RegExp (#102)
1 parent f3c9b7f commit 3766560

File tree

7 files changed

+63
-4
lines changed

7 files changed

+63
-4
lines changed
 

‎src/WorkerPool.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import asyncMapSeries from 'neo-async/mapSeries';
77

88
import readBuffer from './readBuffer';
99
import WorkerError from './WorkerError';
10+
import { replacer, reviver } from './serializer';
1011

1112
const workerPath = require.resolve('./worker');
1213

@@ -107,7 +108,7 @@ class PoolWorker {
107108

108109
writeJson(data) {
109110
const lengthBuffer = Buffer.alloc(4);
110-
const messageBuffer = Buffer.from(JSON.stringify(data), 'utf-8');
111+
const messageBuffer = Buffer.from(JSON.stringify(data, replacer), 'utf-8');
111112
lengthBuffer.writeInt32BE(messageBuffer.length, 0);
112113
this.writePipe.write(lengthBuffer);
113114
this.writePipe.write(messageBuffer);
@@ -141,7 +142,7 @@ class PoolWorker {
141142
}
142143
this.state = 'message read';
143144
const messageString = messageBuffer.toString('utf-8');
144-
const message = JSON.parse(messageString);
145+
const message = JSON.parse(messageString, reviver);
145146
this.state = 'process message';
146147
this.onWorkerMessage(message, (err) => {
147148
if (err) {

‎src/serializer.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
export function replacer(_key, value) {
2+
if (value instanceof RegExp) {
3+
return {
4+
__serialized_type: 'RegExp',
5+
source: value.source,
6+
flags: value.flags,
7+
};
8+
}
9+
return value;
10+
}
11+
12+
export function reviver(_key, value) {
13+
if (typeof value === 'object' && value !== null) {
14+
// eslint-disable-next-line no-underscore-dangle
15+
if (value.__serialized_type === 'RegExp') {
16+
return new RegExp(value.source, value.flags);
17+
}
18+
}
19+
20+
return value;
21+
}

‎src/worker.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import loaderRunner from 'loader-runner';
66
import asyncQueue from 'neo-async/queue';
77

88
import readBuffer from './readBuffer';
9+
import { replacer, reviver } from './serializer';
910

1011
const writePipe = fs.createWriteStream(null, { fd: 3 });
1112
const readPipe = fs.createReadStream(null, { fd: 4 });
@@ -93,7 +94,7 @@ function writeJson(data) {
9394
});
9495

9596
const lengthBuffer = Buffer.alloc(4);
96-
const messageBuffer = Buffer.from(JSON.stringify(data), 'utf-8');
97+
const messageBuffer = Buffer.from(JSON.stringify(data, replacer), 'utf-8');
9798
lengthBuffer.writeInt32BE(messageBuffer.length, 0);
9899

99100
writePipeWrite(lengthBuffer);
@@ -319,7 +320,7 @@ function readNextMessage() {
319320
return;
320321
}
321322
const messageString = messageBuffer.toString('utf-8');
322-
const message = JSON.parse(messageString);
323+
const message = JSON.parse(messageString, reviver);
323324

324325
onMessage(message);
325326
setImmediate(() => readNextMessage());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
$white: #FFFFFF;

‎test/sass-loader-example/style.scss

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
@import '_shared';
2+
@import 'color_palette';
23

34
body {
45
background: red;

‎test/sass-loader-example/webpack.config.js

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ module.exports = (env) => {
1616
};
1717
const sassLoaderOptions = {
1818
sourceMap: true,
19+
sassOptions: {
20+
includePaths: [path.resolve(__dirname, 'assets')],
21+
},
1922
};
2023
if (+env.threads > 0) {
2124
threadLoader.warmup(workerPool, ['babel-loader', 'babel-preset-env']);

‎test/serializer.test.js

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
const { replacer, reviver } = require('../src/serializer');
2+
3+
test('round-trips plain objects', () => {
4+
const json = JSON.stringify(
5+
{
6+
a: 1,
7+
b: 'foo',
8+
c: [null, false],
9+
},
10+
replacer
11+
);
12+
expect(JSON.parse(json, reviver)).toEqual({
13+
a: 1,
14+
b: 'foo',
15+
c: [null, false],
16+
});
17+
});
18+
19+
test('round-trips regular expressions', () => {
20+
const json = JSON.stringify(
21+
{
22+
r: /hoge/g,
23+
s: /^(\w\s)+$/m,
24+
},
25+
replacer
26+
);
27+
expect(JSON.parse(json, reviver)).toEqual({
28+
r: /hoge/g,
29+
s: /^(\w\s)+$/m,
30+
});
31+
});

0 commit comments

Comments
 (0)
Please sign in to comment.