TypeStrong / grunt-ts

A grunt task to manage your complete typescript development to production workflow
https://www.npmjs.com/package/grunt-ts
MIT License
330 stars 121 forks source link

grunt-ts hangs for several minutes #315

Open nibblesnbits opened 8 years ago

nibblesnbits commented 8 years ago

I'm not sure if anyone else has had this problem, but for as long as I've been using grunt-ts, it has been hanging for several minutes every time I run the task. Unfortunately it's also intermittent. Occasionally it runs just fine.

When I use the --verbose flag, it stops at Verifying property ts.default exists in config...OK, and eventually continues. Is there another way I can debug this? I'm using version 5.2.0.

Thomas-P commented 8 years ago

Did you specify an input file via "src"? Otherwise it could hang. could you report your configuration?

nycdotnet commented 8 years ago

Hi @nibblesnbits - thanks for the report. We should probably take better advantage of the verbose switch and increase the logging to help diagnose this sort of issue.

Do you mind sharing the ts section of your gruntfile?

nibblesnbits commented 8 years ago
{
  default: {
    src: ["**/*.ts", "!node_modules/**/*.ts", '!typings/**/*.ts']
  }
}
nibblesnbits commented 8 years ago

Is there a way to step into the grunt-ts code while running it on my machine to see exactly where it's hanging up?

nycdotnet commented 8 years ago

Yes in the last section of the readme it describes it: "Quickstart for debugging Grunt plugins with Node Inspector".

I suspect you're running into an issue with your glob. Can you try changing the second one to "!node_modules/**" and let me know if you still have hangs? I think that excluding the .ts extension in the "not" still causes the globber to enumerate the files in node_modules everytime (even though there is nothing to be gained).

nibblesnbits commented 8 years ago

I've tried !node_modules/** and !node_modules with no change. I'll follow the debugging guide and see where I can get.

nycdotnet commented 8 years ago

OK thanks.

denisbabineau commented 6 years ago

@nycdotnet I realize this issue is old but I appear to be running into the same problem. It started happening after I added a new folder in my project that has deep paths and not an overly large number of files (~ 100) which is actually excluded. Here's a section of the callstack when it's hanging, glob goes probably close to a 100 frames deep:

image

Here is what the globsToResolve array looks like at the selected frame in tsconfig.ts:

[
"<path_to_project>/**/*.ts",
"<path_to_project>/**/*.d.ts",
"<path_to_project>/**/*.tsx",
"!<path_to_project>/node_modules/**",
"!<path_to_project>/bin/**",
"!<path_to_project>/unwanted_folder1",
"!<path_to_project>/unwanted_folder2/**",
"!<path_to_project>/new_folder_with_relatively_deep_paths/**"
]

and here is my tsconfig.json:

{
  "compilerOptions": {
    "outFile": "bin/js/main.js",
    "target": "es5",
    "sourceMap": true,
    "declaration": true,
    "removeComments": true,
    "experimentalDecorators": true
  },
  "exclude": [
    "node_modules",
    "bin",
    "unwanted_folder1",
    "unwanted_folder2",
    "new_folder_with_relatively_deep_paths"
  ]
}

it does seem to be related to your suspicion on glob but I still don't understand how reading a still relatively small folder would take so much time (in the range of 5 minutes)

denisbabineau commented 6 years ago

Adding to the above, in my case I have a symbolic link in subfolders of my new_folder that points back to the root of my project which appears to be causing recursion (although somehow at some point it's bailing out of it somehow).

My workaround is to explicitly define "include" patterns in favor of "exclude" in my tsconfig.json to avoid globing the top-level folder of my project altogether.

nycdotnet commented 6 years ago

Thank you for the detailed feedback. I wonder if that symbolic link could be the cause of the trouble, but if so, that folder should not be getting enumerated in the first place from what you're telling me. I really do appreciate you looking into this and providing that info - even going down the route of debugging it. I wonder if this is a matter of updating the globbing library we're on or something, because to me those globs should short circuit the excluded paths. If you run tsc -p, does your thing build as you want? If so, you might want to consider using the tsconfig pass through feature of grunt-ts, at which point you're mostly just using grunt-ts as a glorified process executor.

denisbabineau commented 6 years ago

running with tsc -p or with passThrough with grunt there is no hang so it does seem to be isolated to grunt-ts' handling (when not in passThrough mode).

When you look at grunt's file.expand (called via globExpander in addFilesToCompilationContext, see callstack above) it invokes a local function called processPatterns. Looking at the implementation there it indeed appears to be glob'ing all the explicitly excluded patterns to remove them from the set (instead of ignoring them before being added to the set). Perhaps a better approach might be to use glob's own ignore option passing it all the excluded patterns but I'm not sure what the implications on the .dot files would be as per their documentation or if this might actually just be doing the same thing under the hood.