-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Absolute Require Syntax #80
Draft
bradsharp
wants to merge
2
commits into
master
Choose a base branch
from
rfc-absolute-require
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
# Absolute Requires | ||
|
||
## Summary | ||
|
||
This proposal describes a new absolute syntax to support require-by-string in a format that can work for filesystems and embedded applications such as the Roblox platform, replacing the existing syntax we have today. | ||
|
||
## Motivation | ||
|
||
It should be possible for all users of Luau to write code that is capable of running, without modification, on many different platforms. Unfortunately, we identified an issue with the current syntax that would make it difficult for users of certain tools to adopt. As paths are relative to the file calling require, any tools that adjust the file hierarchy would also need to update require paths to match. While we know there may not be a perfect solution that works for all use-cases, we think the current syntax should be amended to support these cases or at least not require them to translate require paths in files. | ||
|
||
## Design | ||
|
||
### Overview | ||
|
||
When calling require without a prefix, the path will be resolved as an absolute path where the root directory is defined as follows: | ||
|
||
* If the file does not belong to a library, then the entry point's directory | ||
* If the file belongs to a library, then the directory containing the library | ||
|
||
For example, here's a simple file system: | ||
|
||
``` | ||
├── folder | ||
│ └── file.luau | ||
├── module.luau | ||
└── init.luau | ||
``` | ||
|
||
And here's how you would navigate between files using the proposed syntax when init.luau is the entry point: | ||
|
||
| **From** | **To** | **Path** | | ||
|------------------|------------------|-------------| | ||
| init.luau | module.luau | module | | ||
| init.luau | folder/file.luau | folder/file | | ||
| module.luau | folder/file.luau | folder/file | | ||
| folder/file.luau | module.luau | module | | ||
|
||
With this syntax, paths are the same no matter where a file is in a project, meaning they can be restructured by the user or with tools, without creating any issues. | ||
|
||
### Libraries | ||
|
||
While this RFC does not call out the exact definition of a library, there will be a way to designate a directory as such. Here is an example of a filesystem including one: | ||
|
||
``` | ||
├── library (defined in some way) | ||
│ ├── folder | ||
│ │ └── file.luau | ||
│ └── module.luau | ||
└── init.luau | ||
``` | ||
|
||
And here's how you would navigate between these files: | ||
|
||
| **From** | **To** | **Path** | | ||
|--------------------------|--------------------------|----------------| | ||
| init.luau | library/module.luau | library/module | | ||
| library/module.luau | library/folder/file.luau | folder/file | | ||
| library/folder/file.luau | library/module.luau | module | | ||
|
||
Again, paths are still reasonably simple, but this time files in the library requires are relative to the root directory of the library. | ||
|
||
### Init | ||
|
||
As they can today, files called init.luau inside of a directory can be required by requiring the path to the directory they are in. | ||
|
||
``` | ||
├── folder | ||
│ └── init.luau | ||
├── module.luau | ||
└── init.luau | ||
``` | ||
|
||
Given this file structure, it's possible to require folder/init.luau with require("folder"). | ||
However, one subtle change is that you won't be allowed to require init.luau directly. We're doing this for cases where files can also act as directories in certain environments. | ||
|
||
### Aliases | ||
|
||
There are no changes to aliases in this proposal. | ||
|
||
### Comparison with Relative Paths | ||
|
||
We will continue to support relative paths, however recommend updating to absolute paths to guarantee portability between different environments. | ||
|
||
``` | ||
├── folder | ||
│ └── init.luau | ||
├── library (defined in some way) | ||
│ ├── folder | ||
│ │ └── file.luau | ||
│ └── init.luau | ||
├── module.luau | ||
└── init.luau | ||
``` | ||
|
||
| **From** | **To** | **Relative Path** | **Absolute Path** | | ||
|-------------------|--------------------------|-------------------------------------------------|----------------------| | ||
| init.luau | module.luau | ./module | module | | ||
| init.luau | folder/init.luau | ./folder | folder | | ||
| init.luau | library/init.luau | ./library | library | | ||
| init.luau | library/folder/file.luau | ./library/folder/file | library/folder/file | | ||
| module.luau | folder/init.luau | ./folder | folder | | ||
| module.luau | library/init.luau | ./library | library | | ||
| folder/init.luau | module.luau | ./../module ../module | module | | ||
| folder/init.luau | library/folder/file.luau | ./../library/folder/file ../library/folder/file | library/folder/file | | ||
| library/init.luau | library/folder/file.luau | ./folder/file | folder/file | | ||
|
||
As paths are relative to the root directory with the absolute syntax the only ones that change are those in files under a subdirectory. All other paths remain the same as the current syntax. | ||
|
||
## Drawbacks | ||
|
||
As relative paths are still available, we haven't completely solved the problem. Users could still opt to use them, leading to the issue mentioned above. However, there may be options (such as tooling) to guide users away from relative paths over time to help address this. | ||
|
||
## Alternatives | ||
|
||
We have already considered (and even approved) some alternatives to this approach, however there are drawbacks with each of them that ultimately led us in this direction. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can I see this section reworked? As it is, it requires you to read all the RFCs and filtering out irrelevant information wrt what this RFC is trying to solve. It's also not really "alternatives" either. |
||
|
||
* [Amended Require Syntax and Resolution Semantics](https://github.com/luau-lang/rfcs/pull/56) | ||
* [Require by String (split into two RFCs)](https://github.com/luau-lang/luau/pull/969) | ||
* [Require by String with Aliases](https://github.com/luau-lang/rfcs/pull/7) | ||
* [New Require by String Semantics](https://github.com/luau-lang/rfcs/pull/6) | ||
* [Amended Require Resolution Init](https://github.com/luau-lang/rfcs/pull/76) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which tools?
What tools would adjust the file hierarchy other than a human moving files around?
This can be solved with code refactoring tools. In TypeScript, if you have some statement
You can press F2 on
"./foo"
and it will rename the file, and also applies renaming over other imports that resolves to the same file, ditto any kind of action of moving files around as long as the action of moving files around happens through LSP.I'm not a fan of any RFCs that wants to cop out from motivating the need for better tooling, similar to postfix
!
to removenil
, and this RFC feels like it has the same problem.