Skip to content
This repository was archived by the owner on Dec 5, 2019. It is now read-only.

Commit 8d7ebcd

Browse files
evilebottnawimichael-ciniawsky
authored andcommitted
refactor: use serialize-javascript package instead own implementation (#183)
1 parent d97ab11 commit 8d7ebcd

10 files changed

+68
-125
lines changed

package-lock.json

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"dependencies": {
3333
"cacache": "^10.0.0",
3434
"find-cache-dir": "^1.0.0",
35+
"serialize-javascript": "^1.4.0",
3536
"schema-utils": "^0.3.0",
3637
"source-map": "^0.6.1",
3738
"uglify-es": "^3.2.0",

src/index.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import { SourceMapSource, RawSource, ConcatSource } from 'webpack-sources';
88
import RequestShortener from 'webpack/lib/RequestShortener';
99
import ModuleFilenameHelpers from 'webpack/lib/ModuleFilenameHelpers';
1010
import validateOptions from 'schema-utils';
11+
import serialize from 'serialize-javascript';
1112
import schema from './options.json';
1213
import Uglify from './uglify';
13-
import { encode } from './uglify/serialization';
1414
import versions from './uglify/versions';
1515

1616
/* eslint-disable
@@ -155,13 +155,13 @@ class UglifyJsPlugin {
155155
};
156156

157157
if (this.options.cache) {
158-
task.cacheKey = JSON.stringify({
158+
task.cacheKey = serialize({
159159
'uglify-es': versions.uglify,
160160
'uglifyjs-webpack-plugin': versions.plugin,
161161
'uglifyjs-webpack-plugin-options': this.options,
162162
path: compiler.outputPath ? `${compiler.outputPath}/${file}` : file,
163163
input,
164-
}, encode);
164+
});
165165
}
166166

167167
tasks.push(task);

src/uglify/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import os from 'os';
22
import cacache from 'cacache';
33
import findCacheDir from 'find-cache-dir';
44
import workerFarm from 'worker-farm';
5+
import serialize from 'serialize-javascript';
56
import minify from './minify';
6-
import { encode } from './serialization';
77

88
let workerFile = require.resolve('./worker');
99

@@ -28,7 +28,7 @@ export default class {
2828
if (this.maxConcurrentWorkers > 0) {
2929
const workerOptions = process.platform === 'win32' ? { maxConcurrentWorkers: this.maxConcurrentWorkers, maxConcurrentCallsPerWorker: 1 } : { maxConcurrentWorkers: this.maxConcurrentWorkers };
3030
this.workers = workerFarm(workerOptions, workerFile);
31-
this.boundWorkers = (options, cb) => this.workers(JSON.stringify(options, encode), cb);
31+
this.boundWorkers = (options, cb) => this.workers(serialize(options), cb);
3232
} else {
3333
this.boundWorkers = (options, cb) => {
3434
try {

src/uglify/serialization.js

-34
This file was deleted.

src/uglify/worker.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import minify from './minify';
2-
import { decode } from './serialization';
32

43
module.exports = (options, callback) => {
54
try {
6-
callback(null, minify(JSON.parse(options, decode)));
5+
// 'use strict' => this === undefined (Clean Scope)
6+
// Safer for possible security issues, albeit not critical at all here
7+
// eslint-disable-next-line no-new-func, no-param-reassign
8+
options = new Function(`'use strict'\nreturn ${options}`)();
9+
10+
callback(null, minify(options));
711
} catch (errors) {
812
callback(errors);
913
}

test/__snapshots__/cache-options.test.js.snap

+28-28
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,6 @@ exports[`cache \`string\`: asset main.0c220ec66316af2c1b24.js 1`] = `"webpackJso
1212

1313
exports[`cache \`string\`: asset manifest.6afe1bc6685e9ab36c1c.js 1`] = `"!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,a){for(var i,u,f,l=0,s=[];l<t.length;l++)u=t[l],o[u]&&s.push(o[u][0]),o[u]=0;for(i in c)Object.prototype.hasOwnProperty.call(c,i)&&(e[i]=c[i]);for(r&&r(t,c,a);s.length;)s.shift()();if(a)for(l=0;l<a.length;l++)f=n(n.s=a[l]);return f};var t={},o={1:0};n.e=function(e){function r(){i.onerror=i.onload=null,clearTimeout(u);var n=o[e];0!==n&&(n&&n[1](new Error(\\"Loading chunk \\"+e+\\" failed.\\")),o[e]=void 0)}var t=o[e];if(0===t)return new Promise(function(e){e()});if(t)return t[2];var c=new Promise(function(n,r){t=o[e]=[n,r]});t[2]=c;var a=document.getElementsByTagName(\\"head\\")[0],i=document.createElement(\\"script\\");i.type=\\"text/javascript\\",i.charset=\\"utf-8\\",i.async=!0,i.timeout=12e4,n.nc&&i.setAttribute(\\"nonce\\",n.nc),i.src=n.p+\\"\\"+e+\\".\\"+({0:\\"main\\"}[e]||e)+\\".\\"+{0:\\"0c220ec66316af2c1b24\\"}[e]+\\".js\\";var u=setTimeout(r,12e4);return i.onerror=i.onload=r,a.appendChild(i),c},n.m=e,n.c=t,n.d=function(e,r,t){n.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,\\"a\\",r),r},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p=\\"\\",n.oe=function(e){throw console.error(e),e}}([]);"`;
1414

15-
exports[`cache \`string\`: cached entry test.js 1`] = `
16-
Array [
17-
"test.js",
18-
"function test(foo) { foo = 1; }",
19-
]
20-
`;
21-
22-
exports[`cache \`string\`: cached entry test1.js 1`] = `
23-
Array [
24-
"test1.js",
25-
"function test1(foo) { foo = 1; }",
26-
]
27-
`;
28-
29-
exports[`cache \`string\`: cached entry test2.js 1`] = `
30-
Array [
31-
"test2.js",
32-
"function test2(foo) { foo = 1; }",
33-
]
34-
`;
35-
36-
exports[`cache \`string\`: cached entry test3.js 1`] = `
37-
Array [
38-
"test3.js",
39-
"function test3(foo) { foo = 1; }",
40-
]
41-
`;
42-
4315
exports[`cache \`string\`: errors 1`] = `Array []`;
4416

4517
exports[`cache \`string\`: warnings 1`] = `Array []`;
@@ -55,27 +27,55 @@ Array [
5527
]
5628
`;
5729

30+
exports[`cache \`true\`: cached entry test.js 2`] = `
31+
Array [
32+
"test.js",
33+
"function test(foo) { foo = 1; }",
34+
]
35+
`;
36+
5837
exports[`cache \`true\`: cached entry test1.js 1`] = `
5938
Array [
6039
"test1.js",
6140
"function test1(foo) { foo = 1; }",
6241
]
6342
`;
6443

44+
exports[`cache \`true\`: cached entry test1.js 2`] = `
45+
Array [
46+
"test1.js",
47+
"function test1(foo) { foo = 1; }",
48+
]
49+
`;
50+
6551
exports[`cache \`true\`: cached entry test2.js 1`] = `
6652
Array [
6753
"test2.js",
6854
"function test2(foo) { foo = 1; }",
6955
]
7056
`;
7157

58+
exports[`cache \`true\`: cached entry test2.js 2`] = `
59+
Array [
60+
"test2.js",
61+
"function test2(foo) { foo = 1; }",
62+
]
63+
`;
64+
7265
exports[`cache \`true\`: cached entry test3.js 1`] = `
7366
Array [
7467
"test3.js",
7568
"function test3(foo) { foo = 1; }",
7669
]
7770
`;
7871

72+
exports[`cache \`true\`: cached entry test3.js 2`] = `
73+
Array [
74+
"test3.js",
75+
"function test3(foo) { foo = 1; }",
76+
]
77+
`;
78+
7979
exports[`cache \`true\`: errors 1`] = `Array []`;
8080

8181
exports[`cache \`true\`: warnings 1`] = `Array []`;

test/cache-options.test.js

+16-14
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@ describe('when options.cache', () => {
112112
cacache
113113
.ls(cacheDir)
114114
.then((cacheEntriesList) => {
115-
const cacheEntriesListKeys = Object.keys(cacheEntriesList);
115+
const cacheKeys = Object.keys(cacheEntriesList);
116116

117-
expect(cacheEntriesListKeys.length).toBe(0);
117+
expect(cacheKeys.length).toBe(0);
118118
done();
119119
});
120120
});
@@ -231,15 +231,16 @@ describe('when options.cache', () => {
231231
cacache
232232
.ls(cacheDir)
233233
.then((cacheEntriesList) => {
234-
const cacheEntriesListKeys = Object.keys(cacheEntriesList);
234+
const cacheKeys = Object.keys(cacheEntriesList);
235235

236236
// Make sure that we cached files
237-
expect(cacheEntriesListKeys.length).toBe(files.length);
238-
cacheEntriesListKeys.forEach((cacheJSONEntry) => {
239-
const cacheEntry = JSON.parse(cacheJSONEntry);
237+
expect(cacheKeys.length).toBe(files.length);
238+
cacheKeys.forEach((cacheEntry) => {
239+
// eslint-disable-next-line no-new-func
240+
const cacheEntryOptions = new Function(`'use strict'\nreturn ${cacheEntry}`)();
240241

241-
expect([cacheEntry.path, cacheEntry.input])
242-
.toMatchSnapshot(`cache \`true\`: cached entry ${cacheEntry.path}`);
242+
expect([cacheEntryOptions.path, cacheEntryOptions.input])
243+
.toMatchSnapshot(`cache \`true\`: cached entry ${cacheEntryOptions.path}`);
243244
});
244245

245246
// Reset compilation assets and mocks
@@ -374,15 +375,16 @@ describe('when options.cache', () => {
374375
cacache
375376
.ls(othercacheDir)
376377
.then((cacheEntriesList) => {
377-
const cacheEntriesListKeys = Object.keys(cacheEntriesList);
378+
const cacheKeys = Object.keys(cacheEntriesList);
378379

379380
// Make sure that we cached files
380-
expect(cacheEntriesListKeys.length).toBe(files.length);
381-
cacheEntriesListKeys.forEach((cacheJSONEntry) => {
382-
const cacheEntry = JSON.parse(cacheJSONEntry);
381+
expect(cacheKeys.length).toBe(files.length);
382+
cacheKeys.forEach((cacheEntry) => {
383+
// eslint-disable-next-line no-new-func
384+
const cacheEntryOptions = new Function(`'use strict'\nreturn ${cacheEntry}`)();
383385

384-
expect([cacheEntry.path, cacheEntry.input])
385-
.toMatchSnapshot(`cache \`string\`: cached entry ${cacheEntry.path}`);
386+
expect([cacheEntryOptions.path, cacheEntryOptions.input])
387+
.toMatchSnapshot(`cache \`true\`: cached entry ${cacheEntryOptions.path}`);
386388
});
387389

388390
// Reset compilation assets and mocks

test/uglify/serialization.test.js

-35
This file was deleted.

test/uglify/worker.test.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import serialize from 'serialize-javascript';
12
import worker from '../../src/uglify/worker';
2-
import { encode } from '../../src/uglify/serialization';
33

44
describe('matches snapshot', () => {
55
it('normalizes when options.extractComments is regex', () => {
@@ -8,7 +8,7 @@ describe('matches snapshot', () => {
88
input: 'var foo = 1;/* hello */',
99
extractComments: /foo/,
1010
};
11-
worker(JSON.stringify(options, encode), (error, data) => {
11+
worker(serialize(options), (error, data) => {
1212
if (error) {
1313
throw error;
1414
}
@@ -26,7 +26,7 @@ describe('matches snapshot', () => {
2626
},
2727
},
2828
};
29-
worker(JSON.stringify(options, encode), (error, data) => {
29+
worker(serialize(options), (error, data) => {
3030
if (error) {
3131
throw error;
3232
}
@@ -44,7 +44,7 @@ describe('matches snapshot', () => {
4444
},
4545
},
4646
};
47-
worker(JSON.stringify(options, encode), (error, data) => {
47+
worker(serialize(options), (error, data) => {
4848
if (error) {
4949
throw error;
5050
}
@@ -63,7 +63,7 @@ describe('matches snapshot', () => {
6363
},
6464
extractComments: 1,
6565
};
66-
worker(JSON.stringify(options, encode), (error, data) => {
66+
worker(serialize(options), (error, data) => {
6767
if (error) {
6868
throw error;
6969
}
@@ -90,7 +90,7 @@ describe('matches snapshot', () => {
9090
},
9191
},
9292
};
93-
worker(JSON.stringify(options, encode), (error, data) => {
93+
worker(serialize(options), (error, data) => {
9494
if (error) {
9595
throw error;
9696
}
@@ -109,7 +109,7 @@ describe('matches snapshot', () => {
109109
mappings: 'AAAA,QAASA,KAAIC,GACT,GAAIA,EAAG,CACH,MAAOC,MACPC',
110110
},
111111
};
112-
worker(JSON.stringify(options, encode), (error, data) => {
112+
worker(serialize(options), (error, data) => {
113113
if (error) {
114114
throw error;
115115
}

0 commit comments

Comments
 (0)