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

chore: add script to build typescript project references #1636

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ packages/tsdocs/fixtures/monorepo/docs
# ESLint cache
.eslintcache

# TypeScrip build cache
.tsbuildinfo
7 changes: 5 additions & 2 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,16 @@
},
{
"label": "Build project",
"group": "build",
"group": {
"kind": "build",
"isDefault": true
},
"type": "shell",
"command": "npm",
"args": [
"run",
"-s",
"build"
"build:dev"
],
"problemMatcher": "$tsc"
},
Expand Down
6 changes: 0 additions & 6 deletions benchmark/index.ts

This file was deleted.

2 changes: 2 additions & 0 deletions benchmark/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
"benchmark"
],
"main": "index.js",
"types:": "dist/index.d.ts",
"engines": {
"node": ">=8.9"
},
"scripts": {
"build": "lb-tsc es2017 --outDir dist",
"build:resources": "lb-copy-resources",
"clean": "lb-clean dist",
"pretest": "npm run clean && npm run build",
"test": "lb-mocha \"dist/__tests__/**/*.js\"",
Expand Down
8 changes: 0 additions & 8 deletions benchmark/tsconfig.build.json

This file was deleted.

30 changes: 30 additions & 0 deletions benchmark/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"$schema": "http://json.schemastore.org/tsconfig",
"extends": "../packages/build/config/tsconfig.common.json",
"compilerOptions": {
"target": "es2017",
"outDir": "dist",
"rootDir": "src",
"composite": true,
"incremental": true,
"tsBuildInfoFile": ".tsbuildinfo"
},
"references": [
{
"path": "../packages/testlab/tsconfig.json"
},
{
"path": "../examples/todo/tsconfig.json"
},
{
"path": "../packages/openapi-spec-builder/tsconfig.json"
},
{
"path": "../packages/rest/tsconfig.json"
}
],
"include": [
"src/**/*",
"src/**/*.json"
]
}
134 changes: 134 additions & 0 deletions bin/update-project-refs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#!/usr/bin/env node
// Copyright IBM Corp. 2017,2018. All Rights Reserved.
// Node module: loopback-next
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

/**
* This is an internal script to update TypeScript project references based on
* lerna's local package dependencies.
*
* See https://www.typescriptlang.org/docs/handbook/project-references.html
*/
'use strict';

const path = require('path');
const fs = require('fs');
const util = require('util');
const debug = require('debug')('loopback:build');
const buildUtils = require('../packages/build/bin/utils');

const Project = require('@lerna/project');
const PackageGraph = require('@lerna/package-graph');

const TSCONFIG = 'tsconfig.json';

async function updateReferences(options) {
options = options || {};
const dryRun = options.dryRun;
const project = new Project(process.cwd());
const packages = await project.getPackages();

const rootRefs = [];
const graph = new PackageGraph(packages);

for (const p of graph.values()) {
debug('Package %s', p.pkg.name);
const pkgLocation = p.pkg.location;
const tsconfigFile = path.join(pkgLocation, TSCONFIG);
// Skip non-typescript packages
if (!fs.existsSync(tsconfigFile)) {
debug('Skipping non-TS package: %s', p.pkg.name);
continue;
}
rootRefs.push({
path: path.join(path.relative(project.rootPath, pkgLocation), TSCONFIG),
});
const tsconfig = require(tsconfigFile);
const refs = [];
for (const d of p.localDependencies.keys()) {
const depPkg = graph.get(d);
// Skip non-typescript packages
if (!fs.existsSync(path.join(depPkg.pkg.location, TSCONFIG))) {
debug('Skipping non-TS dependency: %s', depPkg.pkg.name);
continue;
}
const relativePath = path.relative(pkgLocation, depPkg.pkg.location);
refs.push({path: path.join(relativePath, TSCONFIG)});
}
tsconfig.compilerOptions = Object.assign(
{
// outDir & target have to be set in tsconfig instead of CLI for tsc -b
target: buildUtils.getCompilationTarget(),
outDir: buildUtils.getDistribution(tsconfig.compilerOptions.target),
},
tsconfig.compilerOptions,
{
// composite must be true for project refs
composite: true,
},
);
if (options.incremental) {
// See https://devblogs.microsoft.com/typescript/announcing-typescript-3-4/#faster-subsequent-builds-with-the---incremental-flag
tsconfig.compilerOptions = Object.assign(tsconfig.compilerOptions, {
incremental: true,
tsBuildInfoFile: '.tsbuildinfo',
});
}

if (!tsconfig.include) {
// To include ts/json files
tsconfig.include = ['src/**/*', 'src/**/*.json'];
}
tsconfig.references = refs;

// Convert to JSON
const tsconfigJson = JSON.stringify(tsconfig, null, 2);

if (!dryRun) {
// Using `-f` to overwrite tsconfig.json
fs.writeFileSync(tsconfigFile, tsconfigJson + '\n', {encoding: 'utf-8'});
debug('%s has been updated.', tsconfigFile);
} else {
// Otherwise write to console
debug(tsconfigJson);
console.log('%s', p.pkg.name);
refs.forEach(r => console.log(' %s', r.path));
}
}

const rootTsconfigFile = path.join(project.rootPath, 'tsconfig.json');
const rootTsconfig = require(rootTsconfigFile);
rootTsconfig.compilerOptions = rootTsconfig.compilerOptions || {};
rootTsconfig.compilerOptions.composite = true;
rootTsconfig.references = rootRefs;

// Reset files/include/exclude. The root should use project references now.
rootTsconfig.files = [];
delete rootTsconfig.include;
delete rootTsconfig.exclude;

// Convert to JSON
const rootTsconfigJson = JSON.stringify(rootTsconfig, null, 2);
if (!dryRun) {
// Using `-f` to overwrite tsconfig.json
fs.writeFileSync(rootTsconfigFile, rootTsconfigJson + '\n', {
encoding: 'utf-8',
});
debug('%s has been updated.', rootTsconfigFile);
console.log('TypeScript project references have been updated.');
} else {
debug(rootTsconfigJson);
console.log('\n%s', path.relative(project.rootPath, rootTsconfigFile));
rootRefs.forEach(r => console.log(' %s', r.path));
console.log(
'\nThis is a dry-run. Please use -f option to update tsconfig files.',
);
}
}

if (require.main === module) {
const dryRun = !process.argv.includes('-f');
const incremental = process.argv.includes('--incremental');
updateReferences({dryRun, incremental});
}
3 changes: 0 additions & 3 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
"engines": {
"node": ">=8.9"
},
"files": [
"**/*"
],
"keywords": [
"LoopBack",
"docs"
Expand Down
5 changes: 0 additions & 5 deletions docs/site/DEVELOPING.md
Original file line number Diff line number Diff line change
Expand Up @@ -578,11 +578,6 @@ In the [`loopback-next`](https://github.com/strongloop/loopback-next) monorepo,
1. When using VS Code, the `TypeScript` engine views `loopback-next` as a single
big project.

This enables the "refactor - rename" command to change all places using the
renamed symbol, and also makes "go to definition" command jump to `.ts` files
containing the original source code. Otherwise "refactor - rename" works
within the same package only and "go to definition" jumps to `.d.ts` files.

2. When building the monorepo, we need to build the packages individually, so
that one `dist` directory is created for each package.

Expand Down
19 changes: 8 additions & 11 deletions docs/site/Testing-your-application.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ helper method; for example:
{% include code-caption.html content="src/__tests__/helpers/database.helpers.ts" %}

```ts
import {ProductRepository, CategoryRepository} from '../../src/repositories';
import {ProductRepository, CategoryRepository} from '../../repositories';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's land these documentation fixes in a standalone pull request please.

import {testdb} from '../fixtures/datasources/testdb.datasource';

export async function givenEmptyDatabase() {
Expand Down Expand Up @@ -547,7 +547,7 @@ valid data to create a new model instance.
{% include code-caption.html content="src/__tests__/unit/models/person.model.unit.ts" %}

```ts
import {Person} from '../../../src/models';
import {Person} from '../../../models';
import {givenPersonData} from '../../helpers/database.helpers';
import {expect} from '@loopback/testlab';

Expand Down Expand Up @@ -638,7 +638,7 @@ import {
givenEmptyDatabase,
givenCategory,
} from '../../helpers/database.helpers';
import {CategoryRepository} from '../../../src/repositories';
import {CategoryRepository} from '../../../repositories';
import {expect} from '@loopback/testlab';
import {testdb} from '../../fixtures/datasources/testdb.datasource';

Expand Down Expand Up @@ -671,8 +671,8 @@ ingredient.
```ts
import {expect} from '@loopback/testlab';
import {givenEmptyDatabase, givenProduct} from '../../helpers/database.helpers';
import {ProductController} from '../../../src/controllers';
import {ProductRepository} from '../../../src/repositories';
import {ProductController} from '../../../controllers';
import {ProductRepository} from '../../../repositories';
import {testdb} from '../../fixtures/datasources/testdb.datasource';

describe('ProductController (integration)', () => {
Expand Down Expand Up @@ -719,11 +719,8 @@ of the service proxy by invoking the provider. This helper should be typically
invoked once before the integration test suite begins.

```ts
import {
GeoService,
GeoServiceProvider,
} from '../../src/services/geo.service.ts';
import {GeoDataSource} from '../../src/datasources/geo.datasource.ts';
import {GeoService, GeoServiceProvider} from '../../services/geo.service.ts';
import {GeoDataSource} from '../../datasources/geo.datasource.ts';

describe('GeoService', () => {
let service: GeoService;
Expand All @@ -743,7 +740,7 @@ instance:

```ts
import {merge} from 'lodash';
import * as GEO_CODER_CONFIG from '../src/datasources/geo.datasource.json';
import * as GEO_CODER_CONFIG from '../datasources/geo.datasource.json';

function givenGeoService() {
const config = merge({}, GEO_CODER_CONFIG, {
Expand Down
20 changes: 17 additions & 3 deletions docs/site/VSCODE.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,23 @@ opposed to jumping to a `.d.ts` file in `dist`)
#### Refactoring in VS Code

Verify that refactorings like "rename symbol" (`F2`) will change all places
using the renamed entity. Two different scenarios to verify: rename at the place
where the entity is defined, rename at the place where the entity is used. (You
can e.g. rename `inject` to test.)
using the renamed entity. Two different scenarios to verify, you can e.g. rename
`inject` to test.

1. Rename at the place where the entity is defined. In the current versions of
TypeScript, VS Code performs the rename at `import` level only.

```ts
import {oldName as newName} from 'module';
```

2. Rename at the place where the entity is used.

Due to limitations of the current TypeScript implementation and our project
setup, the refactoring is applied only to files in the same package. The
changes are not applied in other packages in our monorepo. Fortunately, the
TypeScript compiler will tell you which other places you need to change
manually.

## How to verify ESLint setup

Expand Down
8 changes: 0 additions & 8 deletions examples/context/tsconfig.build.json

This file was deleted.

21 changes: 21 additions & 0 deletions examples/context/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "http://json.schemastore.org/tsconfig",
"extends": "@loopback/build/config/tsconfig.common.json",
"compilerOptions": {
"target": "es2017",
"outDir": "dist",
"rootDir": "src",
"composite": true
},
"include": [
"src"
],
"references": [
{
"path": "../../packages/testlab/tsconfig.json"
},
{
"path": "../../packages/context/tsconfig.json"
}
]
}
6 changes: 0 additions & 6 deletions examples/express-composition/index.d.ts

This file was deleted.

6 changes: 0 additions & 6 deletions examples/express-composition/index.ts

This file was deleted.

1 change: 1 addition & 0 deletions examples/express-composition/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"express"
],
"main": "index.js",
"types": "dist/index.d.ts",
"engines": {
"node": ">=8.9"
},
Expand Down
8 changes: 0 additions & 8 deletions examples/express-composition/tsconfig.build.json

This file was deleted.

6 changes: 0 additions & 6 deletions examples/hello-world/index.d.ts

This file was deleted.

Loading