storm-lua-minify 0.1.1 → 0.1.2
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/dist/ast2lua.js +36 -26
- package/dist/cli.js +21 -42
- package/dist/minifier.js +94 -0
- package/package.json +1 -1
- package/src/cli.ts +1 -1
package/dist/ast2lua.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// based on "luamin": Copyright Mathias Bynens <https://mathiasbynens.be/>
|
|
3
3
|
// SPDX-License-Identifier: MIT
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.
|
|
5
|
+
exports.MinifyFile = void 0;
|
|
6
6
|
const source_map_1 = require("source-map");
|
|
7
7
|
const PRECEDENCE = {
|
|
8
8
|
or: 1,
|
|
@@ -89,8 +89,6 @@ const IDENTIFIER_PARTS = [
|
|
|
89
89
|
"Z",
|
|
90
90
|
"_",
|
|
91
91
|
];
|
|
92
|
-
const identifierMap = new Map();
|
|
93
|
-
const identifiersInUse = new Set();
|
|
94
92
|
function wrapArray(obj) {
|
|
95
93
|
if (Array.isArray(obj)) {
|
|
96
94
|
return obj;
|
|
@@ -206,25 +204,27 @@ function prependWithSeparator(val, prepending, separator = " ") {
|
|
|
206
204
|
function insertSeparator(a, b, separator = " ") {
|
|
207
205
|
return isNeedSeparator(a.toString(), b.toString()) ? separator : undefined;
|
|
208
206
|
}
|
|
209
|
-
class
|
|
207
|
+
class MinifyFile {
|
|
210
208
|
fileName;
|
|
211
209
|
ast;
|
|
212
|
-
|
|
213
|
-
|
|
210
|
+
minifier;
|
|
211
|
+
mode;
|
|
212
|
+
constructor(fileName, ast, minifier, mode) {
|
|
214
213
|
this.fileName = fileName;
|
|
215
214
|
this.ast = ast;
|
|
216
|
-
this.
|
|
217
|
-
|
|
215
|
+
this.minifier = minifier;
|
|
216
|
+
this.mode = mode;
|
|
218
217
|
}
|
|
219
|
-
parse() {
|
|
218
|
+
parse(noComment) {
|
|
220
219
|
const body = this.formatStatementList(this.ast.body);
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
}
|
|
220
|
+
if (!noComment && this.ast.comments) {
|
|
221
|
+
const comments = this.ast.comments;
|
|
222
|
+
comments.reverse().filter(v => v.raw.includes("--#") || v.raw.includes("[[#")).forEach(comment => {
|
|
223
|
+
body.prepend([this.sourceNodeHelper(comment, comment.raw), "\n"]);
|
|
224
|
+
});
|
|
225
|
+
return body;
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
228
|
return body;
|
|
229
229
|
}
|
|
230
230
|
}
|
|
@@ -501,11 +501,21 @@ class Minifier {
|
|
|
501
501
|
}
|
|
502
502
|
else if (expression.type == "CallExpression") {
|
|
503
503
|
// requireの展開モードは2種類: SLモード-その場に読み込み, FLモード-require相当の関数で呼び出し
|
|
504
|
-
|
|
504
|
+
const callExpr = this.formatBase(expression.base).toString();
|
|
505
|
+
if ((callExpr === "require" || callExpr === "dofile") &&
|
|
505
506
|
expression?.arguments[0].type === "StringLiteral") {
|
|
506
|
-
const
|
|
507
|
-
|
|
508
|
-
|
|
507
|
+
const moduleName = expression.arguments[0].raw
|
|
508
|
+
.replaceAll('"', "")
|
|
509
|
+
.replaceAll("'", "");
|
|
510
|
+
const res = this.minifier.parseModule(moduleName);
|
|
511
|
+
if (this.mode.moduleLikeLua) {
|
|
512
|
+
if (callExpr === "dofile") {
|
|
513
|
+
return (res || this.sourceNodeHelper(undefined, ""));
|
|
514
|
+
}
|
|
515
|
+
// requireならスキップ
|
|
516
|
+
}
|
|
517
|
+
else {
|
|
518
|
+
return (res || this.sourceNodeHelper(undefined, ""));
|
|
509
519
|
}
|
|
510
520
|
}
|
|
511
521
|
const args = expression.arguments
|
|
@@ -632,7 +642,7 @@ class Minifier {
|
|
|
632
642
|
if (nameItem.name === "self") {
|
|
633
643
|
return this.sourceNodeHelper(nameItem, "self", "self");
|
|
634
644
|
}
|
|
635
|
-
const defined = identifierMap.get(nameItem.name);
|
|
645
|
+
const defined = this.minifier.identifierMap.get(nameItem.name);
|
|
636
646
|
if (defined) {
|
|
637
647
|
return this.sourceNodeHelper(nameItem, defined, nameItem.name); // 第3引数は要調査
|
|
638
648
|
}
|
|
@@ -649,21 +659,21 @@ class Minifier {
|
|
|
649
659
|
IDENTIFIER_PARTS[index + 1] +
|
|
650
660
|
generateZeroes(length - (position + 1));
|
|
651
661
|
if (isKeyword(this.currentIdentifier) ||
|
|
652
|
-
identifiersInUse.has(this.currentIdentifier)) {
|
|
662
|
+
this.minifier.identifiersInUse.has(this.currentIdentifier)) {
|
|
653
663
|
return this.generateIdentifier(nameItem, nested);
|
|
654
664
|
}
|
|
655
|
-
identifierMap.set(nameItem.name, this.currentIdentifier);
|
|
665
|
+
this.minifier.identifierMap.set(nameItem.name, this.currentIdentifier);
|
|
656
666
|
return this.generateIdentifier(nameItem, nested);
|
|
657
667
|
}
|
|
658
668
|
--position;
|
|
659
669
|
}
|
|
660
670
|
this.currentIdentifier = "a" + generateZeroes(length);
|
|
661
|
-
if (identifiersInUse.has(this.currentIdentifier)) {
|
|
671
|
+
if (this.minifier.identifiersInUse.has(this.currentIdentifier)) {
|
|
662
672
|
return this.generateIdentifier(nameItem, nested);
|
|
663
673
|
}
|
|
664
|
-
identifierMap.set(nameItem.name, this.currentIdentifier);
|
|
674
|
+
this.minifier.identifierMap.set(nameItem.name, this.currentIdentifier);
|
|
665
675
|
return this.generateIdentifier(nameItem, nested);
|
|
666
676
|
// return this.sourceNodeHelper(nameItem, nameItem.name, nested ? nameItem.name : undefined);
|
|
667
677
|
}
|
|
668
678
|
}
|
|
669
|
-
exports.
|
|
679
|
+
exports.MinifyFile = MinifyFile;
|
package/dist/cli.js
CHANGED
|
@@ -7,10 +7,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const commander_1 = require("commander");
|
|
10
|
-
const
|
|
11
|
-
const ast2lua_1 = require("./ast2lua");
|
|
10
|
+
const minifier_1 = require("./minifier");
|
|
12
11
|
const program = new commander_1.Command();
|
|
13
|
-
program
|
|
12
|
+
program
|
|
13
|
+
.version("0.1.2")
|
|
14
|
+
.description("A Lua minifier also outputs source map")
|
|
15
|
+
.option("-m, --module-like-lua", "require・dofileの動作を実際のLuaに近づけます");
|
|
14
16
|
program.parse(process.argv);
|
|
15
17
|
const luaFiles = program.args;
|
|
16
18
|
const luaparseSetting = {
|
|
@@ -19,48 +21,25 @@ const luaparseSetting = {
|
|
|
19
21
|
ranges: true,
|
|
20
22
|
scope: true,
|
|
21
23
|
};
|
|
24
|
+
const mode = program.opts();
|
|
22
25
|
luaFiles.forEach((fileName) => {
|
|
23
|
-
const includes = new Map();
|
|
24
26
|
const parsedFileName = path_1.default.parse(fileName);
|
|
25
|
-
function requireHelper(recursiveFilePath) {
|
|
26
|
-
const resolvePath = path_1.default.relative(parsedFileName.dir, path_1.default.join(parsedFileName.dir, recursiveFilePath.replaceAll(".", path_1.default.sep) + ".lua"));
|
|
27
|
-
const fullResolvePath = path_1.default.join(parsedFileName.dir, resolvePath);
|
|
28
|
-
if (!includes.has(resolvePath) && fs_1.default.existsSync(fullResolvePath)) {
|
|
29
|
-
const code = fs_1.default.readFileSync(fullResolvePath).toString();
|
|
30
|
-
const ast = luaparse_1.default.parse(code, luaparseSetting);
|
|
31
|
-
if ("globals" in ast) {
|
|
32
|
-
includes.set(resolvePath, code);
|
|
33
|
-
return new ast2lua_1.Minifier(resolvePath, ast, requireHelper).parse();
|
|
34
|
-
}
|
|
35
|
-
includes.set(resolvePath, "");
|
|
36
|
-
return undefined;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
27
|
if (fs_1.default.existsSync(fileName)) {
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
dir: parsedFileName.dir,
|
|
56
|
-
name: parsedFileName.name,
|
|
57
|
-
ext: parsedFileName.ext + ".map",
|
|
58
|
-
});
|
|
59
|
-
map.add("\n--[[\n//# sourceMappingURL=" + mapFileName + "\n]]");
|
|
60
|
-
const sourceAndMap = map.toStringWithSourceMap();
|
|
61
|
-
fs_1.default.writeFileSync(minFileName, sourceAndMap.code);
|
|
62
|
-
fs_1.default.writeFileSync(mapFileName, JSON.stringify(sourceAndMap.map));
|
|
63
|
-
}
|
|
28
|
+
const map = new minifier_1.Minifier(fileName, luaparseSetting, mode).parse();
|
|
29
|
+
const minFileName = path_1.default.format({
|
|
30
|
+
dir: parsedFileName.dir,
|
|
31
|
+
name: parsedFileName.name + ".min",
|
|
32
|
+
ext: ".lua",
|
|
33
|
+
});
|
|
34
|
+
const mapFileName = path_1.default.format({
|
|
35
|
+
dir: parsedFileName.dir,
|
|
36
|
+
name: parsedFileName.name,
|
|
37
|
+
ext: parsedFileName.ext + ".map",
|
|
38
|
+
});
|
|
39
|
+
map.add("\n--[[\n//# sourceMappingURL=" + mapFileName + "\n]]");
|
|
40
|
+
const sourceAndMap = map.toStringWithSourceMap();
|
|
41
|
+
fs_1.default.writeFileSync(minFileName, sourceAndMap.code);
|
|
42
|
+
fs_1.default.writeFileSync(mapFileName, JSON.stringify(sourceAndMap.map));
|
|
64
43
|
}
|
|
65
44
|
else {
|
|
66
45
|
console.error("No such file: " + fileName);
|
package/dist/minifier.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Minifier = void 0;
|
|
7
|
+
const luaparse_1 = __importDefault(require("luaparse"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const source_map_1 = require("source-map");
|
|
11
|
+
const ast2lua_1 = require("./ast2lua");
|
|
12
|
+
class Minifier {
|
|
13
|
+
identifierMap;
|
|
14
|
+
identifiersInUse;
|
|
15
|
+
moduleSourceText;
|
|
16
|
+
moduleSourceNode;
|
|
17
|
+
moduleAST;
|
|
18
|
+
dir;
|
|
19
|
+
entryModule;
|
|
20
|
+
mode;
|
|
21
|
+
luaParseSettings;
|
|
22
|
+
constructor(entryFilePath, luaParseSettings, mode) {
|
|
23
|
+
this.identifierMap = new Map();
|
|
24
|
+
this.identifiersInUse = new Set();
|
|
25
|
+
this.moduleSourceText = new Map();
|
|
26
|
+
this.moduleSourceNode = new Map();
|
|
27
|
+
this.moduleAST = new Map();
|
|
28
|
+
this.luaParseSettings = luaParseSettings;
|
|
29
|
+
this.mode = mode;
|
|
30
|
+
const pn = path_1.default.parse(entryFilePath);
|
|
31
|
+
this.dir = pn.dir;
|
|
32
|
+
this.entryModule = pn.name;
|
|
33
|
+
}
|
|
34
|
+
parse() {
|
|
35
|
+
const sn = this.parseModule(this.entryModule);
|
|
36
|
+
if (this.mode.moduleLikeLua) {
|
|
37
|
+
// require関数を作成し、流し込む
|
|
38
|
+
/*
|
|
39
|
+
function require(m,r)
|
|
40
|
+
package=package or {loaded={}}
|
|
41
|
+
if package.loaded[m] then return package.loaded[m] end
|
|
42
|
+
if m=="<MODULE_NAME>" then r=(function()[[MODULE]]end)() end
|
|
43
|
+
package.loaded[m]=package.loaded[m] or r or true;return package.loaded[m]
|
|
44
|
+
end
|
|
45
|
+
*/
|
|
46
|
+
sn.prepend("package.loaded[m]=package.loaded[m]or r or true;return package.loaded[m]end\n");
|
|
47
|
+
this.moduleSourceNode.forEach((v, k) => {
|
|
48
|
+
if (k !== this.entryModule) {
|
|
49
|
+
sn.prepend(["if m==\"", k, "\"then r=(function() ", v, " end)()end\n"]);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
sn.prepend("function require(m,r)package=package or{loaded={}};if package.loaded[m]then return package.loaded[m]end\n");
|
|
53
|
+
}
|
|
54
|
+
// コメントの流し込み
|
|
55
|
+
const comments = this.moduleAST.get(this.entryModule)?.comments;
|
|
56
|
+
if (comments) {
|
|
57
|
+
comments
|
|
58
|
+
.reverse()
|
|
59
|
+
.filter((v) => v.raw.includes("--#") || v.raw.includes("[[#"))
|
|
60
|
+
.forEach((comment) => {
|
|
61
|
+
sn.prepend([
|
|
62
|
+
new source_map_1.SourceNode(comment.loc?.start.line || null, comment.loc?.start.column || null, this.entryModule, // 本当に自分のファイル名でよいかは要検討
|
|
63
|
+
comment.raw),
|
|
64
|
+
"\n"
|
|
65
|
+
]);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return sn;
|
|
69
|
+
}
|
|
70
|
+
parseModule(moduleName) {
|
|
71
|
+
const resolvePath = moduleName.replaceAll(".", path_1.default.sep) + ".lua";
|
|
72
|
+
const fullResolvePath = path_1.default.join(this.dir, resolvePath);
|
|
73
|
+
if (this.moduleSourceNode.has(moduleName)) {
|
|
74
|
+
const res = this.moduleSourceNode.get(moduleName);
|
|
75
|
+
if (res) {
|
|
76
|
+
return res;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (fs_1.default.existsSync(fullResolvePath)) {
|
|
80
|
+
const code = fs_1.default.readFileSync(fullResolvePath).toString();
|
|
81
|
+
const ast = luaparse_1.default.parse(code, this.luaParseSettings);
|
|
82
|
+
if ("globals" in ast) {
|
|
83
|
+
ast.globals?.map((v) => this.identifiersInUse.add(v.name));
|
|
84
|
+
const sourceNode = new ast2lua_1.MinifyFile(resolvePath, ast, this, this.mode).parse(resolvePath === this.entryModule);
|
|
85
|
+
this.moduleSourceText.set(moduleName, code);
|
|
86
|
+
this.moduleAST.set(moduleName, ast);
|
|
87
|
+
this.moduleSourceNode.set(moduleName, sourceNode);
|
|
88
|
+
return sourceNode;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
throw new Error(moduleName + " is not found");
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
exports.Minifier = Minifier;
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED