storm-lua-minify 0.1.1 → 0.1.3

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 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.Minifier = void 0;
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 Minifier {
207
+ class MinifyFile {
210
208
  fileName;
211
209
  ast;
212
- requireHelper;
213
- constructor(fileName, ast, requireHelper) {
210
+ minifier;
211
+ mode;
212
+ constructor(fileName, ast, minifier, mode) {
214
213
  this.fileName = fileName;
215
214
  this.ast = ast;
216
- this.requireHelper = requireHelper;
217
- ast.globals?.map((v) => identifiersInUse.add(v.name));
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
- /*if (this.ast.comments) {
222
- const comments = this.ast.comments as Comment[];
223
- comments.reverse().filter(v => v.raw.includes("--#") || v.raw.includes("[[#")).forEach(comment => {
224
- body.prepend(this.sourceNodeHelper(comment, comment.raw));
225
- })
226
- return body;
227
- } else*/ {
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
- if (this.formatBase(expression.base).toString() == "require" &&
504
+ const callExpr = this.formatBase(expression.base).toString();
505
+ if ((callExpr === "require" || callExpr === "dofile") &&
505
506
  expression?.arguments[0].type === "StringLiteral") {
506
- const res = this.requireHelper(expression.arguments[0].raw.replaceAll('"', ""));
507
- if (res != undefined) {
508
- return res;
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.Minifier = Minifier;
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 luaparse_1 = __importDefault(require("luaparse"));
11
- const ast2lua_1 = require("./ast2lua");
10
+ const minifier_1 = require("./minifier");
12
11
  const program = new commander_1.Command();
13
- program.version("0.1.0").description("A Lua minifier also outputs source map");
12
+ program
13
+ .version("0.1.3")
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 code = fs_1.default.readFileSync(fileName).toString();
41
- const ast = luaparse_1.default.parse(code, luaparseSetting);
42
- if ("globals" in ast) {
43
- includes.set(parsedFileName.base, code);
44
- const map = new ast2lua_1.Minifier(parsedFileName.base, ast, requireHelper).parse();
45
- includes.forEach((v, k) => {
46
- console.log(k);
47
- map.setSourceContent(k, v);
48
- });
49
- const minFileName = path_1.default.format({
50
- dir: parsedFileName.dir,
51
- name: parsedFileName.name + ".min",
52
- ext: ".lua",
53
- });
54
- const mapFileName = path_1.default.format({
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=" + path_1.default.basename(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);
@@ -0,0 +1,98 @@
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
+ moduleNameAndFileName;
19
+ dir;
20
+ entryModule;
21
+ mode;
22
+ luaParseSettings;
23
+ constructor(entryFilePath, luaParseSettings, mode) {
24
+ this.identifierMap = new Map();
25
+ this.identifiersInUse = new Set();
26
+ this.moduleSourceText = new Map();
27
+ this.moduleSourceNode = new Map();
28
+ this.moduleAST = new Map();
29
+ this.moduleNameAndFileName = new Map();
30
+ this.luaParseSettings = luaParseSettings;
31
+ this.mode = mode;
32
+ const pn = path_1.default.parse(entryFilePath);
33
+ this.dir = pn.dir;
34
+ this.entryModule = pn.name;
35
+ }
36
+ parse() {
37
+ const sn = this.parseModule(this.entryModule);
38
+ if (this.mode.moduleLikeLua) {
39
+ // require関数を作成し、流し込む
40
+ /*
41
+ function require(m,r)
42
+ package=package or {loaded={}}
43
+ if package.loaded[m] then return package.loaded[m] end
44
+ if m=="<MODULE_NAME>" then r=(function()[[MODULE]]end)() end
45
+ package.loaded[m]=package.loaded[m] or r or true;return package.loaded[m]
46
+ end
47
+ */
48
+ sn.prepend("package.loaded[m]=package.loaded[m]or r or true;return package.loaded[m]end\n");
49
+ this.moduleSourceNode.forEach((v, k) => {
50
+ if (k !== this.entryModule) {
51
+ sn.prepend(["if m==\"", k, "\"then r=(function() ", v, " end)()end\n"]);
52
+ }
53
+ });
54
+ sn.prepend("function require(m,r)package=package or{loaded={}};if package.loaded[m]then return package.loaded[m]end\n");
55
+ }
56
+ // コメントの流し込み
57
+ const comments = this.moduleAST.get(this.entryModule)?.comments;
58
+ if (comments) {
59
+ comments
60
+ .reverse()
61
+ .filter((v) => v.raw.includes("--#") || v.raw.includes("[[#"))
62
+ .forEach((comment) => {
63
+ sn.prepend([
64
+ new source_map_1.SourceNode(comment.loc?.start.line || null, comment.loc?.start.column || null, this.entryModule, // 本当に自分のファイル名でよいかは要検討
65
+ comment.raw),
66
+ "\n"
67
+ ]);
68
+ });
69
+ }
70
+ this.moduleSourceText.forEach((v, k) => { const fileName = this.moduleNameAndFileName.get(k); fileName && sn.setSourceContent(fileName, v); });
71
+ return sn;
72
+ }
73
+ parseModule(moduleName) {
74
+ const resolvePath = moduleName.replaceAll(".", path_1.default.sep) + ".lua";
75
+ const fullResolvePath = path_1.default.join(this.dir, resolvePath);
76
+ if (this.moduleSourceNode.has(moduleName)) {
77
+ const res = this.moduleSourceNode.get(moduleName);
78
+ if (res) {
79
+ return res;
80
+ }
81
+ }
82
+ else if (fs_1.default.existsSync(fullResolvePath)) {
83
+ const code = fs_1.default.readFileSync(fullResolvePath).toString();
84
+ const ast = luaparse_1.default.parse(code, this.luaParseSettings);
85
+ if ("globals" in ast) {
86
+ ast.globals?.map((v) => this.identifiersInUse.add(v.name));
87
+ const sourceNode = new ast2lua_1.MinifyFile(resolvePath, ast, this, this.mode).parse(moduleName === this.entryModule);
88
+ this.moduleSourceText.set(moduleName, code);
89
+ this.moduleAST.set(moduleName, ast);
90
+ this.moduleSourceNode.set(moduleName, sourceNode);
91
+ this.moduleNameAndFileName.set(moduleName, resolvePath);
92
+ return sourceNode;
93
+ }
94
+ }
95
+ throw new Error(moduleName + " is not found");
96
+ }
97
+ }
98
+ exports.Minifier = Minifier;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "storm-lua-minify",
3
3
  "description": "A Lua minifier also outputs source map",
4
- "version": "0.1.1",
4
+ "version": "0.1.3",
5
5
  "dependencies": {
6
6
  "commander": "^12.1.0",
7
7
  "luamin": "^1.0.4",
package/src/cli.ts CHANGED
@@ -9,7 +9,7 @@ import { Minifier, MinifierMode } from "./minifier";
9
9
  const program = new Command();
10
10
 
11
11
  program
12
- .version("0.1.1")
12
+ .version("0.1.3")
13
13
  .description("A Lua minifier also outputs source map")
14
14
  .option(
15
15
  "-m, --module-like-lua",
@@ -44,7 +44,7 @@ luaFiles.forEach((fileName) => {
44
44
  name: parsedFileName.name,
45
45
  ext: parsedFileName.ext + ".map",
46
46
  });
47
- map.add("\n--[[\n//# sourceMappingURL=" + mapFileName + "\n]]");
47
+ map.add("\n--[[\n//# sourceMappingURL=" + path.basename(mapFileName) + "\n]]");
48
48
 
49
49
  const sourceAndMap = map.toStringWithSourceMap();
50
50
 
package/src/minifier.ts CHANGED
@@ -14,6 +14,7 @@ export class Minifier {
14
14
  readonly moduleSourceText: Map<string, string>;
15
15
  readonly moduleSourceNode: Map<string, SourceNode>;
16
16
  readonly moduleAST: Map<string, Chunk>;
17
+ readonly moduleNameAndFileName: Map<string, string>;
17
18
  readonly dir: string;
18
19
  readonly entryModule: string;
19
20
  readonly mode: MinifierMode;
@@ -29,6 +30,7 @@ export class Minifier {
29
30
  this.moduleSourceText = new Map<string, string>();
30
31
  this.moduleSourceNode = new Map<string, SourceNode>();
31
32
  this.moduleAST = new Map<string, Chunk>();
33
+ this.moduleNameAndFileName = new Map<string, string>();
32
34
  this.luaParseSettings = luaParseSettings;
33
35
  this.mode = mode;
34
36
  const pn = path.parse(entryFilePath);
@@ -78,6 +80,7 @@ export class Minifier {
78
80
  });
79
81
  }
80
82
 
83
+ this.moduleSourceText.forEach((v, k) => { const fileName = this.moduleNameAndFileName.get(k); fileName && sn.setSourceContent(fileName, v) });
81
84
  return sn;
82
85
  }
83
86
 
@@ -101,11 +104,12 @@ export class Minifier {
101
104
  ast,
102
105
  this,
103
106
  this.mode
104
- ).parse(resolvePath === this.entryModule);
107
+ ).parse(moduleName === this.entryModule);
105
108
 
106
109
  this.moduleSourceText.set(moduleName, code);
107
110
  this.moduleAST.set(moduleName, ast);
108
111
  this.moduleSourceNode.set(moduleName, sourceNode);
112
+ this.moduleNameAndFileName.set(moduleName, resolvePath);
109
113
  return sourceNode;
110
114
  }
111
115
  }