Disallows importing scoped exports outside their scope
Don't leak LOCAL utils, states, contexts, components into the global scope.
scope | importable from | |
---|---|---|
. | current directory and children | default for all exports |
.. | parent directory and children | default for index files |
../.. | two directories above and children | |
src/consumer | within specified directory and children | |
src/consumer.ts | within specified file | |
* | anywhere |
/** @scopeDefault ../.. */
/** โ Applies to all exports in the file unless overriden with a local `@scope` */
/** @scope * */
export const helper1 = ""; // ๐ Available everywhere
export const helper2 = ""; // ๐ inherits scope `../..` from `@scopeDefault`
/** @scope src/components */
export default "";
.scope.ts
filesโโโ src
โโโ `common`
โโโ utils.ts
โโโ context.ts
โโโ `.scope.ts`
โ
โ
โญโโโโโโโโโโโโโโโโโโโโโฎ
โ export default '*' โ
โฐโโโโโโโโโโโโโโโโโโโโโฏ
// โฌ this will make all exports within `common`
// importable from anywhere unless a
// specific export is overriden on a lower level
// schema.ts
/**
* @scope ..
* @scopeException src/schemaConsumer ๐ whole folder has access
* @scopeException src/schemaConsumer/index.ts ๐ whole file has access
*/
export default "";
.scope.ts
filesโโโ src
โโโ `generated`
โโโ schema.ts
โโโ `.scope.ts`
โ
โ
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ export default '.'; โ
โ โ
โ export const exceptions = [ โ
โ 'src/schemaConsumer', โ
โ 'src/scripts/schemaParser.ts', โ
โ ] โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
// โฌ by default exports are only importable
// within `generated` folder, but
// folders/files in `exceptions` are exempt.
Install ESLint and the export-scope
package. This package includes both an ESLint
plugin and a TS Language Server
plugin.
npm i -D eslint typescript-eslint eslint-plugin-export-scope
// package.json
{
"type": "module"
}
// eslint.config.js
// @ts-check
import tseslint from "typescript-eslint";
import exportScope from "eslint-plugin-export-scope";
export default tseslint.config(
// other configs,
exportScope.configs.flatConfigRecommended,
);
// eslint.config.js
// @ts-check
import tseslint from "typescript-eslint";
import exportScope from "eslint-plugin-export-scope";
export default tseslint.config(
// other configs,
{
files: ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "**/*.mts", "**/*.mjs", "**/*.cjs"],
plugins: { "export-scope": exportScope.plugin },
rules: { "export-scope/no-imports-outside-export-scope": "error" },
languageOptions: { parser: tseslint.parser, parserOptions: { project: true } },
},
);
npm i -D eslint @typescript-eslint/parser eslint-plugin-export-scope
# โฌ v6 or above
// .eslintrc.js
module.exports = {
// ...
extends: ["plugin:eslint-plugin-export-scope/recommended"],
parser: "@typescript-eslint/parser",
parserOptions: { project: true, tsconfigRootDir: __dirname },
ignorePatterns: ["!.scope.ts"],
};
// .eslintrc.js
module.exports = {
// ...
parser: "@typescript-eslint/parser",
parserOptions: { project: true, tsconfigRootDir: __dirname },
plugins: ["export-scope"],
rules: { "export-scope/no-imports-outside-export-scope": "error" },
ignorePatterns: ["!.scope.ts"],
};
// tsconfig.json
"compilerOptions": {
"plugins": [{ "name": "eslint-plugin-export-scope" }],
},
"include": ["**/*", "**/.scope.ts"]
// "../../**/.scope.ts" for monorepos
Tell VSCode to Use Workspace Version
of TypeScript. Otherwise TS plugin won't work.
tsconfig.json
file is still required for the plugin to work.scope.ts
in both configs with .scope.js
compilerOptions.allowJs
to true
in tsconfig.json
//
comments with jsDocs /** */
@scope default
with @scopeDefault
@..
file/folder prefixes with .scope.ts
files..eslintrc.js
and tsconfig.json
configs are updated@
above exports for automatic jsDoc generation..scope.ts
files..scope.ts
file (next to package.json) sets the default for the whole project. Having export default '*'
there will make all exports global by default if you prefer a less strict approach.โ ๏ธ To re-lint an import in VSCode after updating a scope
declaration either touch
this import or restart the ESLint Server (ESLint limitation).