-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Suggestion: making exports visible only to the same directory with JSDoc @package tag #41425
Comments
I'd recommend configurating these package entries in tsconfig. |
Just FYI, I created a userland solution on this as a combination of ESLint plugin and TypeScript Language Service Plugin. https://github.com/uhyo/eslint-plugin-import-access However, the implementation of Language Service Plugin is kind of barbarous, so support from TypeScript is still wanted. |
I have another suggestion to this: use modifier before For example, if you want to export some function only inside of the directory (package), use For file export function sort(/* some args here */) { }
inpackage export function quickSortPartition(/* */) { } For file import { quickSortPartition } from "./sort.ts"
function findNthSmallest(/* */)
{
// Can use partition function here
quickSortPartition()
} But for other file // Cannot import here
import { quickSortPartition } from "./sort/sort.ts" |
I've been thinking about this quite a bit recently. I like the idea of having a prefix for
All of this led me to create a plugin (inspired by @uhyo's plugin) that adds support for I wanted to create a TS decorator, that would make something like this possible: @scope("../..")
export default ""; but, unfortunately, TS doesn't support export decorators. If TS allows it then at least we would be able to create ESLint/TS plugins that would read the decorators instead of comments (which look quite a bit uglier) |
Suggestion : can use dir named "internal" , this dir can be import same level dir file. same as golang internal dir rule ! |
@A-Shleifman I think TS does support decorators, doesn't it? https://www.typescriptlang.org/docs/handbook/decorators.html Unless the terminology is wrong and you mean |
@decoded4620, I was talking about |
I was thinking about idea similar to one of @HQ6968. Here is list of my ideas/opinions. I've left questions that probably can be answered by somebody with more experience The idea
So code in module
Scope is given to the entire module, not to individual identifiers
In my opinion, giving scope to individual functions/variables is harder to reason about: to see the entire public API of a component, or entire private API within the component, you would have to browse each individual file, since each file might contain a mix of both Is there ever a good case to mix public and private things in one module? Can we just split the code in multiple modules for such cases? Dependencies between foldersIt might be useful to declare dependencies between folders, instead of allowing every folder to import any other folder
I like how TS Project references do that: each folder has tsconfig.json at its top, with NPM dependencies are shared for all foldersI think it's convenient that all such folder would be able to import any NPM packages from the root "package.json". If you want different components of code not to share each other's NPM dependencies, you can use a monorepo (e.g. Rush.js) Nested foldersWhat if a folder contains another folder? Can the parent folder access Child accessing things of parentI like idea of #41316, which introduces Parent accessing things of child
No barrel files
IMHO, barrel files are tiresome to maintain. It might be a good idea to have all public API declared in one file, but is there practical problem of browsing all folders except |
Yes! This might not be the best example, but let's say we have a file defining a React Context for an encapsulated Component: const context = createContext({});
export const ContextProvider = context.Provider;
// 👆 should only be accessible by the internal component files
export const useComponentContext = () => useContext(context);
// 👆 should be accessible by any component anywhere wrapped in the Component providing the context
Generally, that's true. That's why we're having this conversation, but there are exceptions. The most basic would be an index file re-exporting an export from a child folder. utils
├── schema-utils/
│ ├── parsers.ts
│ └── validators.ts
└── index.ts In this case, it should be possible for the |
I would love a solution to this problem to be integrated into TS, but while we wait, here's a v2 of eslint-plugin-export-scope |
Personally, I would use this kind of export primarly for testing purpose: Exporting a "private" function that could be seen only by the associated test file. |
This would be a great addition to TS. For me, it would allow me to better break it down my file structure ensuring that modules are self-contained. For e.g., in my React projects, I would have my folder structure like:
If we had something like the This would also allow exporting two modules with same name in different scopes. |
Search Terms
JSDoc package directory package-private
Suggestion
If an export is annotated with
@package
, that export is visible only to files in the same directory.I can think of two levels of
@package
support: a soft one would remove these exports from auto completion if not visible. A hard one would also emit a compile error.See also: Use JSDoc: @package
Use Cases
We organize source code using directory structure. We often make exports that are meant to be referenced only by sibling modules. However, JavaScript/TypeScript has no idea of scoping based on file system, so we are free to import such "local" exports everywhere. TypeScript could help us do file system-based scoping.
Examples
Checklist
My suggestion meets these guidelines:
The text was updated successfully, but these errors were encountered: