@tilua/compiler 8.1.0 → 9.0.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 CHANGED
@@ -13,10 +13,15 @@ npx tilua src/main.tilua --out build/main.luau
13
13
  ```
14
14
 
15
15
  ```
16
- tilua <entry> [--out <file>] [--output single|chunks|modules] [--config <tilua.config.json>]
17
- [--noCheck] [--noLineMap]
16
+ tilua [<entry>] [--out <file>] [--output single|chunks|files] [--config <tilua.config.json>]
17
+ [--noCheck] [--noLineMap] [--minify] [--watch]
18
+ tilua init
18
19
  ```
19
20
 
21
+ `--watch` builds again whenever a `.tilua` file, the config or a Rojo project
22
+ changes, and keeps going. `tilua init` writes a `tilua.config.json` for the
23
+ Rojo project in the folder — see `@tilua-types/roblox`.
24
+
20
25
  Every module the entry imports is bundled in. Problems are reported as
21
26
  `file:line:column message`. Type errors are checked against the config's
22
27
  `types`: they are reported, but the bundle is still written (`--noCheck` skips
@@ -123,6 +128,11 @@ Luau without asking:
123
128
  | `@native` and other attributes | dropped | kept |
124
129
  | another file of the bundle | `loadfile` | `require` by path |
125
130
 
131
+ Without such a library the output is printed as Lua 5.1, and the printer
132
+ refuses what 5.1 has no syntax for: a `+=` let through, or a library's runtime
133
+ written in Luau, stops the build with `The output cannot be written as Lua
134
+ 5.1: …` instead of failing on a Lua that cannot read it.
135
+
126
136
  An object's `freeze` does nothing on a Lua without `table.freeze`, and
127
137
  `isFrozen` answers `false`. `npm test` with `LUA51` naming a Lua 5.1
128
138
  interpreter builds a program both ways and checks they print the same.
@@ -264,6 +274,18 @@ arguments. `globalCall` and `globalValue` answer for a global, such as
264
274
  `print(x)` or a bare `print`. A runtime can read `__LINES__` to reach the
265
275
  bundle's line map, and wraps a new array it answers with in `__ARRAY__(...)`. See the `@tilua/parser` README for the details.
266
276
 
277
+ `entryExports` answers for what a bundle whose entry exports returns: it is
278
+ handed that expression (`value`) and the entry's exports as an importer sees
279
+ them, and may answer another expression and statements to put before it.
280
+ `@tilua-types/luau` casts the exports table to its Luau type there, so a
281
+ script that `require`s the bundle knows what it got.
282
+
283
+ A library can add options to `tilua.config.json` by declaring them in its
284
+ package.json — `"tilua": { "options": { "typedExports": { "type": "boolean",
285
+ "default": true } } }` — and every hook is handed its library's own as
286
+ `options`. A key no loaded library declares is an unknown option. See the
287
+ `@tilua/parser` README.
288
+
267
289
  A library for a Lua with more syntax than 5.1's lists it, and the output uses
268
290
  it (see [Lua and Luau](#lua-and-luau)):
269
291
 
@@ -306,6 +328,15 @@ everything that reads it: the entry runs without `xpcall`, a callback handed
306
328
  to Roblox is passed through unwrapped, and an error names the bundle's own
307
329
  lines, as plain Luau would.
308
330
 
331
+ ## Layout
332
+
333
+ `"indent": "\t"` (or a number of spaces) indents the output a block level at
334
+ a time; without it nothing is indented. `"minify": true` (or `--minify`, or
335
+ `bundle({ minify: true })`) writes the whole output on one line, keeping a `;`
336
+ only where the next statement starts with `(`. One line cannot be mapped back
337
+ to the project's, so a minified bundle goes without the line map, as with
338
+ `"lineMap": false`.
339
+
309
340
  ## Modules
310
341
 
311
342
  Roblox's `require` takes an Instance, so the bundle has its own. Each module
@@ -401,21 +432,16 @@ says how many files the project becomes:
401
432
  |---|---|
402
433
  | `"single"` (default) | one, holding every module |
403
434
  | `"chunks"` | the entry's, holding what it reaches through `import` statements; one for each `import()` that leads somewhere else, holding what only it reaches; and one for what several of those share |
404
- | `"modules"` | one per module, in the project's own tree |
435
+ | `"files"` | no entry: one per file under `rootDir`, in the same place under `outDir`, and the runtime — see [A file per module](#a-file-per-module) |
405
436
 
406
437
  ```
407
438
  tilua src/main.tilua --out build/main.luau --output chunks
408
439
  # build/main.luau, build/main_src_shop.luau, ...
409
-
410
- tilua src/main.tilua --out build --output modules
411
- # build/src/main.luau, build/src/shop.luau, ...
412
440
  ```
413
441
 
414
- With `"modules"`, `--out` is the folder the tree goes in — by default the
415
- project's, so each `.luau` lands beside its `.tilua`. From the API,
416
- `result.files` holds every file with the path it has to be written at, the
417
- entry's first; `outFile` names the entry's file, which the others are named
418
- after.
442
+ From the API, `result.files` holds every file with the path it has to be
443
+ written at, the entry's first; `outFile` names the entry's file, which the
444
+ others are named after.
419
445
 
420
446
  The module table is the same one, filled by more than one file. The entry's
421
447
  file has the runtime; every other file is a function that adds its modules:
@@ -441,15 +467,84 @@ How a file is loaded depends on the Lua (see [Lua and Luau](#lua-and-luau)):
441
467
  Either way the files have to stay where they were written, relative to the
442
468
  entry's.
443
469
 
470
+ ## A file per module
471
+
472
+ `"output": "files"` has no entry. Every `.tilua` under `rootDir` (a
473
+ definitions file aside) becomes a `.luau` in the same place under `outDir`,
474
+ as `tsc` writes `src` to `dist`, and each of them is a file a script can
475
+ `require`:
476
+
477
+ ```jsonc
478
+ { "types": ["roblox"], "output": "files", "rootDir": "src", "outDir": "dist" }
479
+ ```
480
+
481
+ ```
482
+ tilua # the config above this folder says the rest
483
+ # dist/main.luau, dist/shop/buy.luau, ..., dist/_tilua.luau
484
+ ```
485
+
486
+ `rootDir` is the config's folder unless set, and `outDir` is `rootDir`, so
487
+ each `.luau` lands beside its `.tilua`. Every file it writes ends with a line
488
+ saying tilua wrote it: the CLI never replaces a `.luau` without that line —
489
+ one written by hand — and removes one with it whose `.tilua` is gone. `--out` names the folder in place of
490
+ `outDir`. From the API, `bundle({ output: "files", root })` without an
491
+ `entry`; `result.files` holds every file, its path from `outDir`.
492
+
493
+ The runtime — the module table, `require`, the line maps, and the helpers
494
+ the modules share, the language's and the libraries' runtimes, each set up
495
+ once — is a file of its own, `_tilua.luau`. Every other file requires it,
496
+ takes the helpers it names from it, adds its module to the table, and returns
497
+ the module's exports:
498
+
499
+ ```lua
500
+ local G = require("../_tilua")
501
+ G.modules["src/shop/buy"] = { load = function(exports)
502
+ local tax
503
+ tax = G.require("src/shop/tax", function()
504
+ return require("./tax")
505
+ end)
506
+ ...
507
+ end }
508
+ return G.run("src/shop/buy")
509
+ ```
510
+
511
+ An `import` is still the runtime's `require`, so the modules behave as they
512
+ do in one file: a cycle gets the exports as they stand (Luau's own `require`
513
+ refuses one), and exports are live. The function after the name requires the
514
+ module's file by its path from this one, written out for the tools that
515
+ follow a `require`, and only if nothing has loaded it yet; an `import()` is
516
+ the same, where it runs. `run` is `require` under `xpcall` for the first file
517
+ asked for, so an error reaches the project's files once, however deep.
518
+
519
+ A file named `init.tilua` is the folder it is in, as Luau reads `init.luau`:
520
+ `import "./net"` finds `net/init.tilua`, the folder's files require it as
521
+ `./net`, and it requires them as `@self/remote`.
522
+
523
+ Where the files end up is the host's to say: a library's `files` hook can
524
+ place each file somewhere else, name the top of that tree (`@game`), move
525
+ the runtime, run something first in a file, and mark the files that are
526
+ scripts the host runs rather than modules — nothing may import one.
527
+ `@tilua-types/roblox` answers from a Rojo project.
528
+
529
+ A file is required by its path, which Luau reads and Lua 5.1 does not: the
530
+ output needs a library that says its Lua can (`requireByPath` — `"luau"`, or
531
+ `"roblox"`, which loads it). A file imported from outside `rootDir` has no
532
+ place under `outDir`, and is an error. Without an entry there is nothing to
533
+ reach things from, so `treeShaking` leaves no module out; it still leaves out
534
+ the runtime functions nothing calls.
535
+
536
+ `@tilua-types/luau` casts what each file returns to its module's exports, so
537
+ a script that requires any of them knows what it got.
538
+
444
539
  <!-- compatibility:start -->
445
540
  ## Compatibility
446
541
 
447
- `@tilua/compiler@8.1.0` works with these tilua packages. *Released with* is the
542
+ `@tilua/compiler@9.0.0` works with these tilua packages. *Released with* is the
448
543
  version it was built and tested against.
449
544
 
450
545
  | Package | Range | Released with | |
451
546
  | --- | --- | --- | --- |
452
- | `@tilua/parser` | `^8.1.0` | 8.1.0 | dependency |
547
+ | `@tilua/parser` | `^9.0.0` | 9.0.0 | dependency |
453
548
  <!-- compatibility:end -->
454
549
 
455
550
  ## Development