import-js icon indicating copy to clipboard operation
import-js copied to clipboard

"includes" configuration option to add other sibling source roots?

Open indigoviolet opened this issue 6 years ago • 13 comments

In our set up, we have a 'shared' directory that applies to multiple of our "apps"

something like,

root/shared
root/apps/web
root/apps/dashboard

and we use Webpack to resolve across these directories.

How would I convince import-js to look in these other locations? Would it make sense to add an includes configuration option analogous to excludes?

indigoviolet avatar Jun 19 '18 19:06 indigoviolet

and we use Webpack to resolve across these directories.

Can you explain what this means? For instance, what does an import look like from lets say root/apps/dashboard/foo.js to root/shared/bar.js?

trotzig avatar Jun 19 '18 19:06 trotzig

The import looks like

import bar from 'shared/bar'

Then, somewhere in our Webpack config we have

resolve: {
  modules: ['./node_modules', './shared']
}

indigoviolet avatar Jun 19 '18 19:06 indigoviolet

Okay, cool.

Is import-js picking up exports from the shared folder and just making the imports look weird? Or are they not found at all? I'm asking because if the import statements are there but wrong, you might be able to solve this with the moduleNameFormatter configuration option: https://github.com/Galooshi/import-js#modulenameformatter

trotzig avatar Jun 19 '18 19:06 trotzig

Oh, wait. Maybe there is a package.json in each of the apps folders? That would make import-js stop there when searching for imports.

trotzig avatar Jun 19 '18 19:06 trotzig

They aren't found at all, and yes, you're exactly right - there is a package.json in each of the apps folders. That's why I'd like to explicitly tell import-js about the other folders it should look in.

indigoviolet avatar Jun 19 '18 19:06 indigoviolet

I understand the issue. Having an includes config option which would allow sibling projects to be searched could be a little tricky because the file watcher we use (watchman) needs a common root. I'm not saying it's impossible though, just that it would require some work.

One workaround I can think of is to try adding symlinks inside the different apps folders. If I'm not mistaken, watchman will traverse symlinks as well.

trotzig avatar Jun 19 '18 19:06 trotzig

Cool, I'll try the symlinks option and report back.

Re: watchman's requirement for a common root, is it necessary to watch the sibling projects? Could it work with the assumption that changes to the sibling directories requires a restart of the daemon?

Thanks for being so responsive!

indigoviolet avatar Jun 19 '18 19:06 indigoviolet

I guess that would work given that we document it properly with the potential addition of includes.

trotzig avatar Jun 19 '18 20:06 trotzig

Unfortunately the symlinks approach does not seem to work.

I verified that it does work when I copy the directory instead of creating the symlink.

It doesn't look like watchman supports symlinks completely: https://github.com/facebook/watchman/issues/105

~However one of the suggestions in that thread (https://github.com/facebook/watchman/issues/105#issuecomment-296390118) which causes 'shared' to mimic a node_modules package did work for me.~

indigoviolet avatar Jun 19 '18 21:06 indigoviolet

Actually I think I was mistaken about the node_modules hack - I still had the copied folder in scope. Doing the test correctly shows that the symlink approach doesn't work at all for me.

Just documenting a version of the copying hack for future reference:

You could use https://github.com/wix/wml to do

wml add shared app/shared wml start

Add app/shared to .gitignore

indigoviolet avatar Jun 19 '18 22:06 indigoviolet

Interesting, thanks for trying it out. I recently worked in a project which made use of Lerna (https://github.com/lerna/lerna) and import-js was able to resolve imports across sibling packages. And if I'm not mistaken, Lerna uses symlinks to "bootstrap" package dependencies.

Ninja edit: I just realize in a Lerna setup the "shared" packages are listed as dependencies in package.json. When import-js resolves imports from package dependencies, it doesn't use watchman. It simply grabs exports directly from the index file pointed out in e.g. node_modules/shared-package/package.json.

Another way to solve the problem you have could be to allow the watchman root to be overridden in config. I'd be happy to review a PR exploring a solution.

trotzig avatar Jun 20 '18 20:06 trotzig

I think that one difference from the lerna setup is that our sibling root is not a package -- it isn't exporting everything from under it in an index file. Since #344 is still open, my guess is that this approach won't work without adding a burden of changing the exports.

indigoviolet avatar Jun 20 '18 23:06 indigoviolet

I was looking for a somewhat similar solution, with this kind of monorepo structure (Meteor environment):

/project
  /meteor-packages
    /package1
    /package2
    /package2
  /app1
    /packages
       /package1 *symlink -> ../../../meteor-packages/package1*
  /app2
    /packages
       /package2 *symlink -> ../../../meteor-packages/package2*
  /app3

Each app has it's own package.json and therefore it's own .importjs.js config.

To use ImportJS with the Meteor packages, I have to temporarily move the package directory over to one of the app folders, run the batch ImportJS command, then move the package directory back to /meteor-packages.

arggh avatar Mar 24 '19 09:03 arggh