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 2a02910..e6e8724 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); @@ -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()); 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 b0a3918..5624ddb 100644 --- a/test/sass-loader-example/webpack.config.js +++ b/test/sass-loader-example/webpack.config.js @@ -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']); 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, + }); +});