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

Flatten outDir structure when both of rootDir and rootDirs is specified #8245

Closed
alexeagle opened this Issue Apr 21, 2016 · 14 comments

Comments

Projects
None yet
3 participants
@alexeagle
Contributor

alexeagle commented Apr 21, 2016

TS@next: with a tsconfig.json like

        "outDir": "built/",
        // rootDirs for resolution of relative imports
        "rootDirs": [
          "src",    // for authored sources
          "codegen" // for generated code
        ],

and src/a.ts and codegen/a_gen.ts I end up with
built/src/a.js and built/codegen/a_gen.js.

I want an output structure that collapses the trees
built/a.js and built/a_gen.js
It seems like --rootDir might work, but

  1. try rootDir: src -> error TS6059 because all sources are expected to be under rootDir
  2. try rootDir: . -> no change in behavior

I would like some combination of rootDir and rootDirs that flattens the output tree.
cc @robwormald @tbosch

@mhegazy

This comment has been minimized.

Contributor

mhegazy commented Apr 21, 2016

rootDirs (and so are paths, baseurl, moduleResolution) do not have any effect on output. they are just ways to get the compiler to know what is the meaning of modules.

@mhegazy

This comment has been minimized.

Contributor

mhegazy commented Apr 21, 2016

i suppose it is not that far from what we do for rootDir. so we should be able to do it.

@alexeagle

This comment has been minimized.

Contributor

alexeagle commented Apr 22, 2016

given how close the names of the options are, it feels nice if rootDir: foo is equivalent to rootDirs: [foo]
thanks! this will help Angular 2 users a lot, I think.

@alexeagle

This comment has been minimized.

Contributor

alexeagle commented Apr 22, 2016

FYI for those following, the TS team has determined this is not a semantic they want to add, since it overloads this option. PathMapping was intended to allow design-time structure to match runtime structure, and this feature request doesn't follow that logic.

@vladima

This comment has been minimized.

Contributor

vladima commented Apr 22, 2016

Resolution: paths/rootDirs` were intended to be used only for module resolution purposes to remove mismatch between runtime and design time structure of the project and repurposing them will bring in lots of confusion.

@vladima vladima closed this Apr 22, 2016

@alexeagle

This comment has been minimized.

Contributor

alexeagle commented Apr 23, 2016

I just discovered that if you use

outDir: 'built',
rootDirs: ['src', 'does-not-exist']

then src/foo.ts will emit to built/foo.js. This is surprising if rootDirs is not supposed to affect the output structure. Re-open? File new issue?

@alexeagle

This comment has been minimized.

Contributor

alexeagle commented Apr 23, 2016

repro:

alexeagle-macbookpro2:repro_rootDirs_strips alexeagle$ cat tsconfig.json
{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "noImplicitAny": false,
        "sourceMap": false,
        "outDir": "built",
        "rootDirs": ["src", "does-not-exist"]
    },
    "exclude": [
        "node_modules"
    ]
}alexeagle-macbookpro2:repro_rootDirs_strips alexeagle$ cat src/a.ts
let v:string;
alexeagle-macbookpro2:repro_rootDirs_strips alexeagle$ ./node_modules/.bin/tsc
alexeagle-macbookpro2:repro_rootDirs_strips alexeagle$ ls
built       node_modules    src     tsconfig.json
alexeagle-macbookpro2:repro_rootDirs_strips alexeagle$ ls built
a.js
@alexeagle

This comment has been minimized.

Contributor

alexeagle commented Apr 23, 2016

oh, and there has to be at least one (possibly empty) file in the second of rootDirs:

alexeagle-macbookpro2:repro_rootDirs_strips alexeagle$ mkdir does-not-exist
alexeagle-macbookpro2:repro_rootDirs_strips alexeagle$ rm -rf built
alexeagle-macbookpro2:repro_rootDirs_strips alexeagle$ ./node_modules/.bin/tsc
alexeagle-macbookpro2:repro_rootDirs_strips alexeagle$ ls built
a.js
alexeagle-macbookpro2:repro_rootDirs_strips alexeagle$ touch does-not-exist/b.ts
alexeagle-macbookpro2:repro_rootDirs_strips alexeagle$ rm -rf built
alexeagle-macbookpro2:repro_rootDirs_strips alexeagle$ ./node_modules/.bin/tsc
alexeagle-macbookpro2:repro_rootDirs_strips alexeagle$ ls built
does-not-exist  src
@vladima

This comment has been minimized.

Contributor

vladima commented Apr 23, 2016

this is by design (cannot personally say that I like it) and can be reproduced even if you drop rootDirs from tsconfig.json. If rootDir is not specified compiler infers it as common subfolder for all files that are included in compilation. In first case there is only one file a.ts so rootDir will be inferred as ./src. In the second case common subfolder for ./src/a.ts and ./does-not-exist will be ..

@alexeagle

This comment has been minimized.

Contributor

alexeagle commented Apr 24, 2016

ah, right.
This becomes very important for the codegen case. If you have /src and /codegen under your project, then the first compilation occurs with an empty codegen directory, but a subsequent compilation has files in there, so the output directory shifts. On the third compilation, I get errors because of files in /src/codegen/src which have wrong relative paths.

Short answer is that rootDir is required when using rootDirs for the codegen case. The names are unfortunate, how do you explain what

"rootDir": ".",
"rootDirs": ["src", "codegen"]

means? They appear contradictory to someone who doesn't understand the flag meaning. But that's what we've got, so I'll document it.
Thanks again for all your help.

@vladima

This comment has been minimized.

Contributor

vladima commented Apr 24, 2016

I do agree that current setup can be confusing. rootDir was already shipped so renaming it will be a breaking change, however we still can change the name of rootDirs or make baseUrl, paths and rootDirs sub options of top level option moduleResolutionOptions so their purpose will be more clear (//cc @mhegazy ).

@basarat basarat referenced this issue Apr 24, 2016

Closed

Proposal: Modularize Library #6974

3 of 4 tasks complete
@alexeagle

This comment has been minimized.

Contributor

alexeagle commented Apr 24, 2016

Oh that would be amazing if you could have suboptions. Would that look like

"moduleResolution": ["node", {
  "baseDir": "..",
  "paths": {"angular2/*": ["../download/angular2/*"]},
  "rootDirs": ["src", "gen"]
}]

or something?

On Sun, Apr 24, 2016 at 4:33 AM Vladimir Matveev notifications@github.com
wrote:

I do agree that current setup can be confusing. rootDir was already
shipped so renaming it will be a breaking change, however we still can
change the name of rootDirs or make paths and rootDirs sub options of top
level option moduleResolutionOptions so their purpose will be more clear
(//cc @mhegazy https://github.com/mhegazy ).


You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub
#8245 (comment)

@alexeagle

This comment has been minimized.

Contributor

alexeagle commented Apr 24, 2016

not all of them can be expressed as options to the CLI so it doesn't seem
like a downside to express this way

On Sun, Apr 24, 2016 at 7:46 AM Alex Eagle alexeagle@google.com wrote:

Oh that would be amazing if you could have suboptions. Would that look like

"moduleResolution": ["node", {
  "baseDir": "..",
  "paths": {"angular2/*": ["../download/angular2/*"]},
  "rootDirs": ["src", "gen"]
}]

or something?

On Sun, Apr 24, 2016 at 4:33 AM Vladimir Matveev notifications@github.com
wrote:

I do agree that current setup can be confusing. rootDir was already
shipped so renaming it will be a breaking change, however we still can
change the name of rootDirs or make paths and rootDirs sub options of
top level option moduleResolutionOptions so their purpose will be more
clear (//cc @mhegazy https://github.com/mhegazy ).


You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub
#8245 (comment)

@alexeagle

This comment has been minimized.

Contributor

alexeagle commented May 1, 2017

FYI @mhegazy I'm working on the open-source version of our TS tooling for http://bazel.build - this is the first issue I'll need to workaround by creating a new "tsc_wrapped" for bazel to call.

alexeagle added a commit to bazelbuild/rules_typescript that referenced this issue May 26, 2017

Use a custom TypeScript compiler that maps output locations back to t…
…he shortest rootDirs.

Workaround for Microsoft/TypeScript#8245

Fixes #5

PiperOrigin-RevId: 157259036

@Microsoft Microsoft locked and limited conversation to collaborators Jun 19, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.