UNPKG

12.8 kBMarkdownView Raw
1# :file_folder: tslint-folders
2
3Use tslint to check for invalid imports between packages and folders in your TypeScript project.
4
5Automatic validation and documentation of package architecture (via `tslint-folders-diagrams`).
6
7## status - stable
8
9tslint-folders is stable and in use every day in CI builds and on dev boxes (Linux, Mac, Windows) for at least one major product.
10
11[![Build Status](https://travis-ci.com/mrseanryan/tslint-folders.svg?branch=master)](https://travis-ci.com/mrseanryan/tslint-folders)
12[![Coveralls](https://img.shields.io/coveralls/mrseanryan/tslint-folders.svg)](https://coveralls.io/github/mrseanryan/tslint-folders)
13[![Size](https://packagephobia.now.sh/badge?p=tslint-folders)](https://packagephobia.now.sh/result?p=tslint-folders)
14
15[![Dependencies](https://david-dm.org/mrseanryan/tslint-folders.svg)](https://david-dm.org/mrseanryan/tslint-folders)
16
17[![npm Package](https://img.shields.io/npm/v/tslint-folders.svg?style=flat-square)](https://www.npmjs.org/package/tslint-folders)
18[![NPM Downloads](https://img.shields.io/npm/dm/tslint-folders.svg)](https://npmjs.org/package/tslint-folders)
19
20[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
21[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
22
23[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
24
25---
26
27## why?
28
29Save time spent manually code reviewing for 'silly' mistakes such as:
30
31- Architecture violations:
32 - importing from a 'higher level' package or folder
33 - importing from folders in both directions
34- Importing from an 'invalid' folder like 'dist' or 'modules' (ugly, and in some cases this can cause issues like webpack bundling the same code twice)
35- Pushing code with disabled tests or with breakpoint code
36- Inconsistent naming of files (the default tslint rule `file-name-casing` only allows for 1 style)
37
38---
39
40## features
41
42- Uses a simple JSON file to model the desired relations between folders and sub-folders
43- Provides a custom tslint rule that walks your TypeScript project, checking for imports that violate the model
44- Other custom rules:
45 - configurably detect disabled tests
46 - detect debug/breakpoint code
47 - detect invalid imports from folders like 'node_modules' or 'dist'
48 - detect filenames that do not match expected style (allows for more than 1 filename style)
49- Provides a tool to generate architecture diagrams from the same model, via [tslint-folders-diagrams](https://github.com/mrseanryan/tslint-folders-diagrams)
50
51---
52
53## versioning
54
55We use [SemVer](https://semver.org) for versioning. For the versions available, see [Releases](https://github.com/mrseanryan/tslint-folders/releases).
56
57---
58
59## usage
60
61### 1 Install via yarn into your website
62
63```
64yarn add tslint-folders
65```
66
67### 2 Configure tslint to pick up the custom rules
68
69Edit your `tslint.json` to have an entry `"rulesDirectory"` that points to tslint-folders.
70
71Normally this would be like:
72
73```
74 "rulesDirectory": "./node_modules/tslint-folders/dist/lib/"
75```
76
77See [tslint.tslint-folders.json](https://github.com/mrseanryan/tslint-folders/blob/master/tslint.tslint-folders.json) for an example.
78
79### 3 Configure the rules
80
81The tslint rules are enabled and configured in `tslint.json`.
82
83See the section under `tsf-folders-imports-between-packages` in [tslint.tslint-folders.json](https://github.com/mrseanryan/tslint-folders/blob/master/tslint.tslint-folders.json) or the [unit tests](https://github.com/mrseanryan/tslint-folders/blob/master/test/rules/) for examples.
84
85Optionally, you can split out the tslint-folders configuration into a separate file, like `tslint.tslint-folders.json`. To reference the file, add this code to `tslint.json`:
86
87```
88 "extends": "./tslint.tslint-folders.json"
89```
90
91Assuming tslint is already in place, then you should now see any unexpected imports (or disabled tests) be flagged by tslint. This should work as usual for tslint: on the command line, or in an editor such as Visual Code (may require refreshing the editor).
92
93### 4 Generate a summary of the package configuration
94
95See [tslint-folders-diagrams](https://github.com/mrseanryan/tslint-folders-diagrams)
96
97### using graphviz to generate image diagrams of the architecture
98
99A diagram can be automatically generated from the same config used to validated the code:
100
101![example diagram](https://github.com/mrseanryan/tslint-folders/blob/master/static/images/example_diagram_from_Dot_output.png?raw=true)
102
103see [tslint-folders-diagrams](https://github.com/mrseanryan/tslint-folders-diagrams) for details.
104
105---
106
107## Summary of the Custom Rules
108
109here is a summary of the current custom rules.
110
111| Rule ID | Description |
112| ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
113| tsf-folders-disabled-test | Detect a disabled unit test, test suite or integration test. |
114| tsf-folders-file-names | Validates casing of filenames. Similar to standard rule `file-name-casing` except it supports multiple allowed casings, and disallows file names with invalid characters (such as spaces or commas). |
115| tsf-folders-import-from-disallowed-folders | Detect an import from a non-standard folder like node_modules |
116| tsf-folders-imports-between-packages | Detect an import from a 'higher level' package: for example, import from an application 'shell' package when inside an 'area' package. This is the main custom rule. Also can detect when a package has imports using this packages name (instead of a relative path). |
117| tsf-folders-test-with-breakpoint | Detect when an integration test has a break point like `browser.debug()` |
118
119---
120
121## sites
122
123| site | URL |
124| -------------------- | -------------------------------------------- |
125| source code (github) | https://github.com/mrseanryan/tslint-folders |
126| github page | https://mrseanryan.github.io/tslint-folders/ |
127| npm | https://www.npmjs.com/package/tslint-folders |
128
129---
130
131## approach taken
132
133All of the rules use the same prefix `tsf-folders-`.
134
135To make it clear to developers that a _custom_ rule is involved, all messages from the rules also include the rule id.
136
137Some of these rules could be replaced by standard tslint configuration.
138However, having custom rules gives clearer messages to help the developer to know what to fix (or what rule to disable for that piece of code).
139
140Some of the rules are not strictly about 'folders', but are included here as they also seem useful.
141
142For more details and examples please see the [unit tests](https://github.com/mrseanryan/tslint-folders/blob/master/test/rules/)
143
144---
145
146## building and testing this source code
147
148To work on the source code for tslint-folders, there are a few scripts:
149
150| command | description |
151| ------------- | ----------------------------------------------------------------------- |
152| yarn build | Builds the rules to the 'dist' folder, from where they can be executed. |
153| yarn lint | Lints the source code of the rules. |
154| yarn start | Builds, tests and lints the code. |
155| yarn test | Tests the rules against spec files (\*.lint) |
156| yarn test-one | Test a single rule against spec files (\*.lint) |
157
158---
159
160## unit tests
161
162The unit tests for the rule `tsf-folders-imports-between-packages` are [here](https://github.com/mrseanryan/tslint-folders/blob/master/test/rules/tsf-folders-imports-between-packages).
163
164The unit tests use test data to check the package boundaries of a fairly typical website.
165
166The matching configuration can be seen in [tslint.tslint-folders.json](https://github.com/mrseanryan/tslint-folders/blob/master/tslint.tslint-folders.json)
167
168### test data - packages
169
170The test data is based around a website that uses multiple packages:
171
172| Package name | Description |
173| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
174| shell | The application shell - this is the top level package, and it can import from any other package. |
175| todo-area | A 'todo app' area of the website, that is hosted within the shell. It should not import from the shell or from other 'area' packages. |
176| todo-contact | A 'contact info' area of the website, that is hosted within the shell. It should not import from the shell or from other 'area' packages. |
177| grid-package | A UI grid that is used by area packages. It should not import any other recognised packages. |
178| utils | A 'utils' package used by the shell and area packages. It should not import any other recognised packages. |
179
180**Example validation**: 'shell' should be able to import from 'todo-area', but not the other way around (shell is at a higher level of abstraction, and also want to avoid 2-way dependencies).
181
182### test data - packages with sub-folders
183
184tslint-folders can also validate imports between sub-folders of a package.
185
186The test data 'todo-area' package is configured with fairly typical sub-folders such as 'components' and 'models'. [tslint.tslint-folders.json](https://github.com/mrseanryan/tslint-folders/blob/master/tslint.tslint-folders.json) has been configured to check the imports between these folders.
187
188| Sub-folder name | Description |
189| --------------- | --------------------------------------------------------------------------------------- |
190| components | Top-level folder of UI components. Can import from any of the other recognised folders. |
191| viewmodels | Folder of view models, used by the UI components. Can only import from models or utils. |
192| models | Folder of models, used by the view models. Can only import from utils. |
193| utils | A 'utils' folder. It should not import any other recognised folders. |
194
195**Example validation**: 'components' should be able to import from 'models', but not the other way around (components is at a higher level of abstraction, and also want to avoid 2-way dependencies).
196
197---
198
199## developing code in _this_ repository
200
201see the [contributing readme](CONTRIBUTING.md).
202
203## origin
204
205This project is based on the excellent seeder project [typescript-library-starter](https://github.com/alexjoverm/typescript-library-starter).
206
207The project was started to avoid having to repeatedly fix similar coding issues in large TypeScript code bases.
208
209### ORIGINAL readme (from the seeder project)
210
211[see here](https://github.com/mrseanryan/tslint-folders/blob/master/readme.original.md)
212
213---
214
215## that's it
216
217That's pretty much it. Let me know if this is useful or how it can be improved!
218
219## authors
220
221Original work by Sean Ryan - mr.sean.ryan(at gmail.com)
222
223## licence = MIT
224
225This project is licensed under the MIT License - see the [LICENSE](https://github.com/mrseanryan/tslint-folders/blob/master/LICENSE) file for details