Skip to content

Commit 302df4f

Browse files
authored
Merge pull request #397 from realityking/templates
Replace ejs templates with a simple js file
2 parents 37f048a + 084cc02 commit 302df4f

File tree

6 files changed

+85
-167
lines changed

6 files changed

+85
-167
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ _Note: Gaps between patch versions are faulty, broken or test releases._
1313
## UNRELEASED
1414

1515
<!-- Add changelog entries for new changes under this section -->
16+
* **Improvement**
17+
* A number of improvements to reduce the number of dependencies ([#391](https://github.com/webpack-contrib/webpack-bundle-analyzer/pull/391), [#396](https://github.com/webpack-contrib/webpack-bundle-analyzer/pull/396), [#397](https://github.com/webpack-contrib/webpack-bundle-analyzer/pull/397))
18+
1619
* **Bug Fix**
1720
* Prevent crashes for bundles generated from webpack array configs. ([#394](https://github.com/webpack-contrib/webpack-bundle-analyzer/pull/394) by [@ctavan](https://github.com/ctavan))
1821
* Fix `non-asset` assets causing analyze failure. ([#385](https://github.com/webpack-contrib/webpack-bundle-analyzer/issues/385) by [@ZKHelloworld](https://github.com/ZKHelloworld))

package-lock.json

Lines changed: 8 additions & 81 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,13 @@
3030
"files": [
3131
"public",
3232
"lib",
33-
"src",
34-
"views"
33+
"src"
3534
],
3635
"dependencies": {
3736
"acorn": "^8.0.4",
3837
"acorn-walk": "^8.0.0",
3938
"chalk": "^4.1.0",
4039
"commander": "^6.2.0",
41-
"ejs": "^3.1.5",
4240
"express": "^4.17.1",
4341
"filesize": "^6.1.0",
4442
"gzip-size": "^6.0.0",
Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,65 @@
1-
<!DOCTYPE html>
1+
/* eslint-disable max-len */
2+
const path = require('path');
3+
const fs = require('fs');
4+
5+
const _ = require('lodash');
6+
7+
const projectRoot = path.resolve(__dirname, '..');
8+
const assetsRoot = path.join(projectRoot, 'public');
9+
10+
exports.renderViewer = renderViewer;
11+
12+
/**
13+
* Escapes `<` characters in JSON to safely use it in `<script>` tag.
14+
*/
15+
function escapeJson(json) {
16+
return JSON.stringify(json).replace(/</gu, '\\u003c');
17+
}
18+
19+
function getAssetContent(filename) {
20+
const assetPath = path.join(assetsRoot, filename);
21+
22+
if (!assetPath.startsWith(assetsRoot)) {
23+
throw new Error(`"${filename}" is outside of the assets root`);
24+
}
25+
26+
return fs.readFileSync(assetPath, 'utf8');
27+
}
28+
29+
function html(strings, ...values) {
30+
return strings.map((string, index) => `${string}${values[index] || ''}`).join('');
31+
}
32+
33+
function getScript(filename, mode) {
34+
if (mode === 'static') {
35+
return `<!-- ${_.escape(filename)} -->
36+
<script>${getAssetContent(filename)}</script>`;
37+
} else {
38+
return `<script src="${_.escape(filename)}"></script>`;
39+
}
40+
}
41+
42+
function renderViewer({title, enableWebSocket, chartData, defaultSizes, mode} = {}) {
43+
return html`<!DOCTYPE html>
244
<html>
345
<head>
446
<meta charset="UTF-8"/>
547
<meta name="viewport" content="width=device-width, initial-scale=1"/>
6-
<title><%= title %></title>
48+
<title>${_.escape(title)}</title>
749
<link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAABrVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+O1foceMD///+J0/qK1Pr7/v8Xdr/9///W8P4UdL7L7P0Scr2r4Pyj3vwad8D5/f/2/f+55f3E6f34+/2H0/ojfMKpzOd0rNgQcb3F3O/j9f7c8v6g3Pz0/P/w+v/q+P7n9v6T1/uQ1vuE0vqLut/y+v+Z2fvt+f+15Pzv9fuc2/vR7v2V2Pvd6/bg9P7I6/285/2y4/yp3/zp8vk8i8kqgMT7/P31+fyv4vxGkcz6/P6/6P3j7vfS5PNnpNUxhcbO7f7F6v3O4vHK3/DA2u631Ouy0eqXweKJud5wqthfoNMMbLvY8f73+v2dxeR8sNtTmdDx9/zX6PSjyeaCtd1YnNGX2PuQveCGt95Nls42h8dLlM3F4vBtAAAAM3RSTlMAAyOx0/sKBvik8opWGBMOAe3l1snDm2E9LSb06eHcu5JpHbarfHZCN9CBb08zzkdNS0kYaptYAAAFV0lEQVRYw92X51/aYBDHHS2O2qqttVbrqNq9m+TJIAYIShBkWwqIiCgoWvfeq7Z2/s29hyQNyUcR7LveGwVyXy6XH8/9rqxglLfUPLxVduUor3h0rfp2TYvpivk37929TkG037hffoX0+peVtZQc1589rigVUdXS/ABSAyEmGIO/1XfvldSK8vs3OqB6u3m0nxmIrvgB0dj7rr7Y9IbuF68hnfFaiHA/sxqm0wciIG43P60qKv9WXWc1RXGh/mFESFABTSBi0sNAKzqet17eCtOb3kZIDwxEEU0oAIJGYxNBDhBND29e0rtXXbcpuPmED9IhEAAQ/AXEaF8EPmnrrKsv0LvWR3fg5sWDNAFZOgAgaKvZDogHNU9MFwnnYROkc56RD5CjAbQX9Ow4g7upCsvYu55aSI/Nj0H1akgKQEUM94dwK65hYRmFU9MIcH/fqJYOZYcnuJSU/waKDgTOEVaVKhwrTRP5XzgSpAITYzom7UvkhFX5VutmxeNnWDjjswTKTyfgluNDGbUpWissXhF3s7mlSml+czWkg3D0l1nNjGNjz3myOQOa1KM/jOS6ebdbAVTCi4gljHSFrviza7tOgRWcS0MOUX9zdNgag5w7rRqA44Lzw0hr1WqES36dFliSJFlh2rXIae3FFcDDgKdxrUIDePr8jGcSClV1u7A9xeN0ModY/pHMxmR1EzRh8TJiwqsHmKW0l4FCEZI+jHio+JdPPE9qwQtTRxku2D8sIeRL2LnxWSllANCQGOIiqVHAz2ye2JR0DcH+HoxDkaADLjgxjKQ+AwCX/g0+DNgdG0ukYCONAe+dbc2IAc6fwt1ARoDSezNHxV2Cmzwv3O6lDMV55edBGwGK9n1+x2F8EDfAGCxug8MhpsMEcTEAWf3rx2vZhe/LAmtIn/6apE6PN0ULKgywD9mmdxbmFl3OvD5AS5fW5zLbv/YHmcsBTjf/afDz3MaZTVCfAP9z6/Bw6ycv8EUBWJIn9zYcoAWWlW9+OzO3vkTy8H+RANLmdrpOuYWdZYEXpo+TlCJrW5EARb7fF+bWdqf3hhyZI1nWJQHgznErZhbjoEsWqi8dQNoE294aldzFurwSABL2XXMf9+H1VQGke9exw5P/AnA5Pv5ngMul7LOvO922iwACu8WkCwLCafvM4CeWPxfA8lNHcWZSoi8EwMAIciKX2Z4SWCMAa3snCZ/G4EA8D6CMLNFsGQhkkz/gQNEBbPCbWsxGUpYVu3z8IyNAknwJkfPMEhLyrdi5RTyUVACkw4GSFRNWJNEW+fgPGwHD8/JxnRuLabN4CGNRkAE23na2+VmEAUmrYymSGjMAYqH84YUIyzgzs3XC7gNgH36Vcc4zKY9o9fgPBXUAiHHwVboBHGLiX6Zcjp1f2wu4tvzZKo0ecPnDtQYDQvJXaBeNzce45Fp28ZQLrEZVuFqgBwOalArKXnW1UzlnSusQKJqKYNuz4tOnI6sZG4zanpemv+7ySU2jbA9h6uhcgpfy6G2PahirDZ6zvq6zDduMVFTKvzw8wgyEdelwY9in3XkEPs3osJuwRQ4qTkfzifndg9Gfc4pdsu82+tTnHZTBa2EAMrqr2t43pguc8tNm7JQVQ2S0ukj2d22dhXYP0/veWtwKrCkNoNimAN5+Xr/oLrxswKbVJjteWrX7eR63o4j9q0GxnaBdWgGA5VStpanIjQmEhV0/nVt5VOFUvix6awJhPcAaTEShgrG+iGyvb5a0Ndb1YGHFPEwoqAinoaykaID1o1pdPNu7XsnCKQ3R+hwWIIhGvORcJUBYXe3Xa3vq/mF/N9V13ugufMkfXn+KHsRD0B8AAAAASUVORK5CYII=" type="image/x-icon" />
850
951
<script>
10-
window.enableWebSocket = <%- escapeJson(enableWebSocket) %>;
52+
window.enableWebSocket = ${escapeJson(enableWebSocket)};
1153
</script>
12-
<%- include('script', { filename: 'viewer.js' }) %>
54+
${getScript('viewer.js', mode)}
1355
</head>
1456
1557
<body>
1658
<div id="app"></div>
1759
<script>
18-
window.chartData = <%- escapeJson(chartData) %>;
19-
window.defaultSizes = <%- escapeJson(defaultSizes) %>;
60+
window.chartData = ${escapeJson(chartData)};
61+
window.defaultSizes = ${escapeJson(defaultSizes)};
2062
</script>
2163
</body>
22-
</html>
64+
</html>`;
65+
}

src/viewer.js

Lines changed: 23 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@ const http = require('http');
55
const WebSocket = require('ws');
66
const _ = require('lodash');
77
const express = require('express');
8-
const ejs = require('ejs');
98
const {bold} = require('chalk');
109

1110
const Logger = require('./Logger');
1211
const analyzer = require('./analyzer');
1312
const {open} = require('./utils');
13+
const {renderViewer} = require('./template');
1414

1515
const projectRoot = path.resolve(__dirname, '..');
16-
const assetsRoot = path.join(projectRoot, 'public');
1716

1817
function resolveTitle(reportTitle) {
1918
if (typeof reportTitle === 'function') {
@@ -50,24 +49,18 @@ async function startServer(bundleStats, opts) {
5049
if (!chartData) return;
5150

5251
const app = express();
53-
54-
// Explicitly using our `ejs` dependency to render templates
55-
// Fixes #17
56-
app.engine('ejs', require('ejs').renderFile);
57-
app.set('view engine', 'ejs');
58-
app.set('views', `${projectRoot}/views`);
5952
app.use(express.static(`${projectRoot}/public`));
6053

61-
app.use('/', (req, res) => {
62-
res.render('viewer', {
54+
app.get('/', (req, res) => {
55+
res.writeHead(200, {'Content-Type': 'text/html'});
56+
const html = renderViewer({
6357
mode: 'server',
6458
title: resolveTitle(reportTitle),
65-
get chartData() { return chartData },
59+
chartData,
6660
defaultSizes,
67-
enableWebSocket: true,
68-
// Helpers
69-
escapeJson
61+
enableWebSocket: true
7062
});
63+
return res.end(html);
7164
});
7265

7366
const server = http.createServer(app);
@@ -139,44 +132,23 @@ async function generateReport(bundleStats, opts) {
139132

140133
if (!chartData) return;
141134

142-
await new Promise((resolve, reject) => {
143-
ejs.renderFile(
144-
`${projectRoot}/views/viewer.ejs`,
145-
{
146-
mode: 'static',
147-
title: resolveTitle(reportTitle),
148-
chartData,
149-
defaultSizes,
150-
enableWebSocket: false,
151-
// Helpers
152-
assetContent: getAssetContent,
153-
escapeJson
154-
},
155-
(err, reportHtml) => {
156-
try {
157-
if (err) {
158-
logger.error(err);
159-
reject(err);
160-
return;
161-
}
162-
163-
const reportFilepath = path.resolve(bundleDir || process.cwd(), reportFilename);
164-
165-
fs.mkdirSync(path.dirname(reportFilepath), {recursive: true});
166-
fs.writeFileSync(reportFilepath, reportHtml);
167-
168-
logger.info(`${bold('Webpack Bundle Analyzer')} saved report to ${bold(reportFilepath)}`);
169-
170-
if (openBrowser) {
171-
open(`file://${reportFilepath}`, logger);
172-
}
173-
resolve();
174-
} catch (e) {
175-
reject(e);
176-
}
177-
}
178-
);
135+
const reportHtml = renderViewer({
136+
mode: 'static',
137+
title: resolveTitle(reportTitle),
138+
chartData,
139+
defaultSizes,
140+
enableWebSocket: false
179141
});
142+
const reportFilepath = path.resolve(bundleDir || process.cwd(), reportFilename);
143+
144+
fs.mkdirSync(path.dirname(reportFilepath), {recursive: true});
145+
fs.writeFileSync(reportFilepath, reportHtml);
146+
147+
logger.info(`${bold('Webpack Bundle Analyzer')} saved report to ${bold(reportFilepath)}`);
148+
149+
if (openBrowser) {
150+
open(`file://${reportFilepath}`, logger);
151+
}
180152
}
181153

182154
async function generateJSONReport(bundleStats, opts) {
@@ -192,23 +164,6 @@ async function generateJSONReport(bundleStats, opts) {
192164
logger.info(`${bold('Webpack Bundle Analyzer')} saved JSON report to ${bold(reportFilename)}`);
193165
}
194166

195-
function getAssetContent(filename) {
196-
const assetPath = path.join(assetsRoot, filename);
197-
198-
if (!assetPath.startsWith(assetsRoot)) {
199-
throw new Error(`"${filename}" is outside of the assets root`);
200-
}
201-
202-
return fs.readFileSync(assetPath, 'utf8');
203-
}
204-
205-
/**
206-
* Escapes `<` characters in JSON to safely use it in `<script>` tag.
207-
*/
208-
function escapeJson(json) {
209-
return JSON.stringify(json).replace(/</gu, '\\u003c');
210-
}
211-
212167
function getChartData(analyzerOpts, ...args) {
213168
let chartData;
214169
const {logger} = analyzerOpts;

views/script.ejs

Lines changed: 0 additions & 8 deletions
This file was deleted.

0 commit comments

Comments
 (0)