1 | # tslint-folders
|
2 |
|
3 | Use tslint to check for invalid imports between packages and folders in your TypeScript project.
|
4 |
|
5 | Automatic validation and documentation of package architecture.
|
6 |
|
7 | ---
|
8 |
|
9 | ## usage
|
10 |
|
11 | _note: the links in this readme do not work on npmjs.com - they do work locally or on the source code site._
|
12 |
|
13 | ### 1 Install via yarn into your website
|
14 |
|
15 | ```
|
16 | yarn add tslint-folders
|
17 | ```
|
18 |
|
19 | ### 2 Configure tslint to pick up the custom rules
|
20 |
|
21 | Edit your `tslint.json` to have an entry `"rulesDirectory"` that points to tslint-folders.
|
22 |
|
23 | Normally this would be like:
|
24 |
|
25 | ```
|
26 | "rulesDirectory": "./node_modules/tslint-folders/dist/"
|
27 | ```
|
28 |
|
29 | See [tslint.tslint-folders.json](tslint.tslint-folders.json) for an example.
|
30 |
|
31 | ### 3 Configure the rules
|
32 |
|
33 | The tslint rules are enabled and configured in `tslint.json`.
|
34 |
|
35 | See the section under `tsf-folders-imports-between-packages` in [tslint.tslint-folders.json](tslint.tslint-folders.json) or the [unit tests](./test/rules/) for examples.
|
36 |
|
37 | Optionally, 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`:
|
38 |
|
39 | ```
|
40 | "extends": "./tslint.tslint-folders.json"
|
41 | ```
|
42 |
|
43 | Assuming 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).
|
44 |
|
45 | ### 4 Generate a summary of the package configuration
|
46 |
|
47 | Assuming that `tslint.tslint-folders.json` has been correctly configured to model the expected package structure, then you can run this command to generate a summary:
|
48 |
|
49 | ```
|
50 | node node_modules/tslint-folders/dist/tools/docsGenerator tslint.tslint-folders.json Text
|
51 | ```
|
52 |
|
53 | example output:
|
54 |
|
55 | ```
|
56 | package structure:
|
57 | _____
|
58 | shell - Application Shell
|
59 | --> (any)
|
60 |
|
61 | todo-area - TODO Area Package
|
62 | --> grid-package, utils
|
63 | folders:
|
64 | components - components
|
65 | --> (any)
|
66 |
|
67 | viewmodels - view models
|
68 | --> models, utils
|
69 |
|
70 | models - models
|
71 | --> utils
|
72 |
|
73 | utils - utils
|
74 | --> (none)
|
75 |
|
76 | contact-area - Area that shows contact details
|
77 | --> grid-package, utils
|
78 |
|
79 | grid-package - Grid Package with no dependencies
|
80 | --> (none)
|
81 |
|
82 | utils - Utils package
|
83 | --> (none)
|
84 |
|
85 | _____
|
86 | ```
|
87 |
|
88 | Allowed imports are shown for each package, after the `-->` arrow.
|
89 |
|
90 | ### using graphviz to generate image diagrams of the architecture
|
91 |
|
92 | A diagram can be automatically generated from the same config used to validated the code:
|
93 |
|
94 | ![example diagram](https://bitbucket.org/str/tslint-folders/raw/f9c220af572d72f8dc4024d02582cf2b03b15552/static/images/example_diagram_from_Dot_output-2.svg)
|
95 |
|
96 | see [generating diagrams](./readme.generating-diagram-images.md) for details.
|
97 |
|
98 | ---
|
99 |
|
100 | ## Summary of the Custom Rules
|
101 |
|
102 | here is a summary of the current custom rules.
|
103 |
|
104 | | Rule ID | Description |
|
105 | | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
106 | | tsf-folders-disabled-test | Detect a disabled unit test, test suite or integration test. |
|
107 | | 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). |
|
108 | | tsf-folders-import-from-disallowed-folders | Detect an import from a non-standard folder like node_modules |
|
109 | | 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). |
|
110 | | tsf-folders-test-with-breakpoint | Detect when an integration test has a break point like `browser.debug()` |
|
111 |
|
112 | ---
|
113 |
|
114 | ## sites
|
115 |
|
116 | | site | URL |
|
117 | | ----------------------- | -------------------------------------------- |
|
118 | | bitbucket (source code) | https://bitbucket.org/str/tslint-folders |
|
119 | | npm | https://www.npmjs.com/package/tslint-folders |
|
120 |
|
121 | ---
|
122 |
|
123 | ## approach taken
|
124 |
|
125 | All of the rules use the same prefix `tsf-folders-`.
|
126 |
|
127 | To make it clear to developers that a _custom_ rule is involved, all messages from the rules also include the rule id.
|
128 |
|
129 | Some of these rules could be replaced by standard tslint configuration.
|
130 | However, 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).
|
131 |
|
132 | Some of the rules are not strictly about 'folders', but are included here as they also seem useful.
|
133 |
|
134 | For more details and examples please see the [unit tests](./test/rules/)
|
135 |
|
136 | ---
|
137 |
|
138 | ## building and testing this source code
|
139 |
|
140 | To work on the source code for tslint-folders, there are a few scripts:
|
141 |
|
142 | | command | description |
|
143 | | ------------- | ----------------------------------------------------------------------- |
|
144 | | yarn build | Builds the rules to the 'dist' folder, from where they can be executed. |
|
145 | | yarn docs | Generates summary of the package structure described in tslint.json. |
|
146 | | yarn lint | Lints the source code of the rules. |
|
147 | | yarn start | Builds, tests and lints the code. |
|
148 | | yarn test | Tests the rules against spec files (\*.lint) |
|
149 | | yarn test-one | Test a single rule against spec files (\*.lint) |
|
150 |
|
151 | ---
|
152 |
|
153 | ### git notes
|
154 |
|
155 | merging a feature branch into master: (after unit testing!)
|
156 |
|
157 | ```
|
158 | git checkout master
|
159 | git fetch
|
160 | git pull
|
161 | git merge feature/my-feature
|
162 | git push
|
163 | ```
|
164 |
|
165 | ---
|
166 |
|
167 | ## unit tests
|
168 |
|
169 | The unit tests for the rule `tsf-folders-imports-between-packages` are [here](./test/rules/tsf-folders-imports-between-packages).
|
170 |
|
171 | The unit tests use test data to check the package boundaries of a fairly typical website.
|
172 |
|
173 | The matching configuration can be seen in [tslint.tslint-folders.json](tslint.tslint-folders.json)
|
174 |
|
175 | ### test data - packages
|
176 |
|
177 | The test data is based around a website that uses multiple packages:
|
178 |
|
179 | | Package name | Description |
|
180 | | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
181 | | shell | The application shell - this is the top level package, and it can import from any other package. |
|
182 | | 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. |
|
183 | | 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. |
|
184 | | grid-package | A UI grid that is used by area packages. It should not import any other recognised packages. |
|
185 | | utils | A 'utils' package used by the shell and area packages. It should not import any other recognised packages. |
|
186 |
|
187 | **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).
|
188 |
|
189 | ### test data - packages with sub-folders
|
190 |
|
191 | tslint-folders can also validate imports between sub-folders of a package.
|
192 |
|
193 | The test data 'todo-area' package is configured with fairly typical sub-folders such as 'components' and 'models'. [tslint.tslint-folders.json](tslint.tslint-folders.json) has been configured to check the imports between these folders.
|
194 |
|
195 | | Sub-folder name | Description |
|
196 | | --------------- | --------------------------------------------------------------------------------------- |
|
197 | | components | Top-level folder of UI components. Can import from any of the other recognised folders. |
|
198 | | viewmodels | Folder of view models, used by the UI components. Can only import from models or utils. |
|
199 | | models | Folder of models, used by the view models. Can only import from utils. |
|
200 | | utils | A 'utils' folder. It should not import any other recognised folders. |
|
201 |
|
202 | **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).
|
203 |
|
204 | ---
|
205 |
|
206 | ## that's it
|
207 |
|
208 | That's pretty much it. Let me know if this is useful or how it can be improved!
|
209 |
|
210 | ## licence = MIT
|
211 |
|
212 | License is MIT, so feel free to use or modify.
|