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

Conversation

raymondfeng
Copy link
Contributor

@raymondfeng raymondfeng commented Aug 22, 2018

Start to add support for TypeScript project references.

Checklist

  • npm test passes on your machine
  • New tests added or existing tests modified to cover all changes
  • Code conforms with the style guide
  • API Documentation in code was updated
  • Documentation in /docs/site was updated
  • Affected artifact templates in packages/cli were updated
  • Affected example projects in examples/* were updated

@raymondfeng raymondfeng changed the title chore: add script to build typescript project references [WIP] chore: add script to build typescript project references Aug 22, 2018
@raymondfeng raymondfeng mentioned this pull request Aug 22, 2018
7 tasks
@raymondfeng raymondfeng force-pushed the add-ts-project-refs branch 3 times, most recently from b060100 to 9afd744 Compare August 22, 2018 20:31
rootRefs.push({
path: path.join(
path.relative(project.rootPath, pkgLocation),
'tsconfig.build.json',
Copy link
Member

Choose a reason for hiding this comment

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

Once we switch our monrepo to use project references, we should be able to get rid of tsconfig.build.json files and use regular per-package tsconfig.json file instead.

We are using tsconfig.build.json files to prevent VS Code from recognizing individual packages as individual TypeScript projects, and force it to treat our entire monorepo as a single TypeScript project. This is needed to make cross-package navigation and refactoring working.

With the new feature of project references, supported by VS Code too (now? in a near future?), there is no need to use a different configuration for VS Code and the compiler. We can rename per-package tsconfig.build.json files to regular tsconfig.json files.

We may be able to remove the repository-level tsconfig.json file too, but that requires changes in the way how tslint is executed. I am not sure if running tslint on per-package basis is something we actually want to do.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, we cannot get rid of the top-level tsconfig.json file because this file must contain a list of references to all projects included in the monorepo.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can probably remove tsconfig files from git and generate them as part of the build.

Copy link
Member

Choose a reason for hiding this comment

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

Sure, we can try that.

For now, I am fine with keeping the top-level tsconfig file in git. I think it may be easier for our users, as they don't have to run build before opening VS Code.

bin/update-project-refs.js Outdated Show resolved Hide resolved
bin/update-project-refs.js Outdated Show resolved Hide resolved
@bajtos
Copy link
Member

bajtos commented Aug 23, 2018

I am looking forward to see this work finished and the pull request landed ❤️

@raymondfeng
Copy link
Contributor Author

There are a few challenges to reach a working build:

  1. We allow coexistence of dist8 and dist10 based on the Node version. tsc -b mode does not allow --outDir and --target command options. These values need to be set in tsconfig.json. We might have to dynamically create/update tsconfig.json for our build.

  2. The tsc -b seems to have trouble handing our project layout:

metadata
  - src
  - test
  - index.ts
  - index.d.ts
  - index.js
  - dist10
    - index.d.ts
    - src
    - test

I'm playing with types in package.json to see if it helps. No luck so far.

@bajtos
Copy link
Member

bajtos commented Aug 23, 2018

We allow coexistence of dist8 and dist10 based on the Node version. tsc -b mode does not allow --outDir and --target command options. These values need to be set in tsconfig.json. We might have to dynamically create/update tsconfig.json for our build.

Ouch.

I see why --outDir must be set in tsconfig.json file - there are multiple projects and each has a different output directory. However, could we perhaps work with the TypeScript team to allow --outDir with a project-relative path?

I don't see why --target is not allowed, but it's entirely possible I am missing something. Is this perhaps another opportunity for improving tsc?

The tsc -b seems to have trouble handing our project layout.

Note that package-level index.d.ts is exporting type definitions from dist8, but your example is using dist10 as the output directory. Could that be the source of the problem?

I guess the fix is to dynamically modify these package-level index.d.ts files depending on which version of Node.js we are running on.


Considering all these troubles and how little is Node.js 10.x adding in terms of JavaScript features, maybe we should simply abandon multi-target build and always transpile for Node.js 8.x only?

@raymondfeng
Copy link
Contributor Author

I tried with both Node 8 and 10 to make sure dist8 is available, but the issue stays. You can try as follows:

  1. Check out the branch and run npm i
  2. Run ./bin/update-project-refs.js
  3. cd packages/metadata
  4. ../build/bin/compile-package.js -b tsconfig.build.json or use tsc -b tsconfig.build.json

It complains about export * from './src' in testlab.

@raymondfeng raymondfeng force-pushed the add-ts-project-refs branch 2 times, most recently from ee3cf82 to 1e6dd21 Compare August 23, 2018 23:08
@raymondfeng
Copy link
Contributor Author

Considering all these troubles and how little is Node.js 10.x adding in terms of JavaScript features, maybe we should simply abandon multi-target build and always transpile for Node.js 8.x only?

+1 if necessary.

@bajtos
Copy link
Member

bajtos commented Aug 27, 2018

I'll try to run your changes on my machine later this week.

From what I remember, TypeScript in build mode uses .d.ts.map files to tell the compiler where to find the original sources (to go from the transpiled output back to .ts files). Our hand-writen package-level index file does not provide any map file. If we keep the current approach for selecting a dist directory based on Node.js version, then I am pretty sure we will need to roll out a hand-written index.d.ts.map file to accompany the hand-written index.d.ts file.

I don't know if the missing .d.ts.map file is the source of the error you are seeing though.

@raymondfeng
Copy link
Contributor Author

See microsoft/TypeScript#26689. I created a very simple project to reproduce the problem at https://github.com/raymondfeng/learn-a/.

@raymondfeng
Copy link
Contributor Author

raymondfeng commented Sep 28, 2018

I finally make it working with the following changes:

  • Upgrade to TypeScript 3.1.1
  • Reorganize the project layouts:
    • Move test related files under src/__tests__
    • Set up tsconfig with {"compilerOptions": {"rootDir": "src", "outDir": "dist"}}
    • Add "types": "./dist/index.d.ts" to package.json
    • Consolidate build into one distribution (dist) based on es2017
  • Rename tsconfig.build.json to tsconfig.json
  • Add copy-resources script and build:resources to copy non-TS files

Now we can run tsc -b from loopback-next.

@raymondfeng raymondfeng changed the title [WIP] chore: add script to build typescript project references chore: add script to build typescript project references Sep 28, 2018
@raymondfeng
Copy link
Contributor Author

I have rebased this PR against latest master. PTAL.

@@ -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.

========

Usage:
node ./bin/copy-resources
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 this new build helper in a new pull request. Should we include any documentation for this new helper, e.g. a new section in @loopback/build's README?

Also, shouldn't the usage line mention the actual script name used by npm, which is lb-copy-resources?

@@ -16,17 +16,17 @@
"strictNullChecks": true,
"resolveJsonModule": true,

"lib": ["es2018", "dom", "esnext.asynciterable"],
"lib": ["es2017", "dom", "esnext.asynciterable"],
Copy link
Member

Choose a reason for hiding this comment

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

We want to keep using ES2018 features in our codebase, even if they are transpiled down to ES2017. Please revert this line.

@@ -8,12 +8,13 @@
"performance",
"benchmark"
],
"main": "index.js",
"types": "./dist/index.d.ts",
Copy link
Member

Choose a reason for hiding this comment

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

I'd like to make the change in types configuration in a standalone pull request because it requires changes in other places too. See #2613

@raymondfeng raymondfeng force-pushed the add-ts-project-refs branch 3 times, most recently from 06df8fc to e08f02e Compare April 2, 2019 21:31
@raymondfeng raymondfeng force-pushed the add-ts-project-refs branch 2 times, most recently from 686efa7 to fbdf3be Compare April 17, 2019 20:13
@bajtos
Copy link
Member

bajtos commented May 10, 2019

This pull request is pretty much blocked by microsoft/TypeScript#30823 :(

  • Refactor-rename does not work across packages.
  • Find all references does not work either.

Configure TSC to emit declaration maps, providing information needed by
IDEs like VSCode to jump from usage of a symbol to its definition in
the original source code.

Simplify layout of all packages, remove top-level `index.ts` and
`index.d.ts` files in favor of a package.json entry

    "types": "dist/index.d.ts"

Simplify layout of module packages (excluding example applications) and
remove the top-level `index.js` file in favor of a package.json entry
    "main": "dist/index.js"

Update developer documentation and project templates accordingly.

Benefits of these changes:

- It's a preparation step for TypeScript Project References

- Build is consuming less CPU cycles now. User time used to be 5m21
  before, it's 1m48s now. Real time went down from 0m49s to 0m37s.

- Simpler project setup in our packages, we no longer need to maintain
  dummy index files at the top level.

Drawbacks:

- Refactor-rename does not work across packagas. I believe this is a
  limitation of TypeScript, hopefully it will be eventually fixed.

- Navigation across packages may not work until the monorepo is built.
- add script to build typescript project references
- reorg project layout for better typescript refs
- switch to tsconfig.json
- add copy-resources script
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Internal Tooling Issues related to our tooling and monorepo infrastructore
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants