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

Optimize tsc --w using the CoS builder #10879

Closed
normalser opened this issue Sep 12, 2016 · 15 comments · Fixed by #17269
Closed

Optimize tsc --w using the CoS builder #10879

normalser opened this issue Sep 12, 2016 · 15 comments · Fixed by #17269
Assignees
Labels
Committed The team has roadmapped this issue Fixed A PR has been merged for this issue Suggestion An idea for TypeScript

Comments

@normalser
Copy link

normalser commented Sep 12, 2016

It would be great if one could run tsc -w --eraseMode (or something similar) that would allow to simply erase the TypeScript annotations and hopefully generate js code quickly

Right now making tiny change in one file:

eg. console.log('test1') to console.log('test2')

triggers "recompilation" (even if incremental) - that takes some time and keeps getting slower as project grows

VScode already makes a great job with showing errors in a project - and I would be happy to have long (re)compilation with full errors to be part of build process - what I would prefer is ability to have 'instant' change reflection in generated js files

Related to: #10878

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels Sep 12, 2016
@thebanjomatic
Copy link

This is a tricky problem as changes in one source file can produce errors in other source file such as renaming a function in one file, and not updating the other files to use the new name. So at the bare minimum, you need to re-evaluate error checking in the other source files in the project. In other cases, such as as changing the values of a const enum, you also have to re-emit as well.

I recently wrote my own watch script using the language service API's and wound up writing both 'watch' and 'unsafewatch' tasks. The watch task does the recompilation ala tsc, and the unsafe version does the single file fast turnaround times like you are describing, at the expense of generating code that may or may not be broken.

To do this correctly, I believe the language service API's would need to expose a way to query the interfile dependencies based on which symbols are used and where they are defined. I didn't see anything exposed in the API along those lines when I was working on this, but I think it could be a welcome addition.

@jwbay
Copy link
Contributor

jwbay commented Sep 17, 2016

I think --isolatedModules would get you part of what you want. The docs for it aren't the clearest, but I think it essentially 'turns off' full-project typechecking and puts tsc into transpilation mode. I use it for fast compilation in webpack projects and rely on my IDE + CI server to catch compile errors.

@RyanCavanaugh
Copy link
Member

--isolatedModules is our most confusing flag. What it actually does is validates that your project can be safely single-file-transpiled. This means no using const enums, no use of unqualified value names in a merged namespace, etc.. It still performs a full typecheck to do this validation (it has to); a project that does compile correctly under this flag can be safely compiled under a faster transpile-only mode.

@RyanCavanaugh RyanCavanaugh added Committed The team has roadmapped this issue and removed In Discussion Not yet reached consensus labels Sep 28, 2016
@RyanCavanaugh
Copy link
Member

tsserver already knows how to do this correctly without a flag; we'll be moving the code from tsserver to tsc that can do this correctly for isolated modules

@mhegazy
Copy link
Contributor

mhegazy commented Sep 28, 2016

@zhengbli we will need to move the builder logic into program perhaps, and allow it to be used for both compile on save, and --watch.

@mhegazy
Copy link
Contributor

mhegazy commented Sep 28, 2016

also related #11229

@wclr
Copy link

wclr commented Jun 14, 2017

I believe this is a really important issue that influences DX daily, hourly, minutely, and not secondly, but firstly.

@jfstephe
Copy link

jfstephe commented Jun 29, 2017

@zhengbli @mhegazy @RyanCavanaugh - Hi guys, just wondering if there was an ETA on this please? Compile times are killing me...

@zpdDG4gta8XKpMCd
Copy link

zpdDG4gta8XKpMCd commented Jul 24, 2017

can't look at so many peoples suffering here:

        {
            "taskName": "quick transpile",
            "suppressTaskName": true,
            "showOutput": "always",
            "command": "node"
            "args": [
                "./node_modules/typescript/bin/tsc --target YOUR_TARGET_HERE --module YOUR_MODULE_HERE --noResolve --rootDir YOUR_ROOT_HERE_IF_NEEDED --outDir YOUR_OUTPUT_FOLDER_HERE_IF_NEEDED ${relativeFile}"
            ]
        }
  1. hook the above json into your tasks.json in .vscode folder, make sure to replace all *_HERE_* placeholders with something meaningful for your setup, add more or remove inapplicable, etc. you should know better
  2. assign this task a shortcut File -> Preferences -> Keyboard shortcuts:

image
add:

 {
     "key": "ctrl+q",
     "command": "workbench.action.tasks.runTask",
     "args": "quick transpile",
     "when": "editorTextFocus"
 },
  1. go to your TS file with changes and hit Ctrl + Q
  2. observe the following output
    image

so what just happened? why do i see these errors in the output?

no panic, we just transpiled the current file into JS ignoring all type checks, so we got our JS from TS lightning fast at the price of no gurantees of being correct assuming you know there were no errors

enjoy

@Ciantic
Copy link

Ciantic commented Sep 13, 2017

There is now babel-preset-typescript, that mostly erases just the types.

See: https://babeljs.io/blog/2017/09/12/planning-for-7.0 and https://github.com/babel/babel/tree/master/packages/babel-preset-typescript

Has anyone tried it yet? How fast is it?

@mhegazy
Copy link
Contributor

mhegazy commented Oct 3, 2017

The fix should be in typescript@next today. please take it for a spin and let us know if you are running into issues.

@mhegazy mhegazy added the Fixed A PR has been merged for this issue label Oct 3, 2017
@Serivy
Copy link

Serivy commented Oct 4, 2017

Like @Aleksey-Bykov we have a similar solution leaning on everyone's experiences to make a gulp watch task

Our typescript full compiles took around 18 seconds, incremental 15 seconds, but whatever visual studio 2015/2017 did it could produce the .js file in the time it took to refresh the browser. So we hooked up a watch to .ts files and compiled the single file.
An example of what we did is here if you're interested (Although it could use cleaning up and changing for your output):

// A experiment for quicker builds.
gulp.task('watch:typescript:quick', function () {
    return gulp.watch(files.tsFiles).on("change", function(file) {
        // Workaround to keep original folder structure
        var currentDirectory = path.dirname(file.path);
        var sourceDirectory = 'scripts';
        var index = currentDirectory.indexOf(sourceDirectory);
        var relativeDirectory = currentDirectory.slice(index + sourceDirectory.length + 1);
        var outputDirectory = __dirname + "\\scripts\\output"
        if (relativeDirectory) {
            outputDirectory = outputDirectory + "\\" + relativeDirectory;
        }
        var cmd = '"' + __dirname + '\\node_modules\\.bin\\tsc.cmd" --target ES5 --module AMD --sourceMap true --noResolve --outDir "' + outputDirectory + '" "' + file.path + '"';
        var startD = new Date();
        console.log(startD.toTimeString().split(' ')[0] + ' - File change detected. Starting incremental compilation...');
        exec(cmd, function (err, stdout, stderr) {
            if (stderr) {
                console.log("Command Failed: " + stderr);
            } else {
                var endD = new Date();
                console.log(endD.toTimeString().split(' ')[0] + ' - Compilation complete. Watching for file changes.');
            }
        });
    });
});

Obviously any errors are not reported and it does its best, so a full compile is needed at some point, but for incremental changes we wanted a quick turn around as possible like we can achieve in VS2017.

I will try out the changes to --w and see if it does what we need. Thanks

@myitcv
Copy link

myitcv commented Oct 18, 2017

@mhegazy and team - just to say, we upgraded today (now that the ImmutableJS type definitions have been fixed) and we're seeing some impressive speed improvements in --w mode.

Thank you very much!

@mhegazy
Copy link
Contributor

mhegazy commented Oct 18, 2017

thanks for getting back to us on this. glad we could make it work better for you.

The change was big, so i would not be surprised if there are issues. please feel free to reach out if you are running into any issues.

@Serivy
Copy link

Serivy commented Nov 6, 2017

We have switched to using it in production. Our watch builds are down from 14 seconds to 1-2 depending on how dependent the file is. Amazing work, looking forward to that api you say you will expose so other tools can use it too. Great Job.

@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.
Labels
Committed The team has roadmapped this issue Fixed A PR has been merged for this issue Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.