Skip to content

Write typescript as modules, but output js without modules #39446

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

Open
bjg2 opened this issue Jul 6, 2020 · 8 comments
Open

Write typescript as modules, but output js without modules #39446

bjg2 opened this issue Jul 6, 2020 · 8 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@bjg2
Copy link

bjg2 commented Jul 6, 2020

Search Terms

Searched the whole internet for anything like it, only webpack and browserify related 'solutions' are proposed.

Suggestion

Split module options in tsconfig so typescript modules could be set separately from output target modules.

Use Cases

Our usecase:

  • We have a huge codebase, and we want to slowly move to typescript.
  • We have a sophisticated build system that we don't want to change - we want typescript to transpile to js and to take js and continue to use it as we were.
  • We don't need nor want to use modules in js. We never used modules - we have our system of imports, minification,
    versioning, caching, etc.
  • The only reason why we need to use modules in typescript is tsc incremental watch build. With no modules, it builds complete codebase on each change. We want to build only file changed and dependent files.

So currently we have two bad options - don't use modules (unacceptably slow build time) or use modules (get the output that we don't want). Currently we 'mitigate' the issue by removing parts of js tsc has output (removing stuff we recognize as related to exports and require), but that's just terrible.

Even worse, even if we were to use modules, require / exports are inlined even in output we want to inline to index.html as critical JS...

Examples

I guess I explained it all above.

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. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • [ * ] This feature would agree with the rest of TypeScript's Design Goals.
@SupinePandora43
Copy link

typescript has outFile option, but it requires UMD/SYSTEM module resolution. nobody uses it, webpack used in most cases

@amcasey
Copy link
Member

amcasey commented Jul 7, 2020

TypeScript also supports incremental compilation of composite projects. For example, the compiler itself is broken into composite projects, but does not use modules. Maybe that would help?

@bjg2
Copy link
Author

bjg2 commented Jul 7, 2020

typescript has outFile option, but it requires UMD/SYSTEM module resolution. nobody uses it, webpack used in most cases

We want to have js built for each ts, next to the ts, and that ts used modules while js does not.

TypeScript also supports incremental compilation of composite projects. For example, the compiler itself is broken into composite projects, but does not use modules. Maybe that would help?

Well, not sure... Each project needs to have its own config file and we need to link all the projects? Then when one project was built whole dependent project is built, even though some are not changed? Then we need to think about projects and which groups to create as projects...

It seems that it complicates our usage significantly. Our use case is fairly simple - when one ts file is changed we want to build only that file and dependent ones, creating our own dependencies through projects instead of modules adds unneeded complexity...

To be a bit more precise - this is what we do:

  • tsc incremental watch all the files in our huge codebase
  • Write ts with modules and write export {...} at the end explicitly (explained later).
  • Set up tsc so it creates js next to the ts files
  • When js is output and about to be used by the rest of the build system we remove all the exports and requires from the file content. This is very error prone process, we're not really parsing js syntax but pattern matching strings. That's the reason why we write exports at the end of the file as mentioned - it generates js that is easier to clean... Also, this messes up sourcemaps a bit.

I guess we're not the only ones with this problem... tsc incremental watch works well for modules (and it is clear why, it has dependency data), ts code is clear with modules (you know where from are the references used), and all that is good related to ts. But there's no reason to imply that someone who write modules in ts wants them in js as well, since the aforementioned goodies are ts-only and not needed in the transpiled js.

@RyanCavanaugh RyanCavanaugh added Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript labels Jul 9, 2020
@RyanCavanaugh
Copy link
Member

This is likely not happening because this actually isn't all that common of a situation, and the solution here is already implemented in things like rollup, whose configuration docs show just how complicated this process is. It's not something we'd want to re-implement unless it was absolutely critical for a large number of people.

@anderejd
Copy link

anderejd commented Sep 29, 2020

This is my use-case, I have an OpenApi specification that is used to generate Typescript client code from. I would like to build this Typescript code into a single javascript file that is not a module and that can be imported into a Polymer 2 project using a simple script tag.

Edit: This Polymer 2 project may be upgraded to Polymer 3 or rewritten using some other framework, but that's not happening right now.

@johnnesky
Copy link

johnnesky commented Oct 9, 2020

I would also accept this as an alternative to my existing issue: #33206

The TSC compiler is just so close to being a great standalone compiler for outputting compact javascript for the web. There's just this frustrating requirement that you either use webpack/rollup or triple-slash-references.

EDIT: I closed my existing issue #33206 and I think rollup does what I want, but I still think it's a shame that rollup's functionality is only provided by the typescript compiler when using triple-slash references, and must be supplemented by the rollup package when using standard import syntax.

@zopsicle
Copy link

zopsicle commented Nov 8, 2020

Currently working on an Electron app and I’ve always used TypeScript’s namespace functionality together with --outFile, and it’s always worked great.

It would be amazing if I could keep this workflow but also import modules from Node.js standard library with require. I don’t need to make my own CommonJS modules, just import those that ship with Node.js or Electron. const fs = require("fs"); works but seems to be of type any which is unfortunate.

@MatthewPinheiro
Copy link

Just trying to keep this alive in 2023. The use case is there. In my case, I'm working in a more niche JS runtime (ServiceNow/Rhino) which doesn't use explicit exports, and so adding this in would definitely serve my use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

8 participants