@tilua/compiler 8.0.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]
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
 
@@ -296,6 +318,25 @@ With several files each has its own line map, and a position is read by the
296
318
  map of the file it names — matched by the end of that file's path, since the
297
319
  Lua running it may call it by a full path, a relative one, or an Instance's.
298
320
 
321
+ The map is packed — the files it names once, then three base-64 VLQ numbers a
322
+ line, each counted from the line before — and read out the first time a line
323
+ is looked up, so a program that never fails never unpacks it.
324
+
325
+ For a release nobody will debug, `"lineMap": false` in `tilua.config.json`
326
+ (or `--noLineMap`, or `bundle({ lineMap: false })`) leaves out the map and
327
+ everything that reads it: the entry runs without `xpcall`, a callback handed
328
+ to Roblox is passed through unwrapped, and an error names the bundle's own
329
+ lines, as plain Luau would.
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
+
299
340
  ## Modules
300
341
 
301
342
  Roblox's `require` takes an Instance, so the bundle has its own. Each module
@@ -391,21 +432,16 @@ says how many files the project becomes:
391
432
  |---|---|
392
433
  | `"single"` (default) | one, holding every module |
393
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 |
394
- | `"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) |
395
436
 
396
437
  ```
397
438
  tilua src/main.tilua --out build/main.luau --output chunks
398
439
  # build/main.luau, build/main_src_shop.luau, ...
399
-
400
- tilua src/main.tilua --out build --output modules
401
- # build/src/main.luau, build/src/shop.luau, ...
402
440
  ```
403
441
 
404
- With `"modules"`, `--out` is the folder the tree goes in — by default the
405
- project's, so each `.luau` lands beside its `.tilua`. From the API,
406
- `result.files` holds every file with the path it has to be written at, the
407
- entry's first; `outFile` names the entry's file, which the others are named
408
- 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.
409
445
 
410
446
  The module table is the same one, filled by more than one file. The entry's
411
447
  file has the runtime; every other file is a function that adds its modules:
@@ -431,15 +467,84 @@ How a file is loaded depends on the Lua (see [Lua and Luau](#lua-and-luau)):
431
467
  Either way the files have to stay where they were written, relative to the
432
468
  entry's.
433
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
+
434
539
  <!-- compatibility:start -->
435
540
  ## Compatibility
436
541
 
437
- `@tilua/compiler@8.0.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
438
543
  version it was built and tested against.
439
544
 
440
545
  | Package | Range | Released with | |
441
546
  | --- | --- | --- | --- |
442
- | `@tilua/parser` | `^8.0.0` | 8.0.0 | dependency |
547
+ | `@tilua/parser` | `^9.0.0` | 9.0.0 | dependency |
443
548
  <!-- compatibility:end -->
444
549
 
445
550
  ## Development