-
Notifications
You must be signed in to change notification settings - Fork 55
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
Match on files within top-level depedencies #344
Comments
I think it would be good to write some unit tests for findMatchingFiles.js and findJsModulesFor.js before adding this feature. |
So, for now. may I conclude that there is no way to |
Unfortunately, I think that's the case. I forgot to check back to this issue before releasing 2.0, so no fix was included. For lodash, you could depend on individual functions instead. For |
thx for help. Will wait for improvement |
@lencioni: do you still think this is an issue? Most packages I've come across export everything in the main file, and now that we have support for finding named exports from package dependencies it might not be an issue anymore. Having to reach in to packages like this seems like an anti-pattern. For instance, the react-router import { Link } from 'react-router';
<Link/> |
@trotzig I think this is going to be useful for a bunch of packages still, particularly component bundle packages like material-ui. Once tree-shaking becomes more mainstream it might not matter anymore, but until then I'd still expect a lot of packages to recommend importing files within the packages directly to avoid bringing in everything and bloating bundle sizes. |
By "bloating bundle sizes", I take it you mean webpack bundles for instance? That's a valid concern. It's a little tricky. I do think it's an anti-pattern, but one that's absolutely necessary in some cases. If you can think of ways to solve this within import-js, I'm all ears. The naive solution would be to reach in to every package dependency in search for modules and their exports. That's potentially expensive, so I've been avoiding that. In the meantime, I do think using aliases is a good-enough workaround. I expect projects to have a handful of these at most, at which point adding them to aliases isn't terrible. Let me know if that assumption is wrong though, there might be use-cases I'm not seeing. |
Yeah, or browserify bundles or whatever build tool you are using that doesn't do tree-shaking. If you used the named import from the main package without tree-shaking, you end up bringing in the entire package.
As one data point, material-ui seems to have at least 41 different "top-level" components that could be imported (I counted the directories starting with uppercase letters here https://github.com/callemall/material-ui/tree/master/src). We have an internal package that is structured like this that currently has 105, but it is changing all the time. Aliases aren't a great solution for us here.
What do you think about my idea in the original post?
Alternatively, we could add a configuration option to import-js that would point import-js at specific packages or even directories within packages to index and match on. |
Ah, sorry. Forgot about this. Yes, I like it. The
I like this too. Something like allowInternalModulesFor: ['react-router', 'material-ui'], I'm using "internal modules" here to match the eslint rule that disallows importing this way: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-internal-modules.md |
Yeah I don't think I've ever seen it actually used. But, using it might give people a reason to add it. |
As for |
What if instead of
Since |
includes is interesting, but how do you know which has precedence, includes or excludes? Would it be whichever has higher specificity? |
Yeah, that would be an issue. I guess the naive answer is to give |
Same as gitignore - includes always grabs filenames first, excludes always subtracts from that list. |
I've given this some more thought. Two things come to mind:
Given these two pieces of information, it seems that the right solution would be something simple. I think that adding an Some open questions: Should we scope the option to packages? e.g. packageIncludes: [
'my-package/foo/**',
] or should the option be more general? e.g. includes: [
'./node_modules/my-package/foo/**',
], If we keep it general, should we allow package includes to be specified without the |
It's a code smell if "node_modules" has to appear anywhere. If you want to support non-packages, I'd suggest two separate lists. I think the default case is that you'll want to be able to import any file in a direct dep - the glob approach is nice, but I'd want my configuration to be "always include every file in every direct dependency". How is that achieved with your suggestion, noting that |
Yes, I agree with this. I think the patterns in this config should understand
I'm not sure we need to support non-packages, but even if we did we could pretty easily achieve it in one list I think.
I'm not convinced about this. How often are folks importing deep files from their dependencies? My hunch is that most dependencies are imported for the The problem with making this look at all of these files by default is it can make the importing process unnecessarily noisy and frictioned since you are much more likely to end up with matches on files that you don't care about. For example, let's say I have a dependency on import moment from 'moment';
import moment from 'moment/moment';
import moment from 'moment/src/moment';
import moment from 'moment/src/lib/moment/moment'; We could probably try to be smart and remove anything that is also
On the flipside, let's say we included all files in direct dependencies by default. How would I exclude all files except for a specific directory from a package? e.g. I only want to include |
Every single person using lodash 5 and up will be importing deep files from it, for example, and not from within any directory. Certainly you'd want to filter out everything that's not in "main". Another approach could be, only show things that aren't required elsewhere, but that'd filter out real entry points too. As for I guess I'd expect the default to be "include all entrypoints from npm-installed modules", with the option to flip that, and then either an "exclude" or an "include" override list respectively, that was a hash keyed by module name, and with a value that's a list of patterns. |
Until this issue is solved, here's a workaround for material-ui imports. I added this option to my importStatementFormatter: (options) => {
// Adjust material-ui imports to avoid accidentally importing the entire
// material-ui bundle.
let stmt = options.importStatement;
const match = (
/import \{\s*([A-Za-z,\s]+)\s*\} from '@material-ui\/core';/.exec(stmt));
if (match) {
const names = match[1].split(',');
stmt = names.map((nameWithWhitespace) => {
const name = nameWithWhitespace.trim();
return `import ${name} from '@material-ui/core/${name}';`;
}).join('\n');
}
return stmt;
}, It seems to do the trick. |
Folks may want to import files from within packages they depend on. I think we need to include these files, or a subset of these files in the files that we match on. This may end up causing relevance issues, which we might be able to resolve with better ranking, with a stricter opt-in mechanism (see below), or both.
In #340 (comment) I mentioned:
I think we could start by adding this feature and allowing packages to opt in to having the files in their
directories.lib
directory be matched. We can always expand it later if necessary.I think we need to do this for 2.0, since we removed
lookupPaths
.The text was updated successfully, but these errors were encountered: