mirror of
https://github.com/luau-lang/luau.git
synced 2025-05-04 10:33:46 +01:00
Add initial changes to RFC
This commit is contained in:
parent
8a9a2ac08d
commit
9132d98a62
1 changed files with 62 additions and 41 deletions
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
We need a way to group together related code and provide easy ways to require them.
|
We need a way to group together related code into libraries and provide easy ways to require them.
|
||||||
|
|
||||||
## Motivation
|
## Motivation
|
||||||
|
|
||||||
|
@ -18,23 +18,13 @@ Our require syntax should:
|
||||||
|
|
||||||
- Allow a library written in Luau to be imported into the Roblox engine and 'just work'.
|
- Allow a library written in Luau to be imported into the Roblox engine and 'just work'.
|
||||||
- Support compile-time file resolution _where possible_ for type checking.
|
- Support compile-time file resolution _where possible_ for type checking.
|
||||||
|
- Be consistent across platforms and both inside and outside of Roblox.
|
||||||
#### Absolute
|
|
||||||
|
|
||||||
Modules can be required by their absolute path from the root of the filesystem.
|
|
||||||
|
|
||||||
Requiring a file called `MyModule.luau` in `C:/MyLibrary`:
|
|
||||||
```lua
|
|
||||||
local MyModule = require("C:/MyLibrary/MyModule")
|
|
||||||
```
|
|
||||||
|
|
||||||
Generally, absolute paths should not be used in regular code and should only appear in the alias map. Their purpose is to allow libraries to be stored in a global location (such as if a package is installed globally) without breaking if the libraries location is changed on disk.
|
|
||||||
|
|
||||||
#### Relative
|
#### Relative
|
||||||
|
|
||||||
Modules can be required relative to the requiring files location in the filesystem.
|
Modules can be required relative to the requiring file's location in the filesystem.
|
||||||
|
|
||||||
If we are trying to access a file called `MyModule.luau` in `C:/MyLibrary`:
|
If we are trying to require a module called `MyModule.luau` in `C:/MyLibrary`:
|
||||||
```lua
|
```lua
|
||||||
-- From C:/MyLibrary/SubDirectory/SubModule.luau
|
-- From C:/MyLibrary/SubDirectory/SubModule.luau
|
||||||
local MyModule = require("../MyModule")
|
local MyModule = require("../MyModule")
|
||||||
|
@ -43,58 +33,82 @@ local MyModule = require("../MyModule")
|
||||||
local MyModule = require("../MyLibrary/MyModule")
|
local MyModule = require("../MyLibrary/MyModule")
|
||||||
```
|
```
|
||||||
|
|
||||||
All relative paths will start with either `./` or `../` which denote the directory of the script or file, and parent directory respectively.
|
Relative paths are the default path type, meaning that if a given path does not begin with a reserved prefix such as `/` or `@`, then it is considered relative to the requiring file's location. Relative paths can begin with `../`, which denotes the parent directory of the requiring script, or the parent of the current working directory for the CLI.
|
||||||
|
|
||||||
|
#### Absolute
|
||||||
|
|
||||||
|
Modules can be required by their absolute path by prefixing the root of the filesystem (e.g. `C:/` or `/`).
|
||||||
|
|
||||||
|
Requiring a file called `MyModule.luau` in `<ROOT>/MyLibrary`:
|
||||||
|
```lua
|
||||||
|
-- Relative to root directory "/" (Linux/Unix)
|
||||||
|
local MyModule = require("/MyLibrary/MyModule")
|
||||||
|
|
||||||
|
-- Relative to root directory "C:/" (Windows)
|
||||||
|
local MyModule = require("C:/MyLibrary/MyModule")
|
||||||
|
|
||||||
|
-- This also works, "\" is internally replaced with "/"
|
||||||
|
local MyModule = require("C:\MyLibrary\MyModule")
|
||||||
|
```
|
||||||
|
|
||||||
|
Generally, absolute paths should not be used in regular code and should only appear in the alias map. Their purpose is to allow libraries to be stored in a global location (such as if packages are installed globally) without breaking if the libraries' locations are changed on disk.
|
||||||
|
|
||||||
#### Aliases
|
#### Aliases
|
||||||
|
|
||||||
Aliases can be used to bind an absolute or relative path to a convenient name that can be required directly. They are always prefixed with `$` to make it obvious they are not the same as a regular path.
|
Aliases can be used to bind an absolute or relative path to a convenient name that can be required directly. They are always prefixed with `@` to unambiguously distinguish them from directory names. Note that the alias map itself does not contain any `@` prefixes; these are required by default when requiring by alias in Luau scripts.
|
||||||
|
|
||||||
Each library has its own map which will be stored in a `luauconfig.json` file. Since libraries can be embedded inside of one another, any aliases which are not overriden will be inherited from the parent library.
|
Each library has its own alias map which will be stored in a `luauconfig.json` file. Since libraries can be embedded inside of one another, any aliases which are not overriden will be inherited from parent libraries.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
"Aliases": {
|
"aliases": {
|
||||||
"Roact": "C:/LuauModules/Roact-v1.4.2"
|
"Roact": "C:/LuauModules/Roact-v1.4.2"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Based on that map you would be able to require Roact directly:
|
Based on the alias map above, you would be able to require Roact directly:
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
local Roact = require("$Roact")
|
local Roact = require("@Roact")
|
||||||
```
|
```
|
||||||
|
|
||||||
Or even a sub-module:
|
Or even a sub-module:
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
local createElement = require("$Roact/createElement")
|
local createElement = require("@Roact/createElement")
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Versioning
|
##### Versioning
|
||||||
|
|
||||||
Aliases are simple bindings and aren't concerned with versioning. The intention is for a package manager to leverage aliases by automatically adding and updating the alias map to reflect a packages dependencies.
|
Aliases are simple bindings and aren't concerned with versioning. The intention is for a package manager to leverage aliases by automatically adding and updating the alias map to reflect a package's dependencies.
|
||||||
|
|
||||||
##### Root Alias
|
##### Root Alias
|
||||||
|
|
||||||
All libraries have a special alias for referring to their root. This alias cannot be overriden and is simply defined as `$`.
|
The blank alias "`@`" cannot be overriden and will remain reserved for now. It has been proposed in the past to use "`@`" to represent the root directory of a script's encapsulating library, but this will remain unimplemented for the time being. Users can use the alias map to explicitly define this behavior, if desired:
|
||||||
|
|
||||||
Requiring any file in the library can be done relative to the root:
|
```json
|
||||||
```lua
|
"aliases": {
|
||||||
local ModuleAtLibraryRoot = require("$/ModuleAtLibraryRoot")
|
"MML": "C:/LuauModules/MyMathLibrary"
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Limitations
|
##### Limitations
|
||||||
|
|
||||||
- Aliases cannot reference other aliases
|
- Aliases cannot reference other aliases.
|
||||||
- Aliases cannot contain certain characters such as `/` or `$` (full list TBD)
|
- Alias names cannot contain certain characters such as `/`, `@`, or `.` (full list TBD).
|
||||||
- All aliases must be prefixed with $ when used in a require statement to avoid ambiguity
|
- All aliases must be prefixed with `@` when used in a require statement to avoid ambiguity.
|
||||||
- Aliases can only occur at the beginning of a path
|
- Aliases can only occur at the beginning of a path.
|
||||||
- Multiple aliases are not supported
|
- Multiple aliases are not supported.
|
||||||
|
|
||||||
#### Directories
|
#### File Resolution
|
||||||
|
|
||||||
If the string resolves to a directory rather than a file then we will attempt to require a specific file in that directory with the following name:
|
If the string resolves to a directory rather than a file, then we will attempt to require a file in that directory with the following name (in this order):
|
||||||
1. `init.lua`
|
1. `init.luau`
|
||||||
2. `init.luau`
|
2. `init.lua`
|
||||||
|
|
||||||
|
If multiple files match the given path, we will attempt to require a file with the following extensions (in this order):
|
||||||
|
1. `.luau`
|
||||||
|
2. `.lua`
|
||||||
|
3. All other file extensions are invalid.
|
||||||
|
|
||||||
#### DataModel as VFS
|
#### DataModel as VFS
|
||||||
|
|
||||||
|
@ -102,20 +116,27 @@ In the Roblox engine, the DataModel will act as a virtual file system. At the ro
|
||||||
|
|
||||||
All paths used in the Roblox engine must refer to a location in the DataModel, they cannot be used to access files on disk.
|
All paths used in the Roblox engine must refer to a location in the DataModel, they cannot be used to access files on disk.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- TODO: EXAMPLE NEEDED
|
||||||
|
```
|
||||||
|
|
||||||
#### Platforms
|
#### Platforms
|
||||||
|
|
||||||
For compatability across platforms, we will automatically map `/` onto `\` on Windows.
|
For compatability across platforms, we will automatically map `/` onto `\`.
|
||||||
|
|
||||||
#### Backwards Compatibility
|
#### Backwards Compatibility
|
||||||
|
|
||||||
Luau libraries are not compatible with existing Lua libraries. This is because Lua favors the `.` based require syntax instead.
|
Luau libraries are already not compatible with existing Lua libraries. This is because Lua favors the `.` based require syntax instead and relies on the `LUA_PATH` environment variable to search for modules, whereas Luau currently implements a basic require-by-string syntax.
|
||||||
|
|
||||||
- Libraries are fully compatible with the Roblox engine as string-syntax is unsupported.
|
- Libraries are fully compatible with the Roblox engine, as require-by-string is currently unsupported.
|
||||||
- Compatibility with existing Luau is TBD.
|
- Luau currently implements relative paths in relation to the current working directory. We propose changing this behavior, and breaking backwards compatibility on this front.
|
||||||
|
- With the current implementation, requiring a library that itself contains relative-path require statements can become a mess if the Lua VM is not launched from the "correct" working directory.
|
||||||
|
- We propose taking a "script-first" approach: relative paths passed to require statements will be considered in relation to the requiring script's location, not the current working directory.
|
||||||
|
- If this causes issues, we can introduce a default alias for the current working directory (e.g. `@CWD`).
|
||||||
|
|
||||||
### luauconfig.json
|
### luauconfig.json
|
||||||
|
|
||||||
As part of this proposal we will introduce a new `luauconfig.json` file. Initially, this file will only include library configuration data but in the future could be expanded to contain more.
|
As part of this proposal, we will introduce a new `luauconfig.json` file. Initially, this file will only include library configuration data but in the future could be expanded to contain more.
|
||||||
|
|
||||||
The proposed structure for this file is:
|
The proposed structure for this file is:
|
||||||
|
|
||||||
|
@ -127,7 +148,7 @@ The proposed structure for this file is:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Where a field is missing from `luauconfig.json` it will be taken from the parent library (if one exists).
|
Missing fields in `luauconfig.json` are inherited (and can be overriden) from any existing parent/grandparent libraries.
|
||||||
|
|
||||||
### Defining a Library
|
### Defining a Library
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue