├── .gitignore ├── animals ├── animal.ts ├── index.ts ├── tsconfig.json └── dog.ts ├── core ├── tsconfig.json └── utilities.ts ├── tsconfig.json ├── zoo ├── zoo.ts └── tsconfig.json ├── tsconfig-base.json ├── package.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | lib/ 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /animals/animal.ts: -------------------------------------------------------------------------------- 1 | export type Size = "small" | "medium" | "large"; 2 | export default interface Animal { 3 | size: Size; 4 | } 5 | -------------------------------------------------------------------------------- /animals/index.ts: -------------------------------------------------------------------------------- 1 | import Animal from './animal'; 2 | 3 | export default Animal; 4 | import { createDog, Dog } from './dog'; 5 | export { createDog, Dog }; 6 | -------------------------------------------------------------------------------- /core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig-base.json", 3 | "compilerOptions": { 4 | "outDir": "../lib/core", 5 | "rootDir": "." 6 | } 7 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./core" 6 | }, 7 | { 8 | "path": "./animals" 9 | }, 10 | { 11 | "path": "./zoo" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /zoo/zoo.ts: -------------------------------------------------------------------------------- 1 | // import Animal from '../animals/index'; 2 | import { Dog, createDog } from '../animals/index'; 3 | 4 | export function createZoo(): Array { 5 | return [ 6 | createDog() 7 | ]; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /animals/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig-base.json", 3 | "compilerOptions": { 4 | "outDir": "../lib/animals", 5 | "rootDir": ".", 6 | }, 7 | "references": [ 8 | { "path": "../core" } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /zoo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig-base.json", 3 | "compilerOptions": { 4 | "outDir": "../lib/zoo", 5 | "rootDir": "." 6 | }, 7 | "references": [ 8 | { 9 | "path": "../animals" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /core/utilities.ts: -------------------------------------------------------------------------------- 1 | 2 | export function makeRandomName() { 3 | return "Bob!?! "; 4 | } 5 | 6 | export function lastElementOf(arr: T[]): T | undefined { 7 | if (arr.length === 0) return undefined; 8 | return arr[arr.length - 1]; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /tsconfig-base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "target": "es5", 5 | "module": "commonjs", 6 | "strict": true, 7 | "noUnusedLocals": true, 8 | "noUnusedParameters": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true, 11 | "composite": true 12 | } 13 | } -------------------------------------------------------------------------------- /animals/dog.ts: -------------------------------------------------------------------------------- 1 | import Animal from '.'; 2 | import { makeRandomName } from '../core/utilities'; 3 | 4 | export interface Dog extends Animal { 5 | woof(): void; 6 | name: string; 7 | } 8 | 9 | export function createDog(): Dog { 10 | return ({ 11 | size: "medium", 12 | woof: function(this: Dog) { 13 | console.log(`${this.name} says "Woof"!`); 14 | }, 15 | name: makeRandomName() 16 | }); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "project-references-demo", 3 | "version": "1.0.0", 4 | "description": "The structure of this repo is as follows:", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "tsc -b -v", 8 | "clean": "tsc -b --clean" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/RyanCavanaugh/project-references-demo.git" 13 | }, 14 | "author": "", 15 | "license": "ISC", 16 | "bugs": { 17 | "url": "https://github.com/RyanCavanaugh/project-references-demo/issues" 18 | }, 19 | "homepage": "https://github.com/RyanCavanaugh/project-references-demo#readme", 20 | "dependencies": { 21 | "typescript": "^3.5.3" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TypeScript Project References Demo 2 | 3 | ## Files in this repository 4 | 5 | The structure of this repo is as follows: 6 | 7 | #### Source Code Folders 8 | ``` 9 | /core Base library for this application 10 | /tsconfig.json Config file for 'core' project 11 | /utilities.ts Submodule that exposes two utility functions 12 | /animals Depends on 'core' 13 | /tsconfig.json Config file for 'animal' project 14 | /animal.ts Defines the 'animal' type 15 | /dog.ts Defines the 'dog' type 16 | /index.ts Entry point module that re-exposes types from animal.ts and dog.ts 17 | /zoo Depends on 'animals' (directly) and 'core' (indirectly) 18 | /tsconfig.json Config file for 'zoo' project 19 | /zoo.ts Creates a zoo with some dogs in it (OK it's a weird zoo) 20 | /tsconfig.json Solution file for the application 21 | ``` 22 | 23 | #### Build and Build Configuration 24 | ``` 25 | /core Base library for this application 26 | /lib Output folder (not checked in) 27 | /tsconfig-base.json Shared configuration file for common compiler options 28 | ``` 29 | 30 | #### The Usual Suspects 31 | ``` 32 | /README.md You're reading it 33 | /.gitignore For excluding build outputs and node_modules 34 | /package.json NPM package definition file 35 | /package-lock.json NPM package lock file 36 | /node_modules NPM modules 37 | ``` 38 | 39 | # Branches You Can Try 40 | 41 | The following branches are provided for demo/exploration purposes 42 | 43 | ### `master` 44 | This branch shows the normal layout 45 | 46 | ``` 47 | > git checkout master 48 | >yarn build 49 | yarn run v1.15.2 50 | $ tsc -b -v 51 | [11:02:33 AM] Projects in this build: 52 | * core/tsconfig.json 53 | * animals/tsconfig.json 54 | * zoo/tsconfig.json 55 | * tsconfig.json 56 | 57 | [11:02:33 AM] Project 'core/tsconfig.json' is out of date because output file 'lib/core/utilities.js' does not exist 58 | 59 | [11:02:33 AM] Building project 'c:/github/project-references-demo/core/tsconfig.json'... 60 | 61 | [11:02:35 AM] Project 'animals/tsconfig.json' is out of date because output file 'lib/animals/animal.js' does not exist 62 | 63 | [11:02:35 AM] Building project 'c:/github/project-references-demo/animals/tsconfig.json'... 64 | 65 | [11:02:35 AM] Project 'zoo/tsconfig.json' is out of date because output file 'lib/zoo/zoo.js' does not exist 66 | 67 | [11:02:35 AM] Building project 'c:/github/project-references-demo/zoo/tsconfig.json'... 68 | 69 | Done in 2.66s. 70 | 71 | > 72 | ``` 73 | 74 | ### `circular` 75 | This branch introduces a circular dependency by editing the `core` project's `tsconfig.json` to add a dependency to `zoo`. 76 | Attempting to build any project will cause an error: 77 | ``` 78 | > git checkout circular 79 | > yarn build 80 | yarn run v1.15.2 81 | $ tsc -b -v 82 | [11:52:04 AM] Projects in this build: 83 | * animals/tsconfig.json 84 | * zoo/tsconfig.json 85 | * core/tsconfig.json 86 | * tsconfig.json 87 | 88 | error TS6202: Project references may not form a circular graph. Cycle detected: c:/github/project-references-demo/tsconfig.json 89 | c:/github/project-references-demo/core/tsconfig.json 90 | c:/github/project-references-demo/zoo/tsconfig.json 91 | c:/github/project-references-demo/animals/tsconfig.json 92 | 93 | 94 | Found 1 error. 95 | 96 | error Command failed with exit code 4. 97 | info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. 98 | 99 | > 100 | 101 | ``` 102 | 103 | ### `bad-ref` 104 | This branch introduces an illegal reference in the source code by adding an `import` targeting a file outside the project folder. Attempting to build `core` will cause an error: 105 | ``` 106 | > git checkout bad-ref 107 | >yarn build 108 | yarn run v1.15.2 109 | $ tsc -b -v 110 | [1:40:34 PM] Projects in this build: 111 | * core/tsconfig.json 112 | * animals/tsconfig.json 113 | * zoo/tsconfig.json 114 | * tsconfig.json 115 | 116 | [1:40:34 PM] Project 'core/tsconfig.json' is out of date because output file 'lib/core/utilities.js' does not exist 117 | 118 | [1:40:34 PM] Building project 'c:/github/project-references-demo/core/tsconfig.json'... 119 | 120 | animals/index.ts:1:20 - error TS6059: File 'c:/github/project-references-demo/animals/animal.ts' is not under 'rootDir' 'c:/github/project-references-demo/core'. 'rootDir' is expected to contain all source files. 121 | 122 | 1 import Animal from './animal'; 123 | ~~~~~~~~~~ 124 | 125 | animals/index.ts:1:20 - error TS6307: File 'c:/github/project-references-demo/animals/animal.ts' is not listed within the file list of project 'c:/github/project-references-demo/core/tsconfig.json'. Projects must list all files or use an 'include' pattern. 126 | 127 | 1 import Animal from './animal'; 128 | ~~~~~~~~~~ 129 | 130 | animals/index.ts:4:32 - error TS6059: File 'c:/github/project-references-demo/animals/dog.ts' is not under 'rootDir' 'c:/github/project-references-demo/core'. 'rootDir' is expected to contain all source files. 131 | 132 | 4 import { createDog, Dog } from './dog'; 133 | ~~~~~~~ 134 | 135 | animals/index.ts:4:32 - error TS6307: File 'c:/github/project-references-demo/animals/dog.ts' is not listed within the file list of project 'c:/github/project-references-demo/core/tsconfig.json'. Projects must list all files or use an 'include' pattern. 136 | 137 | 4 import { createDog, Dog } from './dog'; 138 | ~~~~~~~ 139 | 140 | core/utilities.ts:1:1 - error TS6133: 'A' is declared but its value is never read. 141 | 142 | 1 import * as A from '../animals'; 143 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 144 | 145 | core/utilities.ts:1:20 - error TS6059: File 'c:/github/project-references-demo/animals/index.ts' is not under 'rootDir' 'c:/github/project-references-demo/core'. 'rootDir' is expected to contain all source files. 146 | 147 | 1 import * as A from '../animals'; 148 | ~~~~~~~~~~~~ 149 | 150 | core/utilities.ts:1:20 - error TS6307: File 'c:/github/project-references-demo/animals/index.ts' is not listed within the file list of project 'c:/github/project-references-demo/core/tsconfig.json'. Projects must list all files or use an 'include' pattern. 151 | 152 | 1 import * as A from '../animals'; 153 | ~~~~~~~~~~~~ 154 | 155 | [1:40:35 PM] Project 'animals/tsconfig.json' can't be built because its dependency 'core' has errors 156 | 157 | [1:40:35 PM] Skipping build of project 'c:/github/project-references-demo/animals/tsconfig.json' because its dependency 'c:/github/project-references-demo/core' has errors 158 | 159 | [1:40:35 PM] Project 'zoo/tsconfig.json' can't be built because its dependency 'animals' was not built 160 | 161 | [1:40:35 PM] Skipping build of project 'c:/github/project-references-demo/zoo/tsconfig.json' because its dependency 'c:/github/project-references-demo/animals' was not built 162 | 163 | 164 | Found 7 errors. 165 | 166 | error Command failed with exit code 1. 167 | info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. 168 | 169 | > 170 | ``` 171 | 172 | ### `empty-sleeves` 173 | Nothing up my sleeves 🐇🎩! 174 | This branch *deletes* the `core` and `animals` source files. 175 | The `zoo` project can still be built because it only consumes the output files. 176 | ``` 177 | > gulp clean 178 | [...] 179 | > gulp core animals 180 | [...] 181 | > git checkout empty-sleeves 182 | > gulp zoo 183 | [07:35:22] Using gulpfile C:\github\project-references-demo\gulpfile.js 184 | [07:35:22] Starting 'zoo'... 185 | [07:35:24] Finished 'zoo' after 2.15 s 186 | ``` 187 | --------------------------------------------------------------------------------