Blame view

node_modules/webpack/lib/RecordIdsPlugin.js 4.23 KB
aaac7fed   liuqimichale   add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
  /*
  	MIT License http://www.opensource.org/licenses/mit-license.php
  	Author Tobias Koppers @sokra
  */
  "use strict";
  
  const identifierUtils = require("./util/identifier");
  
  class RecordIdsPlugin {
  
  	apply(compiler) {
  		compiler.plugin("compilation", compilation => {
  			compilation.plugin("record-modules", (modules, records) => {
  				if(!records.modules) records.modules = {};
  				if(!records.modules.byIdentifier) records.modules.byIdentifier = {};
  				if(!records.modules.usedIds) records.modules.usedIds = {};
  				modules.forEach(function(module) {
  					if(!module.portableId) module.portableId = identifierUtils.makePathsRelative(compiler.context, module.identifier());
  					const identifier = module.portableId;
  					records.modules.byIdentifier[identifier] = module.id;
  					records.modules.usedIds[module.id] = module.id;
  				});
  			});
  			compilation.plugin("revive-modules", (modules, records) => {
  				if(!records.modules) return;
  				if(records.modules.byIdentifier) {
  					const usedIds = {};
  					modules.forEach(function(module) {
  						if(module.id !== null) return;
  						if(!module.portableId) module.portableId = identifierUtils.makePathsRelative(compiler.context, module.identifier());
  						const identifier = module.portableId;
  						const id = records.modules.byIdentifier[identifier];
  						if(id === undefined) return;
  						if(usedIds[id]) return;
  						usedIds[id] = true;
  						module.id = id;
  					});
  				}
  				compilation.usedModuleIds = records.modules.usedIds;
  			});
  
  			function getDepBlockIdent(chunk, block) {
  				const ident = [];
  				if(block.chunks.length > 1)
  					ident.push(block.chunks.indexOf(chunk));
  				while(block.parent) {
  					const p = block.parent;
  					const idx = p.blocks.indexOf(block);
  					const l = p.blocks.length - 1;
  					ident.push(`${idx}/${l}`);
  					block = block.parent;
  				}
  				if(!block.identifier) return null;
  				ident.push(identifierUtils.makePathsRelative(compiler.context, block.identifier()));
  				return ident.reverse().join(":");
  			}
  			compilation.plugin("record-chunks", (chunks, records) => {
  				records.nextFreeChunkId = compilation.nextFreeChunkId;
  				if(!records.chunks) records.chunks = {};
  				if(!records.chunks.byName) records.chunks.byName = {};
  				if(!records.chunks.byBlocks) records.chunks.byBlocks = {};
  				records.chunks.usedIds = {};
  				chunks.forEach(chunk => {
  					const name = chunk.name;
  					const blockIdents = chunk.blocks.map(getDepBlockIdent.bind(null, chunk)).filter(Boolean);
  					if(name) records.chunks.byName[name] = chunk.id;
  					blockIdents.forEach((blockIdent) => {
  						records.chunks.byBlocks[blockIdent] = chunk.id;
  					});
  					records.chunks.usedIds[chunk.id] = chunk.id;
  				});
  			});
  			compilation.plugin("revive-chunks", (chunks, records) => {
  				if(!records.chunks) return;
  				const usedIds = {};
  				if(records.chunks.byName) {
  					chunks.forEach(function(chunk) {
  						if(chunk.id !== null) return;
  						if(!chunk.name) return;
  						const id = records.chunks.byName[chunk.name];
  						if(id === undefined) return;
  						if(usedIds[id]) return;
  						usedIds[id] = true;
  						chunk.id = id;
  					});
  				}
  				if(records.chunks.byBlocks) {
  					const argumentedChunks = chunks.filter(chunk => chunk.id === null).map(chunk => ({
  						chunk,
  						blockIdents: chunk.blocks.map(getDepBlockIdent.bind(null, chunk)).filter(Boolean)
  					})).filter(arg => arg.blockIdents.length > 0);
  					let blockIdentsCount = {};
  					argumentedChunks.forEach((arg, idx) => {
  						arg.blockIdents.forEach(blockIdent => {
  							const id = records.chunks.byBlocks[blockIdent];
  							if(typeof id !== "number") return;
  							const accessor = `${id}:${idx}`;
  							blockIdentsCount[accessor] = (blockIdentsCount[accessor] || 0) + 1;
  						});
  					});
  					blockIdentsCount = Object.keys(blockIdentsCount).map(accessor => [blockIdentsCount[accessor]].concat(accessor.split(":").map(Number))).sort((a, b) => b[0] - a[0]);
  					blockIdentsCount.forEach(function(arg) {
  						const id = arg[1];
  						if(usedIds[id]) return;
  						const idx = arg[2];
  						const chunk = argumentedChunks[idx].chunk;
  						if(chunk.id !== null) return;
  						usedIds[id] = true;
  						chunk.id = id;
  					});
  				}
  				compilation.usedChunkIds = records.chunks.usedIds;
  			});
  		});
  	}
  }
  module.exports = RecordIdsPlugin;