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

Allow regular flags to mix with --build #25613

Open
ikokostya opened this issue Jul 12, 2018 · 14 comments
Open

Allow regular flags to mix with --build #25613

ikokostya opened this issue Jul 12, 2018 · 14 comments
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript

Comments

@ikokostya
Copy link
Contributor

ikokostya commented Jul 12, 2018

TypeScript Version: 3.0.0-rc, 3.0.0-dev.20180712

Search Terms:

build mode, --build

Code

I have project with the following tsconfig.json:

{
    "compilerOptions": {
        "module": "commonjs",
        "moduleResolution": "node",
        "target": "es2017",
        "lib": ["es2017"],
        "strict": true,
        "sourceMap": true,
        "noEmitOnError": true,
        "types": ["node"]
    },
    "include": [
        "src/**/*.ts"
    ]
}

and compile it with command:

node_modules/.bin/tsc --build tsconfig.json --outDir out --rootDir /home/kostya/proj/foo

Note, that outDir and rootDir options come from command line arguments, because I want to share output directory for another command (clean).

Expected behavior:

outDir and rootDir options will be took from command line.

Actual behavior:

Compiler ignores this options:

node_modules/.bin/tsc --build tsconfig.json --outDir out --rootDir /home/kostya/proj/foo
message TS6096: File '/home/kostya/proj/foo/--outDir' does not exist.

message TS6096: File '/home/kostya/proj/foo/out' does not exist.

message TS6096: File '/home/kostya/proj/foo/--rootDir' does not exist.

Playground Link:

Related Issues: #25600

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels Jul 12, 2018
@RyanCavanaugh RyanCavanaugh changed the title --build mode doesn't work with --outDir and --rootDir options Allow regular flags to mix with --build Jul 12, 2018
@RyanCavanaugh
Copy link
Member

Hijacking title a bit.

The current design is intentionally that regular flags don't "mix" with --build. For a single compilation these flags are obviously clear, but it becomes rather fraught with -b -- for example, is the outDir relative to the current directory, or should it be relative to each tsconfig in turn? What does it mean to specify a --outFile for a -b compilation - all projects overwrite the file after each other, or they all get bundled together (and if so, in what order?).

We might opt in specific flags that have clear meanings under a multi-project build -- discussion of which ones you'd like to see and what your use cases are would be useful data. Thanks!

@rrousselGit
Copy link

@RyanCavanaugh Parcel uses the transpileModule api to convert ts to js files.

In this situation, how can parcel work with project references to build dependencies too?

@RyanCavanaugh
Copy link
Member

@rrousselGit if you're using transpileModule then there's no particular new work to do - transpilation-only mode knows nothing about module resolution or .d.ts inclusion, which are the only things project reference affect.

If you want to read the references from the tsconfig to walk the dependency graph and build upstream projects, you can call ts.createSolutionBuilder and then call getBuildGraph to get a representation of the dependency tree you can traverse.

@dlannoye
Copy link
Member

@RyanCavanaugh I ran into this today with other flags like noUnusedLocals and noUnusedParameters. I want these to be enforced in my regular builds, but I would like a way to turn them off when doing watching builds so I can still get run-able output while in the middle of refactoring something where I may be left with unused locals/parameters. With the way build mode works today I can't seem to find a way to accomplish this.

I tried a custom build script that called ts.performBuild with a compilierHost that sets these two options and its seems like they were still ignored. To me this felt like it would be a good option to provide if you didn't want to add all of the compiler flags to build mode cli.

@fkleuver
Copy link

fkleuver commented Sep 5, 2018

The thing is: there is nothing you're "protecting" users against by removing these flags right now anyway. You can simply override stuff in a single tsconfig file. That has always mapped directly to the cli flags, and I think that's how it should stay.

So keep it simple. Let the flags behave just as if it's normal build: only apply them to the build that is called directly. Should one need full control over how all the dependencies are built (which should be rare), simply walk the dependency tree yourself and call them in order with the appropriate overrides. Or just not use --build.

I for one don't care about the potential inconsistency with upstream dependencies. If I want to use the flags and something weird happens, that is my problem.

See my use case in #26763

@jquense
Copy link

jquense commented Nov 12, 2019

This is a frustrating situation to be in. We don't use typescript to actually compile code (we use babel) and it's seems very difficult to get a setup using project references that also allows building declaration files.

  • We can't use tsc -p . in a package b/c the composite: true means .d.ts files aren't output
  • We can't generate them via tsc -b without emitDeclarationOnly, which can only be set in a tsconfig
  • setting emitDeclarationOnly in a tsconfig means we can't run tsc --noEmit to typecheck

At this point i've got:

  • 1 root tsconfig setting up references
  • a base tsconfig with the reference compiler options and others
  • 2 tsconfig.jsons per package, one for type checking and one for building

It feels silly, And much of this could be avoided if tsc -b accepted the compiler flags, or had a "type checking only" mode

@dinofx
Copy link

dinofx commented Oct 22, 2020

Arguments like outDir and rootDir seem like they are generally local to a project being built. skipLibCheck seems different, as it is something that could be set in a base config that all of the projects being built extend. Maybe the composite tsconfig being "--built" could refernce a "base" config (that the project configs extend), and any "regular" flags passed get forwarded to that base config. (yeah, that does sound like a maintenance nightmare going forward)

@gh-andre
Copy link

gh-andre commented Apr 6, 2021

I came across of this issue while trying to set up an incremental build in Azure and it seemed like --build was the answer because the docs describe it as "smart incremental builds for TypeScript projects". However, it turns out that this is just an inaccurate description and the point of --build has nothing to do with incremental builds for a single project.

After failing to set up a build with --build and --outDir I experimented a bit with just using the usual --project and --outDir and it turns out that it it builds incrementally just fine and maintains the build state in tsconfig.tsbuildinfo, without having to use --build. Reading this thread and the docs again, I see that --build's point isn't incremental builds, but rather building multiple projects in a way that builds them in the correct order of their dependencies.

I wish TypeScript docs would be more technical and contained fewer things like "Don't worry about ..." and more of what those features actually do and how they interact. Maybe then docs would capture more clearly the intent behind some of those features. This also includes the TypeScript language docs.

Back to --build, being able to generate output in an arbitrary build directory is a requirement of any build pipeline. The --build feature is just not very useful without being able to choose where the output for those multiple projects goes to. Whether it sets some common root for all projects being built or uses some macros, there should be a way to choose the output directory using build pipeline machinery.

@BTOdell
Copy link

BTOdell commented Jul 21, 2021

To start, only boolean command line flags could be enabled to work with --build mode. And only flags that affect the emitted output files (not so much the type-checking settings).

Here are some initial command line options that could be supported in --build mode:

  • --declarationMap
  • --emitBOM
  • --emitDeclarationOnly
  • --emitDecoratorMetadata
  • --importHelpers
  • --inlineSourceMap
  • --inlineSources
  • --noEmitOnError
  • --removeComments
  • --skipDefaultLibCheck
  • --skipLibCheck
  • --sourceMap
  • --stripInternal

(I haven't verified whether all of these options currently don't work in --build mode, but I think they all should)

Supporting options such as --outDir is problematic because relative paths are allowed and they are resolved against the tsconfig in which they are defined. So, it doesn't make much sense to have a single outDir override for multiple tsconfigs in a project.

@MarcCelani-at
Copy link

I would love to see --skipLibCheck override with --build supported. It would make it much easier for us to enable skipLibCheck but to periodically test without (e.g. when someone changes a node_module version or adds a new dependency). skipLibCheck is a major (nearly 50%) wall time win for our project – minutes faster – and the fact that we aren't using it yet is blocking us from breaking up our project into more granular composite projects. See #45691

What can we do to help get this prioritized?

MarcCelani-at added a commit to MarcCelani-at/TypeScript that referenced this issue Sep 2, 2021
Summary:
Many large composite projects rely on skipLibCheck to improve build times.
However, skipLibCheck does introduce some risk that projects miss typescript errors
in new node module versions they install.

This is in response to Issues microsoft#45691, microsoft#25613, and microsoft#41185

Test Plan:
New tsbuild unit test scenario that tests overriding the skipLibCheck value with a flag.
Validated with verbose output that the actual build overrode the value in the tsconfig.json file.
@MarcCelani-at
Copy link

Is there any interest in making progress on this? I sent a PR for skipLibCheck a month ago and there haven't been any comments. It's beginning to get stale. Should I even bother rebasing?

@MarcCelani-at
Copy link

Hey folks. Wondering if this is something we can tackle as part of 4.6. I'd be happy to contribute here.

@jakebailey
Copy link
Member

Just to note it here, in the module-ified version of the TS compiler, I thought it would be nice to add a --unbundled flag to our build such that we could emit individual files if needed, but to do that quickly I'd want to run tsc -b ./src --emitDeclarationOnly=false to override the setting in tsconfig-base.json. My only current option seems to be creating a second set of tsconfigs and doing a bunch of inheriting and duplicating.

The list on #25613 (comment) looks pretty reasonable to me.

@ssalka
Copy link

ssalka commented Aug 25, 2023

Chiming in here that I'm currently unable to check the version when using --build. I suspect in my CI job I am getting the wrong TypeScript version installed due to other packages having a dependency on an older TS. Adding --version just outputs a log line, and doesn't change the actual build behavior at all, so I'm surprised I got an error when trying it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.