3 ms·
All code is fast to write. Decisions like this should be optimized for reading and comprehension, not writing. IMO: Extreme opinions one way or the other don't
by 015a 4y ago
All code is fast to write. Decisions like this should be optimized for reading and comprehension, not writing.
IMO: Extreme opinions one way or the other don't work, and thus (most of the time) code-complete automation also doesn't work.
import { User } from "./User"; # is probably the most readable and comprehensible way to write this.
import { User } from "app/domain/users/types/User"; # is probably less comprehensible
import { User } from "../User"; # may be ok, but it may also depend on how deep this directory is, because
import { User } from "app/users"; # is actually pretty comprehensible
The point should be to make it really quick for readers to understand where this code is coming from. Imagine a situation where you've got identically named imports; like a
import { User } from "foo/db/types"; # used to schematize a user in the database
import { User } from "foo/api/createUser/types"; # used to schematize a component of the request body for creating users
Maybe the tokens themselves are named poorly, but look past that.
Many people find a specific file using, simply, CMD+P (or your editor's equivalent). There's no context for where they may be at; which inherently makes relative imports less comprehensible.
import { User } from "./User";
const u = new User(req.body.user); # but wait... what kind of user did I just create?
There are many ways to help alleviate this low state of comprehension; and what should be deployed is difficult to create hard-and-fast rules around because its so domain specific.
import { User } from "foo/api/createUser/types";
# having an import path like this can help, but maybe only in small files where the imports aren't 500 lines above where they're used.
import { User as CreateUserAPIUser } from "./User";
# aliasing imports is a good solution
import * as createUserApiTypes from "foo/api/createUser/types";
const u = new createUserApiTypes.User(req.body.user);
# importing, then properly naming, the entire module is in my experience an underutilized tool to help with comprehension.
- lelandfe 4y ago> what kind of user did I just create? Do y’all look at the import path at the top of a file to understand a function on line 450? Any editor I can think of provides a way to show what you’re using here. I don’t think import path intelligibility should really be that high on the list of concerns. > (most of the time) code-complete automation also doesn't work They’re pretty great these days, in my experience.
- 015a 4y ago> Do y’all look at the import path at the top of a file to understand a function on line 450? It depends on the language, the editor, and the development process. There's no one-size-fits-all solution. Regardless of all of that: code files are near their peak productivity when they can fit on-screen without scrolling, and when you can put all that aside and just immediately move your eyes from the token to the import path. And they're even closer to the peak when you can combine that with encoded contextual information about the import path (which is generally a reflection of what the token does) into the token itself; via, say, import aliasing or importing the module and accessing the token as a property on that imported module. The reality that we have thousand-line source files obviously isn't ideal. No one who has ever worked with one would say "this is the way the world should be". But, they exist, and thus we have tools like Intellisense to make them manageable, and they'd definitely be less comprehensible without those tools. That doesn't make the whole situation ideal, when talking in hypotheticals. We shouldn't admit defeat to the God of Complexity by saying, even in this small corner of good practices, "well, the comprehensibility of the import path doesn't matter because we gave up on making anything comprehensible a long time ago." > They’re pretty great these days, in my experience. I don't mean that they don't work in the sense that they don't produce compileable import paths. Though this is true in some languages, or some projects with bespoke configuration systems, or in some editors. I mean that they don't work because they don't oftentimes produce comprehensible import paths.
- lelandfe 4y ago> The reality that we have thousand-line source files obviously isn't ideal Cut that number by 2/3 and the situation is the same, right? How often are you working on files where the entirety of them fit on screen at all times… > well, the comprehensibility of the import path doesn't matter because we gave up on making anything comprehensible a long time ago I think they don’t matter because even modest complexity produces this situation. This isn’t a hypothetical, it’s the far reaching majority of real, practical code.