Open alextes opened 7 years ago
There are a number of approaches people tend to use:
node_modules
: this approach means you use the default node require
algorithm, which is a good thing! However, managing symlinks across platforms and via git is very tricky to get right.package.json
and node_modules
in your entire project, at the root.Deviating from node's require
algorithm in any way makes your code harder to reason about, understand, and maintain. Additionally, if you have a ton of ../
in your project - that's a symptom of your project being too large - the solution is to make it smaller (by extracting things into separate npm-installed packages), not to sweep the problem under the rug by masking the dots.
Separating things out into different npm packages sounds like a huge pain. Even managing a couple of libraries is awkward, let alone having to manage your entire project that way. It also conflates external vs internal dependencies, which makes the project more confusing to maintain. (Is this something I can manage directly? Or is it something I have to go open an issue on somewhere?)
Saying a project is "too large" sounds like a bit of a subjective assessment. It's possible to have extremely large projects that are also well structured and maintainable, and there's nothing right or wrong about that. It depends on the needs of your team and the problems you're trying to solve. In our case, for the moment, it makes a lot more sense to make it easy to reason about where something is coming from and quickly make changes rather than adding the complexity of managing internal dependencies as npm packages.
For our part, we set a path to our project files using NODE_PATH
or within Webpack configurations using resolve: { modules: [...] }
. To make it clear what comes from our project vs an external dependency, we put all of project files in an src/
directory and prefix our imports with that:
import React from 'react';
import Blah from 'src/blah';
I've seen others use their project name or something as the prefix path, but we wanted something that's short.
External dependencies make projects easier to maintain - that's the point. You shouldn't be managing much directly - needing to do so is an indicator that things aren't properly encapsulated.
In my experience, no project that gets large enough ends up being well structured or maintainable - just "consistently structured" and "maintainable enough", which isn't the same thing.
The solution you're describing would be better achieved without NODE_PATH
or webpack aliases, but would be achievable with most of the above solutions.
You shouldn't be managing much directly - needing to do so is an indicator that things aren't properly encapsulated.
This doesn't make any sense. We have to manage the code whether we're putting it in external npm packages or inside our codebase directly. It's just a question of what the barrier is to actually managing it. Already when we're dealing with 3rd party dependencies it can be a huge pain to get bugs fixed and add new updates, so adding this additional overhead to managing our own code as well seems kind of wasteful.
In my experience, no project that gets large enough ends up being well structured or maintainable - just "consistently structured" and "maintainable enough", which isn't the same thing.
Your experience differs from mine, in that case. I've worked on a handful of large codebases where solid coding practices keep them maintainable and enjoyable to work in. And I've also worked in a number of codebases broken down into smaller packages that are a huge pain to work with as digging through layers of separation becomes a tedious and confusing process. Not to mention when you realize code belongs somewhere else it becomes that much more difficult to refactor.
Using babel-plugin-module-resolver
works great for me.
This is my .babelrc on a react-native project:
{
"presets": [
"react-native"
],
"sourceMaps": true,
"plugins": [
[
"module-resolver",
{
"cwd": "babelrc",
"root": ["./app"],
"extensions": [".js", ".ios.js", ".android.js"]
}
],
"transform-class-properties"
]
}
Being able to get rid of the dots for me is great because my front-end project structure is very flat, with folders for action-types
, actions
, selectors
, routes
, components
(reusable across the app), utils
, reducers
, styles
, anims
, normals
, and a couple more
But I know where every last dang thing is at any time, I know where to find it 👍
Of course another big benefit of ridding yourself of the ../
dots is you can copy and paste imports without hassle of redoing dots wherever it's pasted. To me that's a huge time-saver
Use import-js to automate that refactoring for you.
The dots belong there, and just because you might not need them, doesn’t mean other devs don’t.
Writing relative paths gets tiresome for big project trees. For example:
Is it okay to use globals, a module, or any other method to shorten the required path?