Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation and example code for projectReferences #1184

Merged
merged 3 commits into from Sep 14, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -713,6 +713,8 @@ This flag enables caching for some FS-functions like `fileExists`, `realpath` an

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.

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/).

### Usage with webpack watch

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:
Expand Down
329 changes: 329 additions & 0 deletions REFERENCES.md

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions examples/project-references-example/.gitignore
@@ -0,0 +1,5 @@
lib/
node_modules/
dist/
tsconfig.tsbuildinfo

24 changes: 24 additions & 0 deletions examples/project-references-example/README.md
@@ -0,0 +1,24 @@
# TypeScript Project References Demo

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:

* TypeScript
* Webpack
* ts-loader
* yarn workspaces

This repo is described in the article [here](/REFERENCES.md).

## Installation
```
yarn install
```

## Running
```
yarn start
```
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.



36 changes: 36 additions & 0 deletions examples/project-references-example/package.json
@@ -0,0 +1,36 @@
{
"name": "project-references-demo",
"version": "1.0.0",
"description": "To compare the performance of project references with webpack & ts-loader vs webpack and tsc run in a separate process.",
"main": "index.js",
"private": true,
"workspaces": ["packages/*"],
"scripts": {
"start": "webpack-dev-server",
"build": "webpack"
},
"repository": {
"type": "git",
"url": "git+https://github.com/appzuka/project-references-demo.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/appzuka/project-references-demo.git/issues"
},
"homepage": "https://github.com/appzuka/project-references-demo.git",
"dependencies": {
"@types/node": "^14.6.1",
"@types/react": "^16.9.48",
"fork-ts-checker-webpack-plugin": "^5.1.0",
"html-webpack-plugin": "^4.4.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"ts-loader": "^8.0.3",
"tsconfig-paths-webpack-plugin": "^3.3.0",
"typescript": "^3.9.7",
"webpack": "^4.44.1",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0"
}
}
10 changes: 10 additions & 0 deletions examples/project-references-example/packages/animals/animal.ts
@@ -0,0 +1,10 @@
type Size = "small" | "medium" | "large";

interface Animal {
size: Size;
}

export {
Animal,
Size
}
28 changes: 28 additions & 0 deletions examples/project-references-example/packages/animals/dog.tsx
@@ -0,0 +1,28 @@
import { Animal, Size } from './animal';
import { makeRandomName } from '@myscope/core';

interface Dog extends Animal {
woof(): void;
name: string;
}

const sizes = "small medium large".split(' ');
const barks = "Woof Yap Growl".split(' ');

function createDog(): Dog {
return ({
size: sizes[Math.floor(Math.random() * sizes.length)] as Size,
woof: function(this: Dog) {
return(`${this.name} says ${barks[Math.floor(Math.random() * barks.length)]}!`);
},
name: makeRandomName(),
// deliberateError: 42
});
}

export {
Dog,
createDog
}


4 changes: 4 additions & 0 deletions examples/project-references-example/packages/animals/index.ts
@@ -0,0 +1,4 @@
import { Animal } from './animal';

import { createDog, Dog } from './dog';
export { Animal, createDog, Dog };
10 changes: 10 additions & 0 deletions examples/project-references-example/packages/animals/package.json
@@ -0,0 +1,10 @@
{
"name": "@myscope/animals",
"version": "1.0.0",
"description": "Animals package",
"main": "lib/index.js",
"directories": {
"lib": "lib"
},
"license": "ISC"
}
10 changes: 10 additions & 0 deletions examples/project-references-example/packages/animals/tsconfig.json
@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig-base.json",
"compilerOptions": {
"outDir": "lib",
"rootDir": ".",
},
"references": [
{ "path": "../core" }
]
}
10 changes: 10 additions & 0 deletions examples/project-references-example/packages/core/package.json
@@ -0,0 +1,10 @@
{
"name": "@myscope/core",
"version": "1.0.0",
"description": "Core package",
"main": "lib/utilities.js",
"directories": {
"lib": "lib"
},
"license": "ISC"
}
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig-base.json",
"compilerOptions": {
"outDir": "lib",
"rootDir": "."
}
}
17 changes: 17 additions & 0 deletions examples/project-references-example/packages/core/utilities.ts
@@ -0,0 +1,17 @@

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(' ');

function makeRandomName() {
return dogNames[Math.floor(Math.random() * dogNames.length)];
}

function lastElementOf<T>(arr: T[]): T | undefined {
if (arr.length === 0) return undefined;
return arr[arr.length - 1];
}

export {
makeRandomName,
lastElementOf
}

10 changes: 10 additions & 0 deletions examples/project-references-example/packages/zoo/package.json
@@ -0,0 +1,10 @@
{
"name": "@myscope/zoo",
"version": "1.0.0",
"description": "Zoo package",
"main": "lib/zoo.js",
"directories": {
"lib": "lib"
},
"license": "ISC"
}
13 changes: 13 additions & 0 deletions examples/project-references-example/packages/zoo/tsconfig.json
@@ -0,0 +1,13 @@
{
"extends": "../../tsconfig-base.json",
"compilerOptions": {
"outDir": "lib",
"jsx": "react",
"rootDir": ".",
},
"references": [
{
"path": "../animals"
}
]
}
31 changes: 31 additions & 0 deletions examples/project-references-example/packages/zoo/zoo.tsx
@@ -0,0 +1,31 @@
import React from 'react';
import { Dog, createDog } from '@myscope/animals';

function CreateZoo() {

const dogs = [
createDog(),
createDog(),
createDog(),
createDog(),
createDog(),
createDog(),
createDog()
];
return (<>
<h2>List of Dogs</h2>
<hr />
{dogs.map((dog, i) => {return(
<div className='dog' key={i}>
<p>Dog: {i} - Size: {dog.size} - Name: {dog.name}</p>
<p>Bark: {dog.woof()}</p>
<hr />
</div>
)})}
</>)
}

export {
CreateZoo
}

8 changes: 8 additions & 0 deletions examples/project-references-example/src/index.tsx
@@ -0,0 +1,8 @@
import { CreateZoo } from '@myscope/zoo';
import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(
<CreateZoo />,
document.getElementById('react-content')
);
16 changes: 16 additions & 0 deletions examples/project-references-example/tsconfig-base.json
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"esModuleInterop": true,
"composite": true,
"jsx": "react",
"baseUrl": ".", // This must be specified if "paths" is.
"paths": {
"packages/*": ["packages/*"]
}
}
}
15 changes: 15 additions & 0 deletions examples/project-references-example/tsconfig.json
@@ -0,0 +1,15 @@
{
"extends": "./tsconfig-base.json",
"files": ["src/index.tsx"],
"references": [
{
"path": "./packages/core"
},
{
"path": "./packages/animals"
},
{
"path": "./packages/zoo"
}
]
}
62 changes: 62 additions & 0 deletions examples/project-references-example/webpack.config.js
@@ -0,0 +1,62 @@
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
// To improve build times for large projects enable fork-ts-checker-webpack-plugin
// const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

module.exports = {
"mode": "development",
"entry": "src/index.tsx",
"output": {
"path": __dirname+'/dist',
"filename": "[name].js"
},
"watch": false,
"context": __dirname, // to automatically find tsconfig.json
"module": {
"rules": [
{
"test": /\.tsx?$/,
"exclude": /node_modules/,
"use": {
"loader": "ts-loader",
"options": {
"transpileOnly": false, // Set to true if you are using fork-ts-checker-webpack-plugin
"projectReferences": true
}
}
}
]
},
resolve: {
modules: [
"node_modules",
path.resolve(__dirname)
],
// TsconfigPathsPlugin will automatically add this
// alias: {
// packages: path.resolve(__dirname, 'packages/'),
// },
extensions: [".js", ".ts", ".tsx"],
plugins: [
new TsconfigPathsPlugin({
logLevel: "info",
mainFields: "module",
extensions: [".js", ".ts", ".tsx"]
})
]
},
plugins: [
new HtmlWebpackPlugin({
templateContent: `
<html>
<body>
<h1>Project Reference Demo App</h1>
<div id='react-content'></div>
</body>
</html>
`
}),
// new ForkTsCheckerWebpackPlugin()
]
}