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

tsc doesn't output proper file case on Windows 10 #15129

Closed
jednano opened this issue Apr 11, 2017 · 22 comments
Closed

tsc doesn't output proper file case on Windows 10 #15129

jednano opened this issue Apr 11, 2017 · 22 comments
Labels
External Relates to another program, environment, or user action which we cannot control.

Comments

@jednano
Copy link
Contributor

jednano commented Apr 11, 2017

TypeScript Version: 2.2.2

Code

irrelevant

Expected behavior:

On Windows 10, compiling Foo.ts writes a file named Foo.js to output folder.

Actual behavior:

If foo.js (lowercase) already exists in output folder, the new file contents of Foo.ts are written to foo.js, but the file name's case doesn't change.

This issue just bit me in the real world on the EditorConfig vscode extension.

Workaround

Deleting foo.js and running tsc again solves the problem; though, this is not ideal.

vscode

@smac89
Copy link

smac89 commented Apr 12, 2017

Isn't windows case insensitive when it comes to files?

So foo.js == Foo.js == fOO.js == FOO.js?

This makes sense why it doesn't create a new file, because it sees that a file with the same name already exists...so it simply overwrites it

@jednano
Copy link
Contributor Author

jednano commented Apr 12, 2017

@smac89 yes, I realize that, but it seems pretty important for the tsc compiler to "somehow" ensure the generated .js files are the correct case, consistent w/ the source .ts files. If not, other people will run into the same issue I just had to deal with, where Linux users are the only ones that are getting errors.

@mhegazy
Copy link
Contributor

mhegazy commented Apr 19, 2017

The compiler does not do any thing special here. this is the node fs apis on windows

c:\test>node
> const fs = require("fs");
undefined
> console.log("Foo.js first");
Foo.js first
undefined
> fs.writeFileSync("./Foo.js", "a");
undefined
> fs.writeFileSync("./foo.js", "a");
undefined
> console.log(JSON.stringify(fs.readdirSync("./"), undefined, 2));
[
  "Foo.js"
]
undefined
>
> fs.unlinkSync("./Foo.js");
undefined
>
> console.log("foo.js first");
foo.js first
undefined
> fs.writeFileSync("./foo.js", "a");
undefined
> fs.writeFileSync("./Foo.js", "a");
undefined
> console.log(JSON.stringify(fs.readdirSync("./"), undefined, 2));
[
  "foo.js"
]
undefined
>

@mhegazy mhegazy added the External Relates to another program, environment, or user action which we cannot control. label Apr 19, 2017
@jednano
Copy link
Contributor Author

jednano commented Apr 19, 2017

Thanks @mhegazy! I posted an issue at nodejs/node#12521.

@jednano jednano closed this as completed Apr 19, 2017
@jednano
Copy link
Contributor Author

jednano commented Apr 19, 2017

@mhegazy the Node.js ticket has been rejected as a Windows issue. I realize Windows has been like this, probably from the beginning, but do you think there's any chance this could go up the ladder at Microsoft? Not sure where to file the issue at this point.

@RyanCavanaugh
Copy link
Member

Everything in Windows works the way it does to avoid breaking decades of backward compatibility. Zero chance this is changeable.

@jednano
Copy link
Contributor Author

jednano commented Apr 19, 2017

Thanks @RyanCavanaugh. If that's the case, I think this remains a TypeScript issue. I just did a little test and it turns out that the following works as expected:

fs.writeFileSync('Foo.js', 'bar');
fs.renameSync('Foo.js', 'foo.js');
fs.readdirSync('.');
[ 'foo.js' ]

The issue here, of course, is that it makes an assumption that the file already exists. I see two ways to solve this problem:

  1. First, check if the file exists, using fs.exists.
  2. Wrap the rename method in something like an _.attempt so that it fails silently.
  3. Do a try...catch and ignore the error.

Would the TypeScript team be open to any of these options?

@jednano jednano reopened this Apr 19, 2017
@RyanCavanaugh
Copy link
Member

It seems like overkill to slow down every single build for the sake of not having to run npm run clean or whatever, once, when you change file casing in the extremely rare case where it actually matters.

@jednano
Copy link
Contributor Author

jednano commented Apr 19, 2017

I guess we're OK with tsc Foo.js -> foo.js then, as an edge case.

@jednano jednano closed this as completed Apr 19, 2017
@sam-github
Copy link

You don't have to rename the file, just always do this:

var file = ...;
fs.unlink(file, function() {
  fs.writeFile(file, ...);
});

Doing an unlink should be fast, and then the output case will be what is expected.

@jednano
Copy link
Contributor Author

jednano commented Apr 20, 2017

@sam-github it's still an extra step. If it takes only an additional nanosecond, it sounds like they don't want it to accumulate for an edge case.

@JesusTheHun
Copy link

Dev: So basically, a code compiled on WIndows won't run on Linux because it will try to require the wrong file name, for exemple.
TypeScritp team : meeeeeh, don't care.

Gj guys. Then wonder why dev doesn't give a damn about Microsoft products.

@mhegazy
Copy link
Contributor

mhegazy commented Jan 11, 2018

--forceConsistentCasingInFileNames should flag some of these scenarios.

@jednano
Copy link
Contributor Author

jednano commented Jan 11, 2018

@mhegazy that flag is not at all related to this issue, as it only pertains to the import statements within the source code. This issue is more about the casing of the file names on the actual operating system / file system.

@mhegazy
Copy link
Contributor

mhegazy commented Jan 11, 2018

that is why i said "some" and not all.

@JesusTheHun
Copy link

This issue is more about the casing of the file names on the actual operating system / file system.

Handle it in the software then. Excuses never made good softwares.

@jednano
Copy link
Contributor Author

jednano commented Jan 11, 2018

@mhegazy there is only one scenario in this issue and --forceConsistentCasingInFileNames has nothing to do with that scenario. What scenario(s) are you talking about?

Microsoft team says it's Node's fault. The Node.js team says it's Windows' fault. Nobody takes ownership of the issue; thus, the issue is never resolved.

I think the compiler should always produce the same result, just like a pure function. Given the same input, I should always receive the same output. Unfortunately, this is not the case with the TypeScript compiler if the compilation folder already has js files in it. This is a side effect and should be fixed, if not by default, then with a compiler flag. The input is the same, but the output directory is not. That shouldn't make a difference!

@jednano jednano reopened this Jan 11, 2018
@gcnew
Copy link
Contributor

gcnew commented Jan 13, 2018

This is how case insensitive systems work and I'd argue it is to be expected. My advice would be to always clean before building or use a case sensitive system. Either way, it's not TypeScripts fault and should not be handled by the compiler.

@JesusTheHun
Copy link

JesusTheHun commented Jan 14, 2018

At the end of the day I only see two output : will I be able to use TypeScript without pain or not ?
The answer is yes only on a non-Microsoft system. For a software developed by Microsoft. Do you get it ?

Also, people want you to handle this issue. Just handle it. Why wouldn't you ? Windows is not gonna become case sensitive tomorrow, and we will

never

run a clean before each compilation. So you are the only one who can fix this.

I'm sending this to twitter, because you really behave like kids. You should be ashamed of yourself.

@gcnew
Copy link
Contributor

gcnew commented Jan 14, 2018

@JesusTheHun I'm not sure what has triggered you. I'm just a community member that shared their opinion.

The only thing that's shameful is your attitude and sense of entitlement.

@JesusTheHun
Copy link

OK I thought you were a TypeScript developer. As a community member too indeed I'm entitled to make the proper development happen. And refusing to resolve an issue that does belong to you, simply because no one else can resolve it, is not the proper development.

@typescript-bot
Copy link
Collaborator

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@microsoft microsoft locked and limited conversation to collaborators Jul 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
External Relates to another program, environment, or user action which we cannot control.
Projects
None yet
Development

No branches or pull requests

8 participants