eslint-plugin-barrel-rules 1.0.4 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ko.md CHANGED
@@ -3,7 +3,7 @@
3
3
  # **Advanced Barrel Pattern Enforcement for JavaScript/TypeScript Projects**
4
4
 
5
5
  <div align="center">
6
- <img src="https://img.shields.io/badge/version-1.0.4-blue.svg" alt="Version"/>
6
+ <img src="https://img.shields.io/badge/version-1.1.1-blue.svg" alt="Version"/>
7
7
  <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License"/>
8
8
  <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs Welcome"/>
9
9
  </div>
@@ -23,7 +23,7 @@ NPM: [https://www.npmjs.com/package/eslint-plugin-barrel-rules](https://www.npmj
23
23
  **eslint-plugin-barrel-rules**는
24
24
  JavaScript/TypeScript 프로젝트에서 Barrel Pattern(배럴 패턴)을 강제하고, 모듈 경계와 캡슐화를 보장하는 고급 ESLint 플러그인입니다.
25
25
 
26
- 지정한 디렉토리(예: `src/domains/*`)의 내부 구현은
26
+ 지정한 디렉토리(예: `src/domains/*`, `src/domains/cart`)의 내부 구현은
27
27
  오직 해당 디렉토리의 **index(배럴) 파일**을 통해서만 접근할 수 있도록 강제합니다.
28
28
  내부 파일을 직접 import하는 것을 차단하여
29
29
  **모듈화, 추상화, 유지보수성, 확장성**을 극대화합니다.
@@ -32,10 +32,12 @@ JavaScript/TypeScript 프로젝트에서 Barrel Pattern(배럴 패턴)을 강제
32
32
 
33
33
  ## 지원 환경
34
34
 
35
- - ESLint 9 (Flat config, 현재 지원)
36
- > ⚠️ ESLint 8 (config) 지원도 추가될 예정입니다!
37
- - Node.js (ES2015+)
38
- - ES Modules (ESM) 지원
35
+ - ESLint 9
36
+ > Flat config(eslint.config.js), TypeScript 지원 "typescript-eslint" config 사용 필요
37
+ - ESLint 8
38
+ > Legacy config(.eslintrc.js), TypeScript 지원 시 "@typescript-eslint/parser"를 parser로 지정하고, "@typescript-eslint"를 plugin에 추가해야 함
39
+ - Node.js (ES2015 이상)
40
+ - ES 모듈, CommonJS 모듈 모두 지원
39
41
 
40
42
  ---
41
43
 
@@ -51,6 +53,22 @@ JavaScript/TypeScript 프로젝트에서 Barrel Pattern(배럴 패턴)을 강제
51
53
 
52
54
  ---
53
55
 
56
+ ## 규칙(Rules)
57
+
58
+ 1. **enforce-barrel-pattern**
59
+ 모듈 임포트 시 배럴 패턴(Barrel Pattern)을 강제합니다.
60
+ 지정한 배럴 파일을 통해서만 임포트가 가능하며, 내부 모듈에 직접 접근하는 것을 방지합니다.
61
+
62
+ - **옵션:**
63
+ - `paths`: 배럴 패턴으로 보호할 디렉토리 경로(`baseDir` 기준 상대경로)
64
+ - `baseDir` (선택): `paths` 해석 기준이 되는 디렉토리. 기본값은 ESLint 실행 위치입니다.
65
+
66
+ 2. **no-wildcard**
67
+ `import * as foo from "module"`, `export * from "./module"`과 같은 와일드카드(네임스페이스) import/export를 금지합니다.
68
+ 트리쉐이킹 및 코드 명확성을 위해 반드시 개별(named) import/export만 허용합니다.
69
+
70
+ ---
71
+
54
72
  ## 설치
55
73
 
56
74
  ```bash
@@ -63,39 +81,81 @@ pnpm add -D eslint-plugin-barrel-rules
63
81
 
64
82
  ---
65
83
 
66
- ## 사용법
84
+ ## Eslint8 사용법
85
+
86
+ ```js
87
+ file(.eslintrc.js)
88
+
89
+ module.exports = {
90
+ ...(any other options)
91
+ // 타입스크립트를 사용할 경우 "@typescript-eslint/parser", "@typescript-eslint"를 설치하고 설정해 주세요.
92
+ parser: "@typescript-eslint/parser",
93
+ plugins: ["@typescript-eslint", "barrel-rules"],
94
+ rules: {
95
+ "barrel-rules/enforce-barrel-pattern": [
96
+ "error",
97
+ {
98
+ // 배럴 파일로 보호할 디렉토리의 경로입니다. baseDir을 기준으로 상대 경로로 설정합니다.
99
+ paths: ["src/typescript/barrel/*", "src/javascript/barrel/*"],
100
+ // (옵션) 설정하지 않으면 기본값은 ESLint를 실행한 위치(작업 디렉토리)입니다.
101
+ // 예: `npx eslint .`처럼 실행하면, 실행 시점의 현재 디렉토리가 기본값이 됩니다.
102
+ baseDir: __dirname,
103
+ },
104
+ ],
105
+ // import * 또는 export * 금지
106
+ "barrel-rules/no-wildcard": ["error"],
107
+ },
108
+ };
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Eslint9 사용법
67
114
 
68
115
  ```js
116
+ file(eslintrc.config.js);
117
+
118
+ import js from "@eslint/js";
119
+ import tseslint from "typescript-eslint";
120
+ import { globalIgnores } from "eslint/config";
121
+ import barrelRules from "eslint-plugin-barrel-rules";
122
+ // ESM에서 __dirname을 사용하기 위한 코드
69
123
  import { fileURLToPath } from "url";
70
124
  import path from "path";
71
- import { enforceBarrelPattern } from "eslint-plugin-barrel-rules";
72
-
73
- //ESM은 __dirname을 지원하지 않기에 직접 구현합니다.
125
+ // 커스텀 __dirname 생성
74
126
  const __filename = fileURLToPath(import.meta.url);
75
127
  const __dirname = path.dirname(__filename);
76
-
77
- export default [
128
+ // 타입스크립트 사용 시 필요
129
+ export default tseslint.config([
130
+ globalIgnores(["dist"]),
78
131
  {
132
+ // (다른 옵션들 추가 가능)
133
+ files: ["**/*.{ts,tsx}"],
134
+ extends: [js.configs.recommended, tseslint.configs.recommended],
135
+ languageOptions: {
136
+ ecmaVersion: 2020,
137
+ },
138
+ // barrel-rules 플러그인만 추가하면 됩니다.
79
139
  plugins: {
80
- "barrel-rules": {
81
- rules: {
82
- "enforce-barrel-pattern": enforceBarrelPattern,
83
- },
84
- },
140
+ "barrel-rules": barrelRules,
85
141
  },
142
+ // barrel-rules에 대한 설정만 추가하면 됩니다.
86
143
  rules: {
87
144
  "barrel-rules/enforce-barrel-pattern": [
88
145
  "error",
89
146
  {
90
- //Barrel Pattern을 강제할 디렉토리를 정의합니다(baseDir 기준으로 상대경로)
91
- paths: ["src/domains/*"],
92
- //paths들의 root경로를 지정합니다.
147
+ // 배럴 파일로 보호할 디렉토리의 경로입니다. baseDir 기준으로 상대 경로로 설정합니다.
148
+ paths: ["src/typescript/barrel/*"],
149
+ // (옵션) 설정하지 않으면 기본값은 ESLint를 실행한 위치(작업 디렉토리)입니다.
150
+ // 예: `npx eslint .`처럼 실행하면, 실행 시점의 현재 디렉토리가 기본값이 됩니다.
93
151
  baseDir: __dirname,
94
152
  },
95
153
  ],
154
+ // import * 또는 export * 금지
155
+ "barrel-rules/no-wildcard": ["error"],
96
156
  },
97
157
  },
98
- ];
158
+ ]);
99
159
  ```
100
160
 
101
161
  ---
@@ -114,16 +174,17 @@ import { Test } from "../domains/foo";
114
174
 
115
175
  ## 앞으로의 계획
116
176
 
117
- - 더 다양한 모듈 경계/추상화 관련 룰 추가 예정
118
-
119
- - **Alias/tsconfig 지원**
120
- TypeScript `paths`, Vite `resolve.alias` 등 다양한 경로 매핑 완벽 지원 예정
121
-
122
- - **Commonjs 지원**
177
+ - 더 다양한 모듈 경계/추상화 관련 룰 추가 예정 (~Ing)
178
+ - Alias/tsconfig 지원: TypeScript의 paths, Vite의 resolve.alias, 기타 커스텀 경로 매핑을 완벽하게 지원 (~Ing)
179
+ - **CJS 지원** (OK)
180
+ - **ESLint 8 지원** (OK)
181
+ - **번들 플러그인(플러그인 내 모든 기능 통합)** (OK)
182
+ - **잘못된 경로 설정 검증 기능** (OK)
183
+ - **와일드카드 import/export 제한 규칙** (OK)
123
184
 
124
185
  ---
125
186
 
126
187
  ## 문의
127
188
 
128
189
  질문, 제안, 버그 리포트, 기여 모두 환영합니다!
129
- [[📬 send mail]](mailto:lhsung98@naver.com)
190
+ [[📬 send mail lhsung98@naver.com]](mailto:lhsung98@naver.com)
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  # **Advanced Barrel Pattern Enforcement for JavaScript/TypeScript Projects**
4
4
 
5
5
  <div align="center">
6
- <img src="https://img.shields.io/badge/version-1.0.4-blue.svg" alt="Version"/>
6
+ <img src="https://img.shields.io/badge/version-1.1.1-blue.svg" alt="Version"/>
7
7
  <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License"/>
8
8
  <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs Welcome"/>
9
9
  </div>
@@ -26,7 +26,7 @@ NPM: [https://www.npmjs.com/package/eslint-plugin-barrel-rules](https://www.npmj
26
26
  that enforces the Barrel Pattern in JavaScript/TypeScript projects,
27
27
  ensuring strict module boundaries and encapsulation.
28
28
 
29
- You can specify directories (e.g., `src/domains/*`) where
29
+ You can specify directories (e.g., `src/domains/*`, `src/domains/cart`) where
30
30
  internal implementation details must only be accessed via the directory’s **index (barrel) file**.
31
31
  Direct imports from internal files are blocked, maximizing
32
32
  **modularity, abstraction, maintainability, and scalability**.
@@ -35,10 +35,12 @@ Direct imports from internal files are blocked, maximizing
35
35
 
36
36
  ## Supports
37
37
 
38
- - ESLint 9 (Flat config, currently supported)
39
- > ⚠️ ESLint 8 (legacy config) support is planned for a future release!
38
+ - ESLint 9
39
+ > Flat config(eslint.config.js), for TypeScript support, use the "typescript-eslint" config
40
+ - ESLint 8
41
+ > Legacy config(.eslintrc.js), for TypeScript support, set "@typescript-eslint/parser" as the parser and add "@typescript-eslint" as a plugin
40
42
  - Node.js (ES2015+)
41
- - Supports ES Modules (ESM)
43
+ - Supports both ES Modules and CommonJS
42
44
 
43
45
  ---
44
46
 
@@ -54,6 +56,22 @@ Direct imports from internal files are blocked, maximizing
54
56
 
55
57
  ---
56
58
 
59
+ ## Rules
60
+
61
+ 1. **enforce-barrel-pattern**
62
+ Enforces the barrel pattern for module imports.
63
+ Only allows imports from designated barrel files and prevents direct access to internal modules.
64
+
65
+ - **Options:**
66
+ - `paths`: The directories to be protected by the barrel pattern (relative to `baseDir`).
67
+ - `baseDir` (optional): The base directory for resolving `paths`. Defaults to the ESLint execution directory.
68
+
69
+ 2. **no-wildcard**
70
+ Disallows wildcard (namespace) imports such as `import * as foo from "module"`, `export * from "./module"`
71
+ Forces you to use named imports for better tree-shaking and code clarity.
72
+
73
+ ---
74
+
57
75
  ## Install
58
76
 
59
77
  ```bash
@@ -66,39 +84,81 @@ pnpm add -D eslint-plugin-barrel-rules
66
84
 
67
85
  ---
68
86
 
69
- ## Usage
87
+ ## Eslint8 Usage
88
+
89
+ ```js
90
+ file(.eslintrc.js)
91
+
92
+ module.exports = {
93
+ ...(any other options)
94
+ //if you use typescript, needs "@typescript-eslint/parser", "@typescript-eslint" install and setup plz..
95
+ parser: "@typescript-eslint/parser",
96
+ plugins: ["@typescript-eslint", "barrel-rules"],
97
+ rules: {
98
+ "barrel-rules/enforce-barrel-pattern": [
99
+ "error",
100
+ {
101
+ // The path to the directory that should be protected by using a barrel file. This path is relative to baseDir.
102
+ paths: ["src/typescript/barrel/*", "src/javascript/barrel/*"],
103
+ // Optional config. The default value is the directory where ESLint is executed.
104
+ // For example, if you run `npx eslint .`, the default will be the current working directory at the time of execution.
105
+ baseDir: __dirname,
106
+ },
107
+ ],
108
+ // Disallow wildcard (namespace) import/export.
109
+ "barrel-rules/no-wildcard": ["error"],
110
+ },
111
+ };
112
+ ```
113
+
114
+ ---
115
+
116
+ ## Eslint9 Usage
70
117
 
71
118
  ```js
119
+ file(eslintrc.config.js);
120
+
121
+ import js from "@eslint/js";
122
+ import tseslint from "typescript-eslint";
123
+ import { globalIgnores } from "eslint/config";
124
+ import barrelRules from "eslint-plugin-barrel-rules";
125
+ //for __dirname in ESM
72
126
  import { fileURLToPath } from "url";
73
127
  import path from "path";
74
- import { enforceBarrelPattern } from "eslint-plugin-barrel-rules";
75
-
76
- //ESM not support __dirname(custom __dirname)
128
+ //custom __dirname
77
129
  const __filename = fileURLToPath(import.meta.url);
78
130
  const __dirname = path.dirname(__filename);
79
-
80
- export default [
131
+ //typescript-config (if you use typescript, needs it)
132
+ export default tseslint.config([
133
+ globalIgnores(["dist"]),
81
134
  {
135
+ ...(any other options)
136
+ files: ["**/*.{ts,tsx}"],
137
+ extends: [js.configs.recommended, tseslint.configs.recommended],
138
+ languageOptions: {
139
+ ecmaVersion: 2020,
140
+ },
141
+ //just set barrle-rules plugin
82
142
  plugins: {
83
- "barrel-rules": {
84
- rules: {
85
- "enforce-barrel-pattern": enforceBarrelPattern,
86
- },
87
- },
143
+ "barrel-rules": barrelRules,
88
144
  },
145
+ //just set your setting for barrel-rules
89
146
  rules: {
90
147
  "barrel-rules/enforce-barrel-pattern": [
91
148
  "error",
92
149
  {
93
- //Enforced directories
94
- paths: ["src/domains/*"],
95
- //BaseDir(root path, mutable)
150
+ // The path to the directory that should be protected by using a barrel file. This path is relative to baseDir.
151
+ paths: ["src/typescript/barrel/*"],
152
+ // Optional config. The default value is the directory where ESLint is executed.
153
+ // For example, if you run `npx eslint .`, the default will be the current working directory at the time of execution.
96
154
  baseDir: __dirname,
97
155
  },
98
156
  ],
157
+ // Disallow wildcard (namespace) import/export.
158
+ "barrel-rules/no-wildcard": ["error"],
99
159
  },
100
160
  },
101
- ];
161
+ ]);
102
162
  ```
103
163
 
104
164
  ---
@@ -117,16 +177,21 @@ import { Test } from "../domains/foo";
117
177
 
118
178
  ## Future Work
119
179
 
120
- - More rules for module boundaries and abstraction
180
+ - More rules for module boundaries and abstraction (~Ing)
121
181
 
122
182
  - **Alias/tsconfig Support**
123
- Fully supports TypeScript `paths`, Vite `resolve.alias`, and other custom path mappings
183
+ Fully supports TypeScript `paths`, Vite `resolve.alias`, and other custom path mappings (~Ing)
124
184
 
125
- - **CJS Support**
185
+ - **CJS Support** (OK)
186
+ - **Eslint8 Support** (OK)
187
+ - **Bundle Plugin(capsure any features in plugin)**
188
+ (OK)
189
+ - **Wrong Path Setup Validator** (OK)
190
+ - **Wildcard Import/Export Protection Rule** (OK)
126
191
 
127
192
  ---
128
193
 
129
194
  ## Contact
130
195
 
131
196
  Questions, suggestions, bug reports, and contributions are welcome!
132
- [[📬 send mail]](mailto:lhsung98@naver.com)
197
+ [[📬 send mail lhsung98@naver.com]](mailto:lhsung98@naver.com)
package/dist/index.cjs CHANGED
@@ -30,7 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
- enforceBarrelPattern: () => enforceBarrelPattern
33
+ default: () => index_default
34
34
  });
35
35
  module.exports = __toCommonJS(index_exports);
36
36
 
@@ -52,6 +52,7 @@ var enforceBarrelPattern = {
52
52
  paths: { type: "array", items: { type: "string" } },
53
53
  baseDir: { type: "string" }
54
54
  },
55
+ required: ["paths"],
55
56
  additionalProperties: false
56
57
  }
57
58
  ],
@@ -131,7 +132,49 @@ var enforceBarrelPattern = {
131
132
  };
132
133
  }
133
134
  };
134
- // Annotate the CommonJS export names for ESM import in node:
135
- 0 && (module.exports = {
136
- enforceBarrelPattern
137
- });
135
+
136
+ // src/rules/no-wildcard.ts
137
+ var import_utils2 = require("@typescript-eslint/utils");
138
+ var noWildcard = {
139
+ meta: {
140
+ type: "problem",
141
+ docs: {
142
+ description: "Wildcard (namespace) import is not allowed."
143
+ },
144
+ schema: [],
145
+ messages: {
146
+ NoWildcardImport: "Wildcard import (`import * as ... from ...`) is not allowed. Please use named imports instead.",
147
+ NoExportAll: "Export all (`export * from ...`) is not allowed. Please use named exports instead."
148
+ }
149
+ },
150
+ defaultOptions: [],
151
+ create(context) {
152
+ return {
153
+ ImportDeclaration(node) {
154
+ const hasNamespaceImport = node.specifiers.some(
155
+ (specifier) => specifier.type === "ImportNamespaceSpecifier"
156
+ );
157
+ if (hasNamespaceImport) {
158
+ context.report({
159
+ node,
160
+ messageId: "NoWildcardImport"
161
+ });
162
+ }
163
+ },
164
+ ExportAllDeclaration(node) {
165
+ context.report({
166
+ node,
167
+ messageId: "NoExportAll"
168
+ });
169
+ }
170
+ };
171
+ }
172
+ };
173
+
174
+ // src/index.ts
175
+ var rules = {
176
+ "enforce-barrel-pattern": enforceBarrelPattern,
177
+ "no-wildcard": noWildcard
178
+ };
179
+ var index_default = { rules };
180
+ module.exports = { rules };
package/dist/index.d.cts CHANGED
@@ -1,10 +1,13 @@
1
- import { RuleModule } from '@typescript-eslint/utils/ts-eslint';
1
+ import * as _typescript_eslint_utils_ts_eslint from '@typescript-eslint/utils/ts-eslint';
2
2
 
3
- type Option = {
4
- paths: string[];
5
- baseDir: string;
3
+ declare const _default: {
4
+ rules: {
5
+ "enforce-barrel-pattern": _typescript_eslint_utils_ts_eslint.RuleModule<"DirectImportDisallowed", {
6
+ paths: string[];
7
+ baseDir: string;
8
+ }[], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
9
+ "no-wildcard": _typescript_eslint_utils_ts_eslint.RuleModule<"NoWildcardImport" | "NoExportAll", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
10
+ };
6
11
  };
7
- type MessageIds = "DirectImportDisallowed";
8
- declare const enforceBarrelPattern: RuleModule<MessageIds, Option[]>;
9
12
 
10
- export { enforceBarrelPattern };
13
+ export { _default as default };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,13 @@
1
- import { RuleModule } from '@typescript-eslint/utils/ts-eslint';
1
+ import * as _typescript_eslint_utils_ts_eslint from '@typescript-eslint/utils/ts-eslint';
2
2
 
3
- type Option = {
4
- paths: string[];
5
- baseDir: string;
3
+ declare const _default: {
4
+ rules: {
5
+ "enforce-barrel-pattern": _typescript_eslint_utils_ts_eslint.RuleModule<"DirectImportDisallowed", {
6
+ paths: string[];
7
+ baseDir: string;
8
+ }[], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
9
+ "no-wildcard": _typescript_eslint_utils_ts_eslint.RuleModule<"NoWildcardImport" | "NoExportAll", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
10
+ };
6
11
  };
7
- type MessageIds = "DirectImportDisallowed";
8
- declare const enforceBarrelPattern: RuleModule<MessageIds, Option[]>;
9
12
 
10
- export { enforceBarrelPattern };
13
+ export { _default as default };
package/dist/index.js CHANGED
@@ -16,6 +16,7 @@ var enforceBarrelPattern = {
16
16
  paths: { type: "array", items: { type: "string" } },
17
17
  baseDir: { type: "string" }
18
18
  },
19
+ required: ["paths"],
19
20
  additionalProperties: false
20
21
  }
21
22
  ],
@@ -95,6 +96,52 @@ var enforceBarrelPattern = {
95
96
  };
96
97
  }
97
98
  };
99
+
100
+ // src/rules/no-wildcard.ts
101
+ import "@typescript-eslint/utils";
102
+ var noWildcard = {
103
+ meta: {
104
+ type: "problem",
105
+ docs: {
106
+ description: "Wildcard (namespace) import is not allowed."
107
+ },
108
+ schema: [],
109
+ messages: {
110
+ NoWildcardImport: "Wildcard import (`import * as ... from ...`) is not allowed. Please use named imports instead.",
111
+ NoExportAll: "Export all (`export * from ...`) is not allowed. Please use named exports instead."
112
+ }
113
+ },
114
+ defaultOptions: [],
115
+ create(context) {
116
+ return {
117
+ ImportDeclaration(node) {
118
+ const hasNamespaceImport = node.specifiers.some(
119
+ (specifier) => specifier.type === "ImportNamespaceSpecifier"
120
+ );
121
+ if (hasNamespaceImport) {
122
+ context.report({
123
+ node,
124
+ messageId: "NoWildcardImport"
125
+ });
126
+ }
127
+ },
128
+ ExportAllDeclaration(node) {
129
+ context.report({
130
+ node,
131
+ messageId: "NoExportAll"
132
+ });
133
+ }
134
+ };
135
+ }
136
+ };
137
+
138
+ // src/index.ts
139
+ var rules = {
140
+ "enforce-barrel-pattern": enforceBarrelPattern,
141
+ "no-wildcard": noWildcard
142
+ };
143
+ var index_default = { rules };
144
+ module.exports = { rules };
98
145
  export {
99
- enforceBarrelPattern
146
+ index_default as default
100
147
  };
package/package.json CHANGED
@@ -23,7 +23,7 @@
23
23
  "encapsulation directory",
24
24
  "enforce barrel pattern"
25
25
  ],
26
- "version": "1.0.4",
26
+ "version": "1.1.1",
27
27
  "type": "module",
28
28
  "main": "dist/index.cjs",
29
29
  "module": "dist/index.js",