1 |
|
2 |
|
3 |
|
4 |
|
5 | 'use strict'
|
6 | let path = require('path')
|
7 | module.exports = class perfInstallModulePlugin {
|
8 | constructor(options) {
|
9 | this.options = options || {}
|
10 | this.PackageJSON = require(path.join(process.cwd(), './package.json'))
|
11 | this.options.url = this.options.url ? this.options.url : ''
|
12 | }
|
13 | apply(compiler) {
|
14 | let me = this
|
15 | compiler.plugin('compilation', (compilation, params) => {
|
16 | compilation.mainTemplate.plugin('local-vars', function(
|
17 | source,
|
18 | chunk,
|
19 | hash
|
20 | ) {
|
21 | return this.asString([
|
22 | source,
|
23 | '// The module cache',
|
24 | `let countTimeMap = {};`,
|
25 | `let RecordTime=[];
|
26 | let currentNode_COUNT=null;
|
27 | `,
|
28 | `let countTimeArr = [];
|
29 | let pageName='';
|
30 | if(typeof window !=='undefined'){
|
31 | pageName =window["location"].pathname.split(".")[0];
|
32 | }
|
33 | function formatJson (list) {
|
34 | let pid = []
|
35 | let items = []
|
36 | let index = []
|
37 | pid.push(list[0].moduleId)
|
38 | items.push(list[0])
|
39 | index.push(0)
|
40 | for (let i = 1;i < list.length - 1;i++) {
|
41 | if (list[i].type === 'start') {
|
42 | list[i].pid = pid[pid.length - 1]
|
43 | pid.push(list[i].moduleId)
|
44 | items.push(list[i])
|
45 | index.push(items.length - 1)
|
46 | }else {
|
47 | let whereNow = index.pop()
|
48 | // console.log("参数",whereNow)
|
49 | items[whereNow].time = new Date(list[i].value) - new Date(items[whereNow].value)
|
50 | pid.pop()
|
51 | }
|
52 | }
|
53 | return items
|
54 | }
|
55 | let resultMap = [];
|
56 | function getTrees (data, pid) {
|
57 | var result = [], temp
|
58 | for (var i in data) {
|
59 | if (data[i].pid == pid) {
|
60 | delete data[i].value
|
61 | delete data[i].type
|
62 | result.push(data[i])
|
63 | temp = getTrees(data, data[i].moduleId);
|
64 | //计算self 时间
|
65 | data[i].selftime=data[i].time;
|
66 | for(var k in temp){
|
67 | data[i].selftime =data[i].selftime-temp[k].time;
|
68 | }
|
69 | resultMap.push(data[i]);
|
70 | if (temp.length > 0) {
|
71 | data[i].children = temp
|
72 | }
|
73 | }
|
74 | }
|
75 | return result
|
76 | }
|
77 | `,
|
78 | `setTimeout(function(){
|
79 |
|
80 | let projectName = '${me.PackageJSON.name}';
|
81 | let version = '${me.PackageJSON.version}';
|
82 | console.log("模块性能指标前20,本测算是指某个模块在初始化时消耗的时间(单位ms),工程名:"+projectName,"页面名:",pageName,"版本号:",version);
|
83 | console.log(getTrees(formatJson(RecordTime) , 0));
|
84 |
|
85 | resultMap.sort(function(a,b){
|
86 | return b.selftime-a.selftime;
|
87 | });
|
88 | resultMap=resultMap.map(m=>{
|
89 | m.moduleId=m.moduleId+"";
|
90 | if(m.moduleId.indexOf('?')>0){
|
91 | m.moduleId = m.moduleId.split("?")[1];
|
92 | }
|
93 | m.moduleId=m.moduleId.replace("./node_modules/","");
|
94 | if(m.moduleId.indexOf('!')>0){
|
95 | m.moduleId = m.moduleId.split("!")[1];
|
96 | }
|
97 | return {name:m.moduleId,time:m.selftime}
|
98 | })
|
99 | try{
|
100 | let postData ={
|
101 | resultMap:resultMap,
|
102 | projectName:projectName,
|
103 | pageName:pageName,
|
104 | version:version
|
105 | };
|
106 | let url = '${me.options.url}';
|
107 | if(url!=''){
|
108 | fetch(url, {
|
109 | method: 'POST',
|
110 | mode: 'cors',
|
111 | credentials: 'include',
|
112 | headers: {
|
113 | 'Content-Type': 'application/x-www-form-urlencoded'
|
114 | },
|
115 | body: JSON.stringify(postData)
|
116 | }).then(function(response) {
|
117 | console.log('上报perf-module-self-executing日志成功!');
|
118 | }).catch(function(ex){
|
119 | console.log('上报perf-module-self-executing日志失败!');
|
120 | });
|
121 | }
|
122 |
|
123 | }
|
124 | catch(ex){
|
125 | console.log('上报perf-module-self-executing日志失败')
|
126 | }
|
127 | console.table(resultMap.slice(0,20));
|
128 | },5000)`,
|
129 | 'var installedModules = {};'
|
130 | ])
|
131 | })
|
132 | compilation.mainTemplate.plugin('require', function(source, chunk, hash) {
|
133 | return this.asString([
|
134 | '// Check if module is in cache',
|
135 | 'if(installedModules[moduleId]) {',
|
136 | this.indent('return installedModules[moduleId].exports;'),
|
137 | '}',
|
138 | '// Create a new module (and put it into the cache)',
|
139 | 'var module = installedModules[moduleId] = {',
|
140 | this.indent(
|
141 | this.applyPluginsWaterfall(
|
142 | 'module-obj',
|
143 | '',
|
144 | chunk,
|
145 | hash,
|
146 | 'moduleId'
|
147 | )
|
148 | ),
|
149 | '};',
|
150 | '',
|
151 | this.asString([
|
152 | '// Execute the module function',
|
153 | `
|
154 | let start = new Date();
|
155 | RecordTime.push({
|
156 | moduleId:moduleId,
|
157 | value:start,
|
158 | type:"start"
|
159 | })
|
160 | countTimeMap[moduleId]={start:start};
|
161 | currentNode_COUNT=moduleId;
|
162 | `,
|
163 | `modules[moduleId].call(module.exports, module, module.exports, ${this.renderRequireFunctionForModule(
|
164 | hash,
|
165 | chunk,
|
166 | 'moduleId'
|
167 | )});`,
|
168 | `
|
169 | let end =new Date();
|
170 | countTimeMap[moduleId].end=end;
|
171 | countTimeMap[moduleId].time=countTimeMap[moduleId].end-countTimeMap[moduleId].start;
|
172 | if(currentNode_COUNT==moduleId){
|
173 | countTimeMap[moduleId].isleaf = true;
|
174 | }
|
175 | countTimeMap[moduleId].name = moduleId;
|
176 | countTimeArr.push(countTimeMap[moduleId]);
|
177 | RecordTime.push({
|
178 | moduleId:moduleId,
|
179 | value:end,
|
180 | type:"end"
|
181 | })
|
182 | `
|
183 | ]),
|
184 | '',
|
185 | '// Flag the module as loaded',
|
186 | 'module.l = true;',
|
187 | '',
|
188 | '// Return the exports of the module',
|
189 | 'return module.exports;'
|
190 | ])
|
191 | })
|
192 | })
|
193 | }
|
194 | }
|