Skip to content

Commit f8eba53

Browse files
authored
Add documentation and example code for projectReferences (#1184)
* Added Project References documentation and example * Fix links & Typos * Clarify relationship between ts-laoder and tsc
1 parent 46d9761 commit f8eba53

21 files changed

+5139
-0
lines changed

Diff for: README.md

+2
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,8 @@ This flag enables caching for some FS-functions like `fileExists`, `realpath` an
713713

714714
ts-loader has opt-in support for [project references](https://www.typescriptlang.org/docs/handbook/project-references.html). With this configuration option enabled, `ts-loader` will incrementally rebuild upstream projects the same way `tsc --build` does. Otherwise, source files in referenced projects will be treated as if they’re part of the root project.
715715

716+
In order to make use of this option your project needs to be correctly configured to build the project references and then to use them as part of the build. See the [Project References Guide](REFERENCES.md) and the example code in the examples which can be found [here](examples/project-references-example/).
717+
716718
### Usage with webpack watch
717719

718720
Because TS will generate .js and .d.ts files, you should ignore these files, otherwise watchers may go into an infinite watch loop. For example, when using webpack, you may wish to add this to your webpack.conf.js file:

Diff for: REFERENCES.md

+331
Large diffs are not rendered by default.

Diff for: examples/project-references-example/.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
lib/
2+
node_modules/
3+
dist/
4+
tsconfig.tsbuildinfo
5+

Diff for: examples/project-references-example/README.md

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# TypeScript Project References Demo
2+
3+
This repo is forked from https://github.com/RyanCavanaugh/project-references-demo, which is a repo to demonstrate the use of project references in TypeScript. It has been extended to show how project references can be used in a project using the following:
4+
5+
* TypeScript
6+
* Webpack
7+
* ts-loader
8+
* yarn workspaces
9+
10+
This repo is described in the article [here](/REFERENCES.md).
11+
12+
## Installation
13+
```
14+
yarn install
15+
```
16+
17+
## Running
18+
```
19+
yarn start
20+
```
21+
Go to localhost:8080 in your browser to view the output. Edit files in the <code>packages</code> to see the changes in the browser.
22+
23+
24+

Diff for: examples/project-references-example/package.json

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "project-references-demo",
3+
"version": "1.0.0",
4+
"description": "To compare the performance of project references with webpack & ts-loader vs webpack and tsc run in a separate process.",
5+
"main": "index.js",
6+
"private": true,
7+
"workspaces": ["packages/*"],
8+
"scripts": {
9+
"start": "webpack-dev-server",
10+
"build": "webpack"
11+
},
12+
"repository": {
13+
"type": "git",
14+
"url": "git+https://github.com/appzuka/project-references-demo.git"
15+
},
16+
"author": "",
17+
"license": "ISC",
18+
"bugs": {
19+
"url": "https://github.com/appzuka/project-references-demo.git/issues"
20+
},
21+
"homepage": "https://github.com/appzuka/project-references-demo.git",
22+
"dependencies": {
23+
"@types/node": "^14.6.1",
24+
"@types/react": "^16.9.48",
25+
"fork-ts-checker-webpack-plugin": "^5.1.0",
26+
"html-webpack-plugin": "^4.4.1",
27+
"react": "^16.13.1",
28+
"react-dom": "^16.13.1",
29+
"ts-loader": "^8.0.3",
30+
"tsconfig-paths-webpack-plugin": "^3.3.0",
31+
"typescript": "^3.9.7",
32+
"webpack": "^4.44.1",
33+
"webpack-cli": "^3.3.12",
34+
"webpack-dev-server": "^3.11.0"
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
type Size = "small" | "medium" | "large";
2+
3+
interface Animal {
4+
size: Size;
5+
}
6+
7+
export {
8+
Animal,
9+
Size
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Animal, Size } from './animal';
2+
import { makeRandomName } from '@myscope/core';
3+
4+
interface Dog extends Animal {
5+
woof(): void;
6+
name: string;
7+
}
8+
9+
const sizes = "small medium large".split(' ');
10+
const barks = "Woof Yap Growl".split(' ');
11+
12+
function createDog(): Dog {
13+
return ({
14+
size: sizes[Math.floor(Math.random() * sizes.length)] as Size,
15+
woof: function(this: Dog) {
16+
return(`${this.name} says ${barks[Math.floor(Math.random() * barks.length)]}!`);
17+
},
18+
name: makeRandomName(),
19+
// deliberateError: 42
20+
});
21+
}
22+
23+
export {
24+
Dog,
25+
createDog
26+
}
27+
28+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { Animal } from './animal';
2+
3+
import { createDog, Dog } from './dog';
4+
export { Animal, createDog, Dog };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "@myscope/animals",
3+
"version": "1.0.0",
4+
"description": "Animals package",
5+
"main": "lib/index.js",
6+
"directories": {
7+
"lib": "lib"
8+
},
9+
"license": "ISC"
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"extends": "../../tsconfig-base.json",
3+
"compilerOptions": {
4+
"outDir": "lib",
5+
"rootDir": ".",
6+
},
7+
"references": [
8+
{ "path": "../core" }
9+
]
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "@myscope/core",
3+
"version": "1.0.0",
4+
"description": "Core package",
5+
"main": "lib/utilities.js",
6+
"directories": {
7+
"lib": "lib"
8+
},
9+
"license": "ISC"
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": "../../tsconfig-base.json",
3+
"compilerOptions": {
4+
"outDir": "lib",
5+
"rootDir": "."
6+
}
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
const dogNames = "Baxter Bear Beau Benji Benny Benny Bentley Blue Bo Boomer Brady Brody Bruno Brutus Bubba Buddy Buster Cash Champ Chance Charlie Chase Chester Chico Coco Cody Cooper Copper Dexter Diesel Duke Elvis Finn Frankie George Gizmo Gunner Gus Hank Harley Henry Hunter Jack Jackson Jake Jasper Jax Joey Kobe Leo Loki Louie Lucky Luke Mac Marley Max Mickey Milo Moose Murphy Oliver Ollie Oreo Oscar Otis Peanut Prince Rex Riley Rocco Rocky Romeo Roscoe Rudy Rufus Rusty Sam Sammy Samson Scooter Scout Shadow Simba Sparky Spike Tank Teddy Thor Toby Tucker Tyson Vader Winston Yoda Zeus Ziggy".split(' ');
3+
4+
function makeRandomName() {
5+
return dogNames[Math.floor(Math.random() * dogNames.length)];
6+
}
7+
8+
function lastElementOf<T>(arr: T[]): T | undefined {
9+
if (arr.length === 0) return undefined;
10+
return arr[arr.length - 1];
11+
}
12+
13+
export {
14+
makeRandomName,
15+
lastElementOf
16+
}
17+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "@myscope/zoo",
3+
"version": "1.0.0",
4+
"description": "Zoo package",
5+
"main": "lib/zoo.js",
6+
"directories": {
7+
"lib": "lib"
8+
},
9+
"license": "ISC"
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"extends": "../../tsconfig-base.json",
3+
"compilerOptions": {
4+
"outDir": "lib",
5+
"jsx": "react",
6+
"rootDir": ".",
7+
},
8+
"references": [
9+
{
10+
"path": "../animals"
11+
}
12+
]
13+
}
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import React from 'react';
2+
import { Dog, createDog } from '@myscope/animals';
3+
4+
function CreateZoo() {
5+
6+
const dogs = [
7+
createDog(),
8+
createDog(),
9+
createDog(),
10+
createDog(),
11+
createDog(),
12+
createDog(),
13+
createDog()
14+
];
15+
return (<>
16+
<h2>List of Dogs</h2>
17+
<hr />
18+
{dogs.map((dog, i) => {return(
19+
<div className='dog' key={i}>
20+
<p>Dog: {i} - Size: {dog.size} - Name: {dog.name}</p>
21+
<p>Bark: {dog.woof()}</p>
22+
<hr />
23+
</div>
24+
)})}
25+
</>)
26+
}
27+
28+
export {
29+
CreateZoo
30+
}
31+

Diff for: examples/project-references-example/src/index.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { CreateZoo } from '@myscope/zoo';
2+
import React from 'react';
3+
import ReactDOM from 'react-dom';
4+
5+
ReactDOM.render(
6+
<CreateZoo />,
7+
document.getElementById('react-content')
8+
);
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"compilerOptions": {
3+
"declaration": true,
4+
"declarationMap": true,
5+
"target": "es5",
6+
"module": "commonjs",
7+
"moduleResolution": "node",
8+
"esModuleInterop": true,
9+
"composite": true,
10+
"jsx": "react",
11+
"baseUrl": ".", // This must be specified if "paths" is.
12+
"paths": {
13+
"packages/*": ["packages/*"]
14+
}
15+
}
16+
}

Diff for: examples/project-references-example/tsconfig.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"extends": "./tsconfig-base.json",
3+
"files": ["src/index.tsx"],
4+
"references": [
5+
{
6+
"path": "./packages/core"
7+
},
8+
{
9+
"path": "./packages/animals"
10+
},
11+
{
12+
"path": "./packages/zoo"
13+
}
14+
]
15+
}
+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
const path = require('path');
2+
const HtmlWebpackPlugin = require('html-webpack-plugin');
3+
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
4+
// To improve build times for large projects enable fork-ts-checker-webpack-plugin
5+
// const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
6+
7+
module.exports = {
8+
"mode": "development",
9+
"entry": "src/index.tsx",
10+
"output": {
11+
"path": __dirname+'/dist',
12+
"filename": "[name].js"
13+
},
14+
"watch": false,
15+
"context": __dirname, // to automatically find tsconfig.json
16+
"module": {
17+
"rules": [
18+
{
19+
"test": /\.tsx?$/,
20+
"exclude": /node_modules/,
21+
"use": {
22+
"loader": "ts-loader",
23+
"options": {
24+
"transpileOnly": false, // Set to true if you are using fork-ts-checker-webpack-plugin
25+
"projectReferences": true
26+
}
27+
}
28+
}
29+
]
30+
},
31+
resolve: {
32+
modules: [
33+
"node_modules",
34+
path.resolve(__dirname)
35+
],
36+
// TsconfigPathsPlugin will automatically add this
37+
// alias: {
38+
// packages: path.resolve(__dirname, 'packages/'),
39+
// },
40+
extensions: [".js", ".ts", ".tsx"],
41+
plugins: [
42+
new TsconfigPathsPlugin({
43+
logLevel: "info",
44+
mainFields: "module",
45+
extensions: [".js", ".ts", ".tsx"]
46+
})
47+
]
48+
},
49+
plugins: [
50+
new HtmlWebpackPlugin({
51+
templateContent: `
52+
<html>
53+
<body>
54+
<h1>Project Reference Demo App</h1>
55+
<div id='react-content'></div>
56+
</body>
57+
</html>
58+
`
59+
}),
60+
// new ForkTsCheckerWebpackPlugin()
61+
]
62+
}

0 commit comments

Comments
 (0)