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

Suggestion: case-sensitive imports #21736

Open
ccorcos opened this issue Feb 7, 2018 · 29 comments
Open

Suggestion: case-sensitive imports #21736

ccorcos opened this issue Feb 7, 2018 · 29 comments
Labels
Effort: Moderate Requires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual". Help Wanted You can do this Suggestion An idea for TypeScript
Milestone

Comments

@ccorcos
Copy link

ccorcos commented Feb 7, 2018

TypeScript Version: 2.7.0-dev.201xxxxx

My mac does not have case sensitive imports. That is you can import the file x.js as ./X.js and everything will work. However, our servers run on linux (like most) and I got a runtime exception that took down the whole server because linux imports are case sensitive.

I think this would be an awesome addition to Typescript to prevent fatal mistakes that are hard to catch like this one.

Related Issues:

#14460

@mhegazy
Copy link
Contributor

mhegazy commented Feb 7, 2018

--forceConsistentCasingInFileNames should catch some of the scenarios involved here. it does not catch all of them though.

@ccorcos
Copy link
Author

ccorcos commented Feb 7, 2018

Oh interesting. I misunderstood what that meant. It doesn't stop you from creating a new file and importing it in a single place with the wrong case though.

@Jessidhia
Copy link

There actually is an option that can be given to the tsservice API (useCaseSensitiveFileNames: () => false) to make it be strict with those -- the problem is that it seems that, somewhere, internally, imports are converted to all lower case before they are resolved, which makes things impossible to compile.

@mhegazy
Copy link
Contributor

mhegazy commented Feb 8, 2018

@Kovensky there are two parts involved, the comparisons which is managed by useCaseSensitiveFileNames and the file system operations. ideally u want the lookup for a module with the wrong case to fail all the time, and not only on a case-sensitive file system. Ideally you want --forceConsistentCasingInFileNames to get fs.realPath and verify it does match the module name used to locate it.

@mhegazy mhegazy added Suggestion An idea for TypeScript Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature labels Feb 8, 2018
@mhegazy
Copy link
Contributor

mhegazy commented Feb 8, 2018

I should add the reason why we did not do that is realPath has negative perf implications.

@ccorcos
Copy link
Author

ccorcos commented Feb 8, 2018

I see. Well it sounds like you guys know what you're doing 👍

It looks like a decent performance hit everywhere I've checked. There's a webpack plugin but it makes several calls to the filesystem:

https://github.com/Urthen/case-sensitive-paths-webpack-plugin/blob/master/index.js

I'm not sure how the TypeScript internals work, but it seems like the performance hit wouldn't be too bad if it were a compile-time check on the import statements rather than actually forcing an error on importing the file. At the very least, we can document it and improve it over time.

@tomgruner
Copy link

Can I upvote this issue?

I spent hours trying to figure out why my TeamCity build was failing only to realize that the project had some imports that were the wrong case!

Quite an unexpected gotcha as I thought OSX would not import the file if it was the wrong case.

@brandonaaskov
Copy link

Just to echo the others here, we were able to run our codebase locally on our macs but it fell over on Heroku because of the wrong casing for the filename, which wasn't obvious and continues to be something we have to keep a keen eye out for (aka old school linting).

@briandesousa
Copy link

Similar experience here with a build succeeding on Windows 10 and failing on RHEL 7.6 with a "Cannot find module" error. Took a while to figure out it was a case error on the import. I also tried using the forceConsistentCasingInFileNames setting in my tsconfig.json but it did not catch this.

@vcfvct
Copy link

vcfvct commented Mar 14, 2019

Same here. We have similar issue when using decorators where Reflect.js is case sensitive. Our Type-Graphql keeps complaining duplicated Types registered. Spent several hours finding out it is due to the import which has a uppercase but still compiles.

@shaunluttin
Copy link

shaunluttin commented Apr 22, 2019

I should add the reason why we did not do that is realPath has negative perf implications.

Make it opt-in with a flag like enforceCaseSensitiveFileSystemWithSlowerCompilerPerformance.

@joshghent
Copy link

joshghent commented Jun 25, 2019

Had this issue a lot lately since we build locally which works and then attempt to build in docker which fails. A flag or something similar that would catch these scenarios would be ideal 👍Is the actual issue here that there is a bug with forceConsistentCasingInFileNames not catching everything?

@RyanCavanaugh RyanCavanaugh added Help Wanted You can do this and removed Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature labels Jul 24, 2019
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Jul 24, 2019
@RyanCavanaugh
Copy link
Member

Did some research here while working on the new Handbook and it looks like the fs.realpath performance problems were addressed in Node 6.0.0. TypeScript technically supports >= 4.2.0 but we're OK very slightly slowing down people on ancient Node builds for the sake of having this option behave in a more reasonable way.

Accepting PRs to have this flag result in checking the disk casing against the user-specified casing. Please test the living daylights out of your change as this stuff tends to be really hard to get right.

@demian85
Copy link

demian85 commented Aug 6, 2019

Any news on this?
In my case, the problem is that we have a folder dashboard and a file Dashbboard.tsx, an import references the folder but TS is looking for the file, why is that? is this a TS or MacOS problem?

@RyanCavanaugh
Copy link
Member

@demian85 can you open a new issue describing that in more detail? Thanks!

@OLDIN
Copy link

OLDIN commented Aug 6, 2019

Is there any news about this?

@rmehlinger
Copy link

I have also been bitten by this very silly behavior.

@shriharip
Copy link

I was bitten by this very time consuming bug :(

@WinjayYu
Copy link

I spent dozens of minutes to find why my Mac all goes well but failed in linux jenkins unit test.

@demian85
Copy link

I know this doesn't solve the problem, but wanted to share my opinion.
I'm starting to realize that kebab-case is a very good naming strategy for files. It would avoid these problems. Maybe most of JS devs like me do not like the idea because so many years of using camelCase/TitleCase, but things changed lately with Typescript. You get autocomplete feature out of the box. Why would I name the file the same as the class or component I'm exporting? Looks like Java to me. Also, all lowercase is clearer, much more easy to read.

@yuyujulin
Copy link

Still no updates yet? Same issue here, damn, we took a long time to figure it out.

@DanielRosenwasser DanielRosenwasser added the Effort: Moderate Requires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual". label Jan 16, 2020
@Kingwl
Copy link
Contributor

Kingwl commented Jan 13, 2021

I'd like to work on this.

@Kingwl
Copy link
Contributor

Kingwl commented Jan 13, 2021

Hey folks. Seems forceConsistentCasingInFileNames is working fine?
image
image

@emptygalaxy
Copy link

I think the problem is importing external modules with different casing and not just internal references to specific files.

@yaneek
Copy link

yaneek commented Mar 17, 2021

@Kingwl its external module imports (for example import MuiLink from "@material-ui/core/link";), and forceConsistentCasingInFileNames: true does not help, imports are still case insensitive.

@Kingwl
Copy link
Contributor

Kingwl commented Mar 18, 2021

Oh. Well Okay. Got the point.

@vprasanth
Copy link

kebab-case ftw. I had low priority PR up for over 2 months -- the issue was the build passed locally (OSX) but failed within the container. We of course took a look at, scratched our heads, and moved on to more important things. This evening I finally spent some time on it .. just wow is all I can say. Unix kids are laughing right now.

@MarekZhang
Copy link

forceConsistentCasingInFileNames does not work for importing from external lib.

// should be 'koa-bodyparser'
import bodyParser from 'koa-bodyParser'

works well on my Mac but failed in my linux CI/CD test.

@Inviz
Copy link

Inviz commented Jan 13, 2023

I have a strange issue that i forceConsistentCasingInFileNames complains on path, but the discrepancy is not on the level of the project, but way higher up:

 '/Users/sitecore/Sites/feaas-components/node_modules/@ctrl/tinycolor/dist/public_api.d.ts' differs from already included file name 
 '/users/sitecore/sites/feaas-components/node_modules/@ctrl/tinycolor/dist/public_api.d.ts' only in casing.

Why would my username on mac os be lowercased on one path and not in another?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Effort: Moderate Requires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual". Help Wanted You can do this Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests