darklua

repository·main·Indexed 42 days ago

https://github.com/seaofvoices/darklua

A code transformation tool for Lua 5.1 and Roblox Luau that allows developers to apply configurable rules to transform source code. It supports bundling Lua code by merging require calls into a single file, converting data files (JSON, YAML, TOML) into Lua modules, and providing custom content loaders for asset management.

Tokens
15.4K
Snippets
61
Records
80
Agent score
52%

What's inside darklua

  1. Understand the Gatsby project structure

    main

    A standard Gatsby project includes several key configuration files and directories:

    • /src: Contains front-end source code (e.g., components, page templates).
    • gatsby-config.js: The main configuration file for site metadata and plugin management.
    • gatsby-node.js: Used to implement Gatsby Node APIs to customize the site build process.
    • gatsby-browser.js: Used to implement Gatsby browser APIs for customizations affecting the browser.
    • gatsby-ssr.js: Used to implement Gatsby server-side rendering (SSR) APIs.
    • package.json: The Node.js manifest file defining project metadata and dependencies.
    • .prettierrc: Configuration for the Prettier code formatting tool.
  2. How Path Resolution works in Path Require Mode

    main

    When darklua encounters a require call with a string, it resolves the path in two steps:

    1. Finding the Head (Starting Point)

    • Starts with . or ..: The path is relative to the file containing the require call.
    • Starts with /: The path is treated as an absolute path.
    • Otherwise: The first component of the path is used to look up a matching entry in the configured sources.

    2. Resolving the Tail (File Matching)

    Darklua searches for the first available file in this specific order:

    1. The exact path provided.
    2. The path + .luau extension.
    3. The path + .lua extension.
    4. The path joined with the module_folder_name (e.g., ./path/init).
    5. The path joined with module_folder_name + .luau.
    6. The path joined with module_folder_name + .lua.

    Example: A require for ./example will check:

    • ./example
    • ./example.luau
    • ./example.lua
    • ./example/init
    • ./example/init.luau
    • ./example/init.lua
  3. Integrate with Luau configuration files (.luaurc)

    main

    Darklua can respect Luau's native configuration files named .luaurc. These files can contain an aliases parameter that functions identically to the aliases parameter in darklua.

    To enable this behavior, ensure use_luau_configuration is set to true (which is the default) in your darklua luau require mode configuration. When enabled, darklua will search for the nearest .luaurc file relative to each file being processed and load its aliases before applying the aliases defined in the darklua config.

  4. Use Luau Require Mode for bundling

    main

    The luau require mode allows darklua to resolve content using Luau-specific module paths, following Luau RFCs for require resolution (including Amended Require Resolution and Abstract Module Paths). This mode is specifically designed to match the behavior of the Lune runtime.

    Warning: Do not confuse the luau require mode with the path require mode. While both use strings that look like file paths, they resolve to actual files using different logic.

    {
      "bundle": {
        "require_mode": {
          "name": "luau"
        }
      }
    }
  5. Use Luau Configuration Files (.luaurc) for aliases

    main

    Darklua can respect Luau configuration files named .luaurc. These files can contain an aliases parameter that functions identically to the sources parameter in darklua's own configuration.

    If use_luau_configuration is set to true (which is the default), darklua will attempt to find the nearest .luaurc file relative to each file it processes and load its aliases before checking the main darklua sources configuration.

    To disable this behavior, set use_luau_configuration: false in your path require mode configuration.

  6. How darklua content loaders work

    main

    darklua selects a loader for every file based on its extension or a configured pattern.

    • Default Behavior: Lua and Luau files are parsed as code; recognized data files (JSON, TOML, YAML) are converted to Lua modules; other files are ignored.
    • Custom Loaders: You can use the loaders field in your configuration to map glob patterns to specific loader names.
    • Pattern Matching: Patterns are matched in order. The first pattern that matches a file is the one used.
    • Fallback: If no pattern matches, darklua falls back to extension-based defaults. If no default loader exists for an extension, the file is skipped.
    {
      loaders: {
        "**/*.model.json": "copy",
        "**/*.md": "string",
        "**/*.png": "buffer/base64",
      },
    }
  7. Configure Roblox Require Mode without a Rojo Sourcemap

    main

    If you do not provide a rojo_sourcemap, darklua assumes all paths are relative to the file performing the require and that the file structure matches the Roblox DataModel.

    Example conversions:

    • ./MyClass becomes script.Parent:FindFirstChild("MyClass") (or script:FindFirstChild("MyClass") if the target is an init.lua module).
    • ../MyClass becomes script.Parent.Parent:FindFirstChild("MyClass").
  8. How darklua rules work

    main

    Rules are the core mechanism that transform Lua code. When running darklua process, the engine iterates through a provided list of rules sequentially. Each rule transforms the code and passes the result to the next rule in the list.

    Important: The order of rules in your configuration matters. You should perform operations like injecting values (e.g., using inject_global_value) before attempting to perform static expression computation or optimizing if branches, as subsequent rules depend on the code state produced by earlier ones.

  9. Require data files as Lua during bundling

    main

    When using the path require mode, darklua can automatically convert data files into Lua data structures during the bundling process. It supports the following file extensions:

    • JSON: .json or .json5
    • YAML: .yml or .yaml
    • Toml: .toml
    • Text: .txt (mapped to a string containing the file content)

    These files are inlined into the resulting Lua bundle as native Lua tables or strings.

  10. Use special global groups in rename_variables

    main

    The globals property in the rename_variables rule supports special tokens starting with $ that allow you to protect entire groups of identifiers at once.

    • $default: Protects all standard Lua language globals (e.g., print, math, table, pairs, _G).
    • $roblox: Protects all standard Roblox Lua globals (e.g., game, workspace, Instance, CFrame).

    Note: Lua language keywords like return and do are automatically excluded from renaming and cannot be configured.

    {
      rule: "rename_variables",
      globals: ["$default", "$roblox"]
    }