Skip to content

Commit 2da0378

Browse files
committed
fix(pack): 修复自身版本号使用 webpack-md5-hash 时问题
1 parent c814175 commit 2da0378

File tree

8 files changed

+125
-54
lines changed

8 files changed

+125
-54
lines changed

lib/models/Config.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
88

99
var path = require('path');
1010
var ExtractTextPlugin = require('extract-text-webpack-plugin');
11-
var WebpackMd5Hash = require('webpack-md5-hash');
1211

1312
var normalize = require('../utils/path').normalize;
1413

@@ -61,10 +60,7 @@ var Config = function () {
6160
},
6261
plugins: [
6362
// local plugin
64-
require('../plugins/extTemplatedPathPlugin.js'), require('../plugins/requireModulePlugin.js'),
65-
66-
// vender plugin
67-
new WebpackMd5Hash()],
63+
require('../plugins/extTemplatedPathPlugin.js'), require('../plugins/requireModulePlugin.js')],
6864
resolve: {
6965
root: [],
7066
extensions: ['', '.js', '.css', '.json', '.string', '.tpl'],

lib/models/Project.js

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -335,32 +335,43 @@ var Project = function () {
335335
});
336336

337337
// 压缩
338-
var computecluster = require('compute-cluster');
339-
var cc = new computecluster({
340-
module: sysPath.resolve(__dirname, '../modules/minifyWorker.js'),
341-
max_backlog: -1,
342-
max_processes: 5
343-
});
344-
345338
if (opt.min) {
346339
(function () {
340+
var computecluster = require('compute-cluster');
341+
var cc = new computecluster({
342+
module: sysPath.resolve(__dirname, '../modules/minWorker.js'),
343+
max_backlog: -1,
344+
max_processes: 5
345+
});
346+
347347
spinner.start();
348348

349349
var assetsInfo = stats.toJson({
350350
errorDetails: false
351351
}).assets;
352352
var processToRun = assetsInfo.length;
353353

354+
var originAssets = stats.compilation.assets;
355+
var nextAssets = {};
354356
assetsInfo.forEach(function (asset) {
355357
cc.enqueue({
356358
opt: opt,
357359
cwd: cwd,
358360
assetName: asset.name
359-
}, function (err) {
361+
}, function (err, response) {
360362
if (err) {
361363
error('an error occured:', err);
362364
}
363365

366+
// 将替换版本号的资源名取代原有名字
367+
if (response.length > 0) {
368+
var originAssetName = response[0];
369+
var nextAssetName = response[1];
370+
if (originAssets[originAssetName]) {
371+
nextAssets[nextAssetName] = originAssets[originAssetName];
372+
}
373+
}
374+
364375
processToRun -= 1;
365376
spinner.text = '[Minify] ' + (assetsInfo.length - processToRun) + '/' + assetsInfo.length + ' assets';
366377

@@ -372,6 +383,9 @@ var Project = function () {
372383
}
373384
});
374385
});
386+
387+
// 更新 stats
388+
stats.compilation.assets = nextAssets;
375389
})();
376390
} else {
377391
afterPack();

lib/modules/minWorker.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
'use strict';
2+
3+
var path = require('path');
4+
var fs = require('fs');
5+
var crypto = require('crypto');
6+
var jsParser = require('uglify-js').parser;
7+
var jsUglify = require('uglify-js').uglify;
8+
var cssUglify = require('uglifycss');
9+
10+
process.on('message', function (m) {
11+
var opt = m.opt;
12+
var cwd = m.cwd;
13+
var assetName = m.assetName;
14+
var nameReg = /^([^\@]*)\@?([^\.]+)(\.(js|css))$/;
15+
var replacedAssets = [];
16+
17+
if (/\.js$/.test(assetName) || /\.css$/.test(assetName)) {
18+
var content = fs.readFileSync(path.resolve(cwd, assetName), { encoding: 'utf8' });
19+
var minifiedCode = null;
20+
21+
if (path.extname(assetName) === '.js') {
22+
// variable name mangling
23+
var willMangle = true;
24+
if (typeof opt.min === 'string' && opt.min.split('=')[0] === 'mangle' && opt.min.split('=')[1] === 'false') {
25+
willMangle = false;
26+
}
27+
var ast = jsParser.parse(content);
28+
ast = willMangle ? jsUglify.ast_mangle(ast) : ast;
29+
ast = jsUglify.ast_squeeze(ast);
30+
minifiedCode = jsUglify.gen_code(ast, true);
31+
} else if (path.extname(assetName) === '.css') {
32+
minifiedCode = cssUglify.processString(content);
33+
}
34+
35+
if (minifiedCode) {
36+
fs.writeFileSync(path.resolve(cwd, assetName), minifiedCode, { encoding: 'utf8' });
37+
38+
// 重新生成版本号, webpack 打的样式文件 hash 会根据所在目录不同而不同,造成 beta/prd 环境下版本号不一致
39+
var matchInfo = assetName.match(nameReg),
40+
version = matchInfo[2];
41+
42+
var nextVersion = md5(minifiedCode);
43+
var nextName = assetName.replace(version, nextVersion);
44+
fs.renameSync(path.resolve(cwd, assetName), path.resolve(cwd, nextName));
45+
46+
replacedAssets = [assetName, nextName];
47+
}
48+
}
49+
50+
process.send(replacedAssets);
51+
});
52+
53+
function md5(content) {
54+
return crypto.createHash('md5').update(content).digest('hex');
55+
}

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@
5252
"through2": "^2.0.1",
5353
"uglify-js": "^1.3.5",
5454
"uglifycss": "0.0.25",
55-
"webpack": "^1.13.1",
56-
"webpack-md5-hash": "0.0.5"
55+
"webpack": "^1.13.1"
5756
},
5857
"repository": {
5958
"type": "http",

src/models/Config.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22
const path = require('path');
33
const ExtractTextPlugin = require('extract-text-webpack-plugin');
4-
const WebpackMd5Hash = require('webpack-md5-hash');
54

65
const normalize = require('../utils/path').normalize;
76

@@ -56,10 +55,7 @@ class Config {
5655
plugins: [
5756
// local plugin
5857
require('../plugins/extTemplatedPathPlugin.js'),
59-
require('../plugins/requireModulePlugin.js'),
60-
61-
// vender plugin
62-
new WebpackMd5Hash()
58+
require('../plugins/requireModulePlugin.js')
6359
],
6460
resolve: {
6561
root: [],

src/models/Project.js

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -311,31 +311,42 @@ class Project {
311311
});
312312

313313
// 压缩
314-
const computecluster = require('compute-cluster');
315-
const cc = new computecluster({
316-
module: sysPath.resolve(__dirname , '../modules/minifyWorker.js'),
317-
max_backlog: -1,
318-
max_processes: 5
319-
});
320-
321314
if(opt.min) {
315+
const computecluster = require('compute-cluster');
316+
const cc = new computecluster({
317+
module: sysPath.resolve(__dirname , '../modules/minWorker.js'),
318+
max_backlog: -1,
319+
max_processes: 5
320+
});
321+
322322
spinner.start();
323323

324324
const assetsInfo = stats.toJson({
325325
errorDetails: false
326326
}).assets;
327327
let processToRun = assetsInfo.length;
328328

329+
const originAssets = stats.compilation.assets;
330+
const nextAssets = {};
329331
assetsInfo.forEach((asset) => {
330332
cc.enqueue({
331333
opt: opt,
332334
cwd: cwd,
333335
assetName: asset.name
334-
}, (err) => {
336+
}, (err, response) => {
335337
if (err) {
336338
error('an error occured:', err);
337339
}
338340

341+
// 将替换版本号的资源名取代原有名字
342+
if(response.length > 0) {
343+
const originAssetName = response[0];
344+
const nextAssetName = response[1];
345+
if(originAssets[originAssetName]) {
346+
nextAssets[nextAssetName] = originAssets[originAssetName];
347+
}
348+
}
349+
339350
processToRun -= 1;
340351
spinner.text = `[Minify] ${assetsInfo.length - processToRun}/${assetsInfo.length} assets`;
341352

@@ -347,6 +358,9 @@ class Project {
347358
}
348359
});
349360
});
361+
362+
// 更新 stats
363+
stats.compilation.assets = nextAssets;
350364
} else {
351365
afterPack();
352366
}

src/modules/minifyWorker.js renamed to src/modules/minWorker.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const path = require('path');
22
const fs = require('fs');
3+
const crypto = require('crypto');
34
const jsParser = require('uglify-js').parser;
45
const jsUglify = require('uglify-js').uglify;
56
const cssUglify = require('uglifycss');
@@ -8,6 +9,8 @@ process.on('message', function(m) {
89
const opt = m.opt;
910
const cwd = m.cwd;
1011
const assetName = m.assetName;
12+
const nameReg = /^([^\@]*)\@?([^\.]+)(\.(js|css))$/;
13+
let replacedAssets = [];
1114

1215
if(/\.js$/.test(assetName) || /\.css$/.test(assetName)) {
1316
const content = fs.readFileSync(path.resolve(cwd, assetName), {encoding: 'utf8'});
@@ -25,10 +28,26 @@ process.on('message', function(m) {
2528
minifiedCode = jsUglify.gen_code(ast, true);
2629
} else if (path.extname(assetName) === '.css') {
2730
minifiedCode = cssUglify.processString(content);
28-
}
31+
}
2932

30-
minifiedCode && fs.writeFileSync(path.resolve(cwd, assetName), minifiedCode, {encoding: 'utf8'});
33+
if(minifiedCode) {
34+
fs.writeFileSync(path.resolve(cwd, assetName), minifiedCode, {encoding: 'utf8'});
35+
36+
// 重新生成版本号, webpack 打的样式文件 hash 会根据所在目录不同而不同,造成 beta/prd 环境下版本号不一致
37+
var matchInfo = assetName.match(nameReg),
38+
version = matchInfo[2];
39+
40+
const nextVersion = md5(minifiedCode);
41+
const nextName = assetName.replace(version, nextVersion);
42+
fs.renameSync(path.resolve(cwd, assetName), path.resolve(cwd, nextName));
43+
44+
replacedAssets = [assetName, nextName];
45+
}
3146
}
3247

33-
process.send('complete');
48+
process.send(replacedAssets);
3449
});
50+
51+
function md5(content) {
52+
return crypto.createHash('md5').update(content).digest('hex');
53+
}

yarn.lock

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -863,10 +863,6 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3:
863863
strip-ansi "^3.0.0"
864864
supports-color "^2.0.0"
865865

866-
charenc@~0.0.1:
867-
version "0.0.1"
868-
resolved "http://registry.npm.corp.qunar.com/charenc/download/charenc-0.0.1.tgz#004cff9feaf102382ed12db58dd6f962796d6e88"
869-
870866
chokidar@^1.0.0, chokidar@^1.6.1:
871867
version "1.6.1"
872868
resolved "http://registry.npm.corp.qunar.com/chokidar/download/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2"
@@ -1271,10 +1267,6 @@ cross-spawn-async@^2.1.1:
12711267
lru-cache "^4.0.0"
12721268
which "^1.2.8"
12731269

1274-
crypt@~0.0.1:
1275-
version "0.0.1"
1276-
resolved "http://registry.npm.corp.qunar.com/crypt/download/crypt-0.0.1.tgz#5f11b21a6c05ef1b5e79708366da6374ece1e6a2"
1277-
12781270
cryptiles@2.x.x:
12791271
version "2.0.5"
12801272
resolved "http://registry.npm.corp.qunar.com/cryptiles/download/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
@@ -2746,7 +2738,7 @@ is-binary-path@^1.0.0:
27462738
dependencies:
27472739
binary-extensions "^1.0.0"
27482740

2749-
is-buffer@^1.0.2, is-buffer@~1.1.1:
2741+
is-buffer@^1.0.2:
27502742
version "1.1.4"
27512743
resolved "http://registry.npm.corp.qunar.com/is-buffer/download/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b"
27522744

@@ -3348,14 +3340,6 @@ math-expression-evaluator@^1.2.14:
33483340
dependencies:
33493341
lodash.indexof "^4.0.5"
33503342

3351-
md5@^2.0.0:
3352-
version "2.2.1"
3353-
resolved "http://registry.npm.corp.qunar.com/md5/download/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9"
3354-
dependencies:
3355-
charenc "~0.0.1"
3356-
crypt "~0.0.1"
3357-
is-buffer "~1.1.1"
3358-
33593343
media-typer@0.3.0:
33603344
version "0.3.0"
33613345
resolved "http://registry.npm.corp.qunar.com/media-typer/download/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
@@ -5374,12 +5358,6 @@ webpack-core@~0.6.0:
53745358
source-list-map "~0.1.0"
53755359
source-map "~0.4.1"
53765360

5377-
webpack-md5-hash@0.0.5:
5378-
version "0.0.5"
5379-
resolved "http://registry.npm.corp.qunar.com/webpack-md5-hash/download/webpack-md5-hash-0.0.5.tgz#d9f1899ead664459dd8b6b0c926ac71cfbd7bc7a"
5380-
dependencies:
5381-
md5 "^2.0.0"
5382-
53835361
webpack-sources@^0.1.0:
53845362
version "0.1.3"
53855363
resolved "http://registry.npm.corp.qunar.com/webpack-sources/download/webpack-sources-0.1.3.tgz#15ce2fb79d0a1da727444ba7c757bf164294f310"

0 commit comments

Comments
 (0)