@vernikr/size-report 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +929 -1081
- package/bin/postinstall.js +17 -18
- package/bin/size.js +2 -2
- package/package.json +3 -4
- package/src/args.js +72 -72
- package/src/artifact.js +14 -14
- package/src/check.js +41 -42
- package/src/cli.js +26 -29
- package/src/config.js +87 -91
- package/src/css.js +14 -14
- package/src/data.js +31 -37
- package/src/derived.js +31 -35
- package/src/doctor.js +95 -99
- package/src/explain.js +46 -47
- package/src/git.js +66 -71
- package/src/history.js +74 -77
- package/src/hook.js +130 -149
- package/src/init.js +36 -37
- package/src/journal.js +17 -15
- package/src/locales.js +25 -16
- package/src/metrics.js +56 -55
- package/src/minify.js +28 -27
- package/src/modes.js +57 -60
- package/src/optional.js +13 -11
- package/src/page/app.css +75 -91
- package/src/page/app.js +30 -35
- package/src/page/build.js +40 -39
- package/src/page/dom.js +8 -9
- package/src/page/panel.js +48 -51
- package/src/page/state.js +72 -87
- package/src/page/table.js +21 -24
- package/src/parse-worker.js +10 -10
- package/src/parse.js +43 -45
- package/src/project.js +100 -104
- package/src/refusal.js +75 -76
- package/src/size-table.js +41 -76
- package/src/strip/forms.js +5 -5
- package/src/strip/guard.js +27 -28
- package/src/strip/js.js +27 -27
- package/src/strip.js +18 -21
- package/src/table.css +13 -14
- package/src/tokens.js +28 -27
- package/src/tool.js +10 -11
- package/templates/README.md +71 -77
- package/templates/ci.yml +33 -33
- package/templates/size-report.config.json +3 -3
- package/CHANGELOG.md +0 -690
package/src/refusal.js
CHANGED
|
@@ -3,17 +3,17 @@ import path from 'path';
|
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
import { TOOL_PKG } from './tool.js';
|
|
5
5
|
|
|
6
|
-
/*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
/* Refusal and help: an exit code, a message carrying the command that fixes the problem,
|
|
7
|
+
* and the `--help` text. It stands at the bottom of the chain — it knows neither the
|
|
8
|
+
* settings nor git — which is why any module may call it. */
|
|
9
9
|
|
|
10
|
-
//
|
|
11
|
-
//
|
|
10
|
+
// ESM has no `__filename`, and `invocation()` needs the engine's own location: the path
|
|
11
|
+
// comes from `import.meta.url`.
|
|
12
12
|
const __filename = fileURLToPath(import.meta.url);
|
|
13
13
|
|
|
14
|
-
/*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
/* A refusal is an exit code and one line with the command that fixes it: an agent branches
|
|
15
|
+
* on the code (the table is in `USAGE` below), a human reads the text. The stack is never
|
|
16
|
+
* handed out — it holds no hint, only paths of the machine. */
|
|
17
17
|
export const EXIT = { OK: 0, VIOLATION: 1, CONFIG: 2, SHALLOW: 3, SENSOR: 4, INTERNAL: 5 };
|
|
18
18
|
|
|
19
19
|
export class Refusal extends Error {
|
|
@@ -27,51 +27,50 @@ export function refuse(code, message) {
|
|
|
27
27
|
throw new Refusal(code, message);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
/*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
30
|
+
/* The causes of a code-2 refusal in one list, and this is the only place where they are
|
|
31
|
+
* spelled out: the help prints them from it, the code table in `README.md` is checked
|
|
32
|
+
* against it (`test/docs-commands.test.js`), and `refuseCause` lets no refusal through
|
|
33
|
+
* without a named cause. So "the documentation says less than happens" cannot pass here
|
|
34
|
+
* silently. The groups say where a cause comes from: the command line, settings and the
|
|
35
|
+
* project, history, the hook, measurement. */
|
|
36
36
|
export const CONFIG_CAUSES = [
|
|
37
|
-
['
|
|
38
|
-
'
|
|
39
|
-
'
|
|
40
|
-
'
|
|
37
|
+
['command line', [
|
|
38
|
+
'unknown flag', 'flag without a value', 'repeated flag', 'two modes at once',
|
|
39
|
+
'extra word', 'command and mode', 'unknown command', 'incompatible flag',
|
|
40
|
+
'no JSON answer', 'two answers at once', 'no commit'
|
|
41
41
|
]],
|
|
42
|
-
['
|
|
43
|
-
'
|
|
44
|
-
'
|
|
42
|
+
['settings and the project', [
|
|
43
|
+
'no settings file', 'settings not parsed', 'settings invalid',
|
|
44
|
+
'git missing', 'not a git repository', 'config already exists'
|
|
45
45
|
]],
|
|
46
|
-
['
|
|
47
|
-
['
|
|
48
|
-
['
|
|
46
|
+
['history', ['no such commit', 'ambiguous commit', 'commit outside the history']],
|
|
47
|
+
['hook', ['foreign hook', 'foreign core.hooksPath', 'no way to invoke the tool']],
|
|
48
|
+
['measurement', ['file is not JavaScript', 'minifier did not parse']]
|
|
49
49
|
];
|
|
50
50
|
|
|
51
|
-
/*
|
|
52
|
-
*
|
|
51
|
+
/* A cause is a declared name, not decoration of the text: an undeclared one never reaches
|
|
52
|
+
* the user, because that is a defect of the tool rather than a dead end for a human. */
|
|
53
53
|
export function refuseCause(cause, message) {
|
|
54
54
|
if (!CONFIG_CAUSES.some((g) => g[1].indexOf(cause) >= 0)) {
|
|
55
|
-
throw new Error('
|
|
55
|
+
throw new Error('refusal cause is not declared: ' + cause);
|
|
56
56
|
}
|
|
57
57
|
refuse(EXIT.CONFIG, message);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
/*
|
|
61
|
-
*
|
|
60
|
+
/* The help lines about causes come from the same list, so the help cannot drift from the
|
|
61
|
+
* checks. */
|
|
62
62
|
const CAUSE_LINES = CONFIG_CAUSES.map((g) => ' ' + g[0] + ': ' + g[1].join(' · '));
|
|
63
63
|
|
|
64
|
-
/*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* в проекте с пакетом она работает, без пакета отказывает на месте и в сеть не идёт.
|
|
64
|
+
/* How the tool is called where it is read. The advice names what lies nearby and never the package
|
|
65
|
+
* name: a path inside the project (`node node_modules/<name>/bin/size.js`) works where the package is
|
|
66
|
+
* installed and, where it is not, refuses on the spot; the name from the registry would instead fetch
|
|
67
|
+
* and run a revision the project never pinned (and the unscoped name there belongs to another package
|
|
68
|
+
* altogether). One form, therefore, and no trip to the network.
|
|
70
69
|
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
70
|
+
* The fix command quotes the entry point rather than the engine itself: importing the
|
|
71
|
+
* engine runs nothing, so `--init` works through the command only. Inside the package's own
|
|
72
|
+
* repository the path is computed from the engine's location rather than from the current
|
|
73
|
+
* directory — the message has to work from anywhere in the project. */
|
|
75
74
|
export function invocation() {
|
|
76
75
|
const local = path.join('node_modules', TOOL_PKG.name, 'bin', 'size.js');
|
|
77
76
|
if (fs.existsSync(path.resolve(process.cwd(), local))) return 'node ' + local;
|
|
@@ -84,55 +83,55 @@ export function cliCommand(flag) {
|
|
|
84
83
|
return invocation() + ' ' + flag;
|
|
85
84
|
}
|
|
86
85
|
|
|
87
|
-
/*
|
|
88
|
-
*
|
|
86
|
+
/* A path inside a ready-made command: a space or a quote in it would break copying, so such
|
|
87
|
+
* a path is quoted the way a shell would accept it. */
|
|
89
88
|
export function advicePath(p) {
|
|
90
89
|
return /[\s"'$`\\]/.test(p) ? JSON.stringify(p) : p;
|
|
91
90
|
}
|
|
92
91
|
|
|
93
92
|
export const USAGE = [
|
|
94
|
-
'@vernikr/size-report —
|
|
95
|
-
'
|
|
93
|
+
'@vernikr/size-report — a report on how the size of files grows commit by commit: one file,',
|
|
94
|
+
'a self-contained page (the data, the styling and the program live inside it).',
|
|
96
95
|
'',
|
|
97
|
-
'
|
|
96
|
+
'Usage: ' + invocation() + ' [command] [mode] [flags]',
|
|
98
97
|
'',
|
|
99
|
-
'
|
|
100
|
-
' check [--json]
|
|
101
|
-
'
|
|
102
|
-
' explain
|
|
103
|
-
' doctor [--json]
|
|
104
|
-
'
|
|
105
|
-
' install-hook
|
|
106
|
-
'
|
|
107
|
-
'
|
|
108
|
-
' uninstall-hook
|
|
109
|
-
' hook-run
|
|
98
|
+
'Commands:',
|
|
99
|
+
' check [--json] completeness: settings, history, paths, sensors (code 1 — a path',
|
|
100
|
+
' of the history is not tracked and is not declared an exception)',
|
|
101
|
+
' explain <commit> why a commit got no row (a revision name, a sha or its beginning)',
|
|
102
|
+
' doctor [--json] diagnostics in one answer: environment, dependencies, settings,',
|
|
103
|
+
' coverage (code 0 — nothing to do, otherwise — the first by weight)',
|
|
104
|
+
' install-hook install the post-commit and post-merge hooks (they install themselves',
|
|
105
|
+
' on the first run in a project): the report is rebuilt after every',
|
|
106
|
+
' commit and merge and, if it is in git, lands as a commit of its own',
|
|
107
|
+
' uninstall-hook remove the hook and its state (the project goes back to what it was)',
|
|
108
|
+
' hook-run what the hook calls: rebuild the report and commit it (never by hand)',
|
|
110
109
|
'',
|
|
111
|
-
'
|
|
112
|
-
' --init [
|
|
113
|
-
' --write [
|
|
114
|
-
' --data
|
|
115
|
-
' --json
|
|
116
|
-
' (
|
|
110
|
+
'Modes:',
|
|
111
|
+
' --init [file] pin the settings in a file (--force — overwrite an existing one)',
|
|
112
|
+
' --write [file] build the report into a file from the settings (the directory is made)',
|
|
113
|
+
' --data the contract data on stdout — for the report and for an agent',
|
|
114
|
+
' --json the former shape of the data on stdout',
|
|
115
|
+
' (no mode) check that the report matches the history',
|
|
117
116
|
'',
|
|
118
|
-
'
|
|
117
|
+
'Flags: --config <file> — other settings; --help — this help.',
|
|
119
118
|
'',
|
|
120
|
-
'--json
|
|
121
|
-
'
|
|
122
|
-
'
|
|
119
|
+
'--json is a shape of the answer rather than a mode of its own, and it has one rule: exactly',
|
|
120
|
+
'four calls answer. Without a command it is the former shape of the data, with check, explain',
|
|
121
|
+
'and doctor — theirs; the rest have no answer, and there --json is a refusal rather than silence.',
|
|
123
122
|
'',
|
|
124
|
-
'
|
|
125
|
-
'
|
|
123
|
+
'One run at a time: a command and a mode do not combine, a mode is alone too, and an extra word',
|
|
124
|
+
'or an unknown flag is a refusal with a ready-made command rather than an ordinary run.',
|
|
126
125
|
'',
|
|
127
|
-
'
|
|
128
|
-
'(
|
|
129
|
-
'
|
|
130
|
-
'
|
|
126
|
+
'Settings are not obligatory: without a file they are derived from the project itself',
|
|
127
|
+
'(columns — from the path groups of the tree and the history, the journal and where to write —',
|
|
128
|
+
'from there too), and the output says so. `--init` pins what was derived in a file — after that',
|
|
129
|
+
'the file is edited; a file named by `--config` has to exist, and otherwise it is a refusal.',
|
|
131
130
|
'',
|
|
132
|
-
'
|
|
133
|
-
'
|
|
134
|
-
'
|
|
135
|
-
'
|
|
131
|
+
'Exit codes: 0 — all is well, 1 — a mismatch with the history or an incompleteness, 2 — the',
|
|
132
|
+
'call, the settings or the environment, 3 — an incomplete history, 4 — no sensor, 5 — an',
|
|
133
|
+
'internal error. doctor has an order of its own: 2, 3, 1, 4 — by the weight of a finding',
|
|
134
|
+
'rather than by what came first.',
|
|
136
135
|
'',
|
|
137
|
-
'
|
|
136
|
+
'Causes of a code-2 refusal (the code table in README.md names them too):'
|
|
138
137
|
].concat(CAUSE_LINES, ['']).join('\n');
|
package/src/size-table.js
CHANGED
|
@@ -1,81 +1,46 @@
|
|
|
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
|
-
* Отчёт один: самодостаточная страница (`size-report.html`), в которой лежат и
|
|
41
|
-
* данные, и оформление, и программа. Второй формы того же отчёта нет намеренно: два
|
|
42
|
-
* вывода одной истории разошлись бы молча, а выбрать, какой верный, было бы нечем.
|
|
43
|
-
*
|
|
44
|
-
* Запуск (из любого места репозитория; `size` — когда пакет установлен, иначе
|
|
45
|
-
* `node bin/size.js`):
|
|
46
|
-
* size проверка: отчёт совпадает с историей (CI)
|
|
47
|
-
* size --write [файл] перегенерировать отчёт
|
|
48
|
-
* size --json строки как JSON в stdout
|
|
49
|
-
* size --data данные для отчёта и агента в stdout
|
|
50
|
-
* size --init [файл] закрепить настройки файлом (без него они выводятся из проекта)
|
|
51
|
-
* size --config <путь> другой файл настроек
|
|
52
|
-
* size --help справка и коды выхода
|
|
53
|
-
*
|
|
54
|
-
* Требуется полная история: на обрезанном клоне (shallow) скрипт отказывается
|
|
55
|
-
* работать, а не пишет молча короткую таблицу. В CI — `fetch-depth: 0`.
|
|
1
|
+
/* Size of files by commit — the portable generator.
|
|
2
|
+
*
|
|
3
|
+
* A row is a commit, a column is a file, a cell is the change against the previous commit
|
|
4
|
+
* for one metric; absolute sizes appear once, in the top "now" row, or a large number
|
|
5
|
+
* would repeat in every row and the columns would run off the screen.
|
|
6
|
+
*
|
|
7
|
+
* The source of truth is git itself: sizes come from the blobs of the commits, not from
|
|
8
|
+
* the working tree, so the table does not depend on what is open in an editor, and it is
|
|
9
|
+
* rebuilt from the whole history rather than appended to — an incremental file would have
|
|
10
|
+
* to be repaired after any change to an old number.
|
|
11
|
+
*
|
|
12
|
+
* **Project matters in the config, mechanics in the package.** The engine knows neither
|
|
13
|
+
* the file names of the project nor the name of its journal nor the language of the
|
|
14
|
+
* labels: columns, metrics, journal, locale and output path all live in
|
|
15
|
+
* `size-table.config.json` next to the repository root (`--config` names another path).
|
|
16
|
+
* That is why the package can be attached to a new project as a dependency, and why
|
|
17
|
+
* `size --init` can draft a config there (which extensions the project has, where its
|
|
18
|
+
* journal is, where to write), to be edited by eye afterwards.
|
|
19
|
+
*
|
|
20
|
+
* A commit gets a row when it moved at least one number, merges included: a merge is
|
|
21
|
+
* diffed against its first parent, so its edits show both in the row and in the carried
|
|
22
|
+
* state. No row goes to a commit that touched only the report itself (or anything else
|
|
23
|
+
* listed in `skip`) — a row about a commit cannot live inside that commit, whose sha is
|
|
24
|
+
* unknown while it is being built, and that is why a rebuilt report is a commit of its
|
|
25
|
+
* own — nor to a commit whose cells all came out zero (a merge resolved into exactly what
|
|
26
|
+
* the branch already gave): a row without a single number reads as a breakdown. Hence the
|
|
27
|
+
* requirement on the config: the columns must cover everything a commit can change,
|
|
28
|
+
* because a commit outside the columns would give such a row, while an empty cell already
|
|
29
|
+
* means "the file is not in that revision yet". With `rows.sha: false` the same invariant
|
|
30
|
+
* serves the other strategy — rebuild and amend into the same commit — because without
|
|
31
|
+
* the sha the artifact becomes a fixed point.
|
|
32
|
+
*
|
|
33
|
+
* One report: a single self-contained page holding the data, the styling and the program.
|
|
34
|
+
* A second form of the same report does not exist on purpose — two outputs of one history
|
|
35
|
+
* would diverge silently, with nothing to tell which one is right.
|
|
36
|
+
*
|
|
37
|
+
* The full history is required: on a shallow clone it refuses instead of silently writing
|
|
38
|
+
* a short table (`fetch-depth: 0` in CI). Modes and exit codes: `size --help`.
|
|
56
39
|
*/
|
|
57
40
|
|
|
58
|
-
/*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* refusal, locales, journal, tool, css, derived — ни на чём не стоят;
|
|
62
|
-
* parse → parse-worker — разбор модуля вне процесса;
|
|
63
|
-
* strip → refusal, parse — снятие балласта и гард;
|
|
64
|
-
* metrics → strip — реестр метрик;
|
|
65
|
-
* git → refusal — всё, что читается у git;
|
|
66
|
-
* project → git, refusal — что проект говорит о себе сам;
|
|
67
|
-
* config → project, git, refusal, locales, metrics, data — настройки проекта;
|
|
68
|
-
* history → git, metrics, journal, refusal — сборка по истории;
|
|
69
|
-
* data → locales, metrics, journal, history, project, tool — контракт со страницей;
|
|
70
|
-
* page/build → locales, css — отчёт одним файлом;
|
|
71
|
-
* artifact → data, page/build — запись отчёта;
|
|
72
|
-
* modes → почти все — что делать по запросу;
|
|
73
|
-
* init → config, project, refusal, artifact — закрепление настроек файлом;
|
|
74
|
-
* cli → args, modes, init, config, refusal — вход: разбор и доставка.
|
|
75
|
-
*
|
|
76
|
-
* Публичный API — то, чем пользуются `bin/size.js` и `test/`: список ниже не
|
|
77
|
-
* сокращается при разбиении (это проверяет `test/api.test.js`).
|
|
78
|
-
*/
|
|
41
|
+
/* The entry point of the package, and nothing else: no computation here, only re-exports.
|
|
42
|
+
* The mechanics are laid out along the seams visible in the imports. The public API is a
|
|
43
|
+
* frozen list — `test/api.test.js` does not let it shrink. */
|
|
79
44
|
export { main } from './cli.js';
|
|
80
45
|
export { initMode } from './init.js';
|
|
81
46
|
export { sniffColumns } from './project.js';
|
package/src/strip/forms.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { stripJs } from './js.js';
|
|
2
2
|
|
|
3
|
-
/*
|
|
4
|
-
* JSON.
|
|
5
|
-
*
|
|
3
|
+
/* Text forms with a stripping rule of their own: markup, styles, the lines of a file and
|
|
4
|
+
* JSON. One rule for all of them would either strip nothing at all or corrupt a syntax it was
|
|
5
|
+
* never taught. */
|
|
6
6
|
|
|
7
7
|
export function stripCss(src) {
|
|
8
8
|
return src.replace(/\/\*[\s\S]*?\*\//g, ' ');
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
/* HTML:
|
|
12
|
-
*
|
|
11
|
+
/* HTML: markup comments, and the comments inside <script> as JS and inside <style> as CSS —
|
|
12
|
+
* each part stripped by the rule of its own form rather than by the markup one. */
|
|
13
13
|
export function stripHtml(src) {
|
|
14
14
|
return src
|
|
15
15
|
.replace(/<!--[\s\S]*?-->/g, '')
|
package/src/strip/guard.js
CHANGED
|
@@ -3,52 +3,51 @@ import vm from 'vm';
|
|
|
3
3
|
import { refuseCause } from '../refusal.js';
|
|
4
4
|
import { moduleError } from '../parse.js';
|
|
5
5
|
|
|
6
|
-
/*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* проверили, было бы хуже, чем не проверять.
|
|
6
|
+
/* The stripper's guard: it may throw away nothing but comments and indentation, so its result
|
|
7
|
+
* has to compile. Only the extensions whose content is valid JavaScript are checked (the list
|
|
8
|
+
* is `minify.guard` in the settings): TypeScript or JSX are not checked by the host, and
|
|
9
|
+
* pretending they were would be worse than not checking at all.
|
|
11
10
|
*
|
|
12
|
-
*
|
|
13
|
-
* `import`/`export`
|
|
14
|
-
* `vm.Script`
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* модулем, и тогда наружу идёт причина того разбора, которым файл был.
|
|
11
|
+
* The text, not the extension, decides between a module and a script: a project with a
|
|
12
|
+
* bundler writes `import`/`export` straight into `.js` (with `type: module` in its manifest
|
|
13
|
+
* and without it), while `vm.Script` parses such a file as a script and fails on the very
|
|
14
|
+
* `export`. So the guard tries the shape the file looks like and accepts the result when
|
|
15
|
+
* either of the two parses it. That does not weaken it: a real breakage parses neither way,
|
|
16
|
+
* and then the reason reported is the one from the shape the file had.
|
|
19
17
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
18
|
+
* A module is parsed by a separate worker (`parse.js`), or the guard would cost a Node run per
|
|
19
|
+
* cell: without it a config like `eslint.config.mjs` would stay unguarded, and an edit of it
|
|
20
|
+
* could silently spoil the "volume" number.
|
|
23
21
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
22
|
+
* When even the original text does not parse, the stripper is not to blame: the cell holds
|
|
23
|
+
* something other than JavaScript (TypeScript, JSX), and that is a refusal with a fix —
|
|
24
|
+
* changing the settings. */
|
|
27
25
|
|
|
28
26
|
const MODULE_MARK = /^[ \t]*(?:import|export)\b/m;
|
|
29
27
|
const MODULE_EXT = ['.mjs'];
|
|
30
28
|
|
|
31
29
|
export function assertCompilable(min, rev, p, src) {
|
|
32
|
-
//
|
|
33
|
-
//
|
|
30
|
+
// The script is tried first for its price rather than its shape: it parses in this
|
|
31
|
+
// process, while a module goes to the worker.
|
|
34
32
|
const asScript = scriptError(min, p);
|
|
35
33
|
if (asScript === null) return;
|
|
36
34
|
const asModule = moduleError(min);
|
|
37
35
|
if (asModule === null) return;
|
|
38
36
|
const shape = MODULE_EXT.indexOf(path.extname(p).toLowerCase()) >= 0 || MODULE_MARK.test(min);
|
|
39
37
|
if (src !== undefined && scriptError(src, p) !== null && moduleError(src) !== null) {
|
|
40
|
-
refuseCause('
|
|
41
|
-
+ '
|
|
42
|
-
+ path.extname(p) + '
|
|
43
|
-
+ '
|
|
44
|
-
+ 'minify.ext —
|
|
38
|
+
refuseCause('file is not JavaScript', 'the file ' + p + ' is not JavaScript: its source text parses'
|
|
39
|
+
+ ' neither as a script nor as a module, so the stripper is not to blame, while '
|
|
40
|
+
+ path.extname(p) + ' stands in minify.guard: ' + (shape ? asModule : asScript) + '\n'
|
|
41
|
+
+ ' fix: remove this extension from minify.guard or give it '
|
|
42
|
+
+ 'minify.ext — for example { "' + path.extname(p).toLowerCase() + '": "strip-lines" }');
|
|
45
43
|
}
|
|
46
|
-
//
|
|
47
|
-
|
|
44
|
+
// The reason comes from the parse the file actually was: blaming the other shape would
|
|
45
|
+
// explain nothing.
|
|
46
|
+
throw new Error('the stripper broke ' + p + ' at ' + rev.slice(0, 7) + ': '
|
|
48
47
|
+ (shape ? asModule : asScript));
|
|
49
48
|
}
|
|
50
49
|
|
|
51
|
-
//
|
|
50
|
+
// Parsing as a script happens in this process: cheaper, and without temporary files.
|
|
52
51
|
function scriptError(text, p) {
|
|
53
52
|
try {
|
|
54
53
|
new vm.Script(text, { filename: p });
|