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

Support using --module and --outDir flags in conjunction with --build #26763

Open
4 tasks done
fkleuver opened this issue Aug 30, 2018 · 7 comments
Open
4 tasks done

Support using --module and --outDir flags in conjunction with --build #26763

fkleuver opened this issue Aug 30, 2018 · 7 comments
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript

Comments

@fkleuver
Copy link

Search Terms

--build --module --outDir

Suggestion

I would like to be able to pass --module and --outDir, in --build mode so that I can have multiple npm scripts for different build outputs without needing multiple tsconfig files.

Use Cases

In Aurelia vNext we've fully adopted the new 3.0 build system and are starting to prepare for publishing. We want to publish the build outputs for all different module systems (for all packages) so that consumers can easily point to the one that's compatible with their project.

We have been able to do this pre-3.0 like so:

    "build:commonjs": "tsc -m commonjs --outDir dist/commonjs",
    "build:amd": "tsc -m amd --outDir dist/amd",
    "build:system": "tsc -m system --outDir dist/system",
    "build:umd": "tsc -m umd --outDir dist/umd",
    "build:es2015": "tsc -m es2015 --outDir dist/es2015",

Now when trying to do this, it doesn't work:

    "build:commonjs": "tsc -b -m commonjs --outDir dist/commonjs",
    "build:amd": "tsc -b -m amd --outDir dist/amd",
    "build:system": "tsc -b -m system --outDir dist/system",
    "build:umd": "tsc -b -m umd --outDir dist/umd",
    "build:es2015": "tsc -b -m es2015 --outDir dist/es2015",
    "build:esnext": "tsc -b -m esnext --outDir dist/esnext",

Results in:

message TS6096: File (...)/packages/runtime/-m' does not exist
message TS6096: File (...)/packages/runtime/commonjs' does not exist

And nothing else happening. I read in the docs that only 4 particular flags are supported in conjunction with --build so it seems this is simply not implemented.

Examples

We'd like to have something like this in the packages package.json:

    "build:commonjs": "tsc -b -m commonjs --outDir dist/commonjs",
    "build:amd": "tsc -b -m amd --outDir dist/amd",
    "build:system": "tsc -b -m system --outDir dist/system",
    "build:umd": "tsc -b -m umd --outDir dist/umd",
    "build:es2015": "tsc -b -m es2015 --outDir dist/es2015",
    "build:esnext": "tsc -b -m esnext --outDir dist/esnext",
    "build": "run-p build:*",

And when calling npm run build from the top-level package (using lerna...), that would produce build outputs in all module formats for all packages

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript / JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. new expression-level syntax)
@raymondfeng
Copy link

raymondfeng commented Aug 30, 2018

My understanding is that these flags should be set by each referenced projects (in tsconfig). Think about a build that brings in more than one modules and it does not make sense to have a (global) CLI option.

@EisenbergEffect
Copy link

For an example setup, you'll need to look at the Aurelia Monorepo. We have a number of packages that we have to build with a single command, all of which need to output every format. Each package has the same configuration, but we now have to duplicate tons of tsconfig.files all over the place, 6 * NumberOfPackages. In our case, that's 36+ tsconfig files instead of 6. Each time we add a new package to our monorepo, we have to add 6 more copies. It's not good for maintenance in real-world monorepo setups.

@fkleuver
Copy link
Author

In the case of multiple module outputs per package, there is no functional difference between setting this in the tsconfig versus setting it in a cli flag.

Example setup

Consider the scenario with two packages package-foo and package-bar, and two different module outputs commonjs and amd

  • package-foo

    • No dependencies
    • tsconfig.json says "module": "commonjs"
    • tsconfig.amd.json says "module": "amd"
    • package.json says "main": "dist/commonjs/index"
  • package-bar

    • Depends on package-foo
    • The rest is identical

Build steps

Now we run tsc -b in package-bar, the following happens:

  1. package-bar sees the dependency on package-foo
  2. package-foo is built; output goes to package-foo/dist/commonjs
  3. package-bar is built, referencing package-foo/dist/commonjs; output goes to package-bar/dist/commonjs

Then we run tsb -b tsconfig.amd.json in package-bar, this happens:

  1. package-bar sees the dependency on package-foo
  2. package-foo is built; output goes to package-foo/dist/commonjs
  3. package-bar is built, referencing package-foo/dist/commonjs; output goes to package-bar/dist/amd

Result

package-bar, by all means and purposes, is fine now. The outputs are not combined, so the fact that the commonjs build outputs of package-foo were used to produce the AMD outputs of package-bar isn't noticeable in any way.

In a next sequential step we build package-foo in the same manner, and now we have both module outputs for both packages. Problem solved.

A consumer who needs the non-default module output would typically have the installation/configuration going through our cli which can make sure all packages are referencing the same module output.

The identical effect could by achieved by passing the cli arguments to tsc -b

@ikokostya
Copy link
Contributor

Related to #25613

@fkleuver
Copy link
Author

fkleuver commented Sep 6, 2018

@RyanCavanaugh I would be OK with closing this as a duplicate of #25613 if that makes things easier for you guys. Essentially my issue boils down to the same thing, it's just specific to some particular flags. Up to you

@RyanCavanaugh
Copy link
Member

@fkleuver thanks - I think these deserve separate issues since the "mixing" mode would probably naturally exclude per-project-computed things like outdir and rootdir. This scenario is complex enough to warrant its own behavior

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels Sep 17, 2018
@screendriver
Copy link

Just a side note because I have the same problem:

  • for my unit tests everything needs to be compiled to CommonJS because AVA just can handle that for running tests
  • for my webpack bundling after the tests the files should be in ECMAScript modules because it has more advantages there.

Now when I run tsc -b, run my unit tests over that and after that do a tsc -b tsconfig.esm.json for the webpack build, nothing changes in my output directory because I didn't touch any files so the type declarations stay the same. As a workaround I could introduce two different output directories. One for ESM and one for CommonJS but this feels a little bit hacky. Or, as I do it at the moment, completely ignore ESM and just compile to CommonJS all the time.

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

No branches or pull requests

6 participants