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

Support import maps #4

Open
djmccormick opened this issue Dec 9, 2020 · 7 comments
Open

Support import maps #4

djmccormick opened this issue Dec 9, 2020 · 7 comments
Labels
enhancement New feature or request

Comments

@djmccormick
Copy link

Support for aliases would make this tool useful in my project.

@jaydenseric jaydenseric added the enhancement New feature or request label Dec 10, 2020
@jaydenseric
Copy link
Owner

jaydenseric commented Dec 10, 2020

Interesting 🤔

Webpack opens a can of works because you can modify anything to do anything else via webpack config. Generally, I keep bundler config to a minimum and avoid clever aliasing and things so that tooling such as import path linting and this one doesn’t get confused.

What is your specific use case (a monorepo?), and what would be the ideal way this package could support it (as in, how would it work)?

There are probably quick hack ways, that would break down in a lot of situations.

We could sniff a webpack config file, and extract the resolve config and use enhanced-resolve when converting the import specifiers to absolute file paths in here:

https://github.com/jaydenseric/find-unused-exports/blob/v1.1.1/public/findUnusedExports.js

But, that is very fragile:

  1. Webpack can have an array of configs for multiple builds (e.g. server, browser, etc.), that could have totally different resolve config. We can only use one at a time, so do we do multiple passes, one for each config, and consider exports unused across all the builds to be unused?
  2. Webpack resolve config actually doesn't apply to every file in the project; it applies to files bundled by Webpack. You could have a script file for example in the project that doesn't get bundled at all, and it would be incorrect to resolve it's import specifiers using the webpack config. So how do you know what files are bundled by Webpack? Only webpack knows, and after building everything.

Probably the most efficient way to deal with the these problems is to use a webpack plugin to find unused exports; some already exist. Although, it is possible for a project file to be used by both bundled and non-bundled code, and an export could be unused according to the webpack plugin when in fact is is used by an seperate non-bundled script.

Moral of the story, stick to standards, don't be too clever with your build tooling, webpack config is the devil 😅

@jaydenseric
Copy link
Owner

Another thing to consider is that there are other bundlers than just webpack; an ideal solution would work for all users.

The "dumbest" approach would be to add an alias option, that accepts a hardcoded map. We could use cosmiconfig to load find-unused-exports config, since it's a map is a little unwieldy to pass in as CLI arguments. A user could potentially use the .js format for the config, and import their webpack config and manually extract the alias config from it and massage it to the find-unused-exports alias format (if we don't exactly match the webpack format), so that way the config is DRY and shared by both tools.

@Nantris
Copy link

Nantris commented Sep 14, 2021

This feature would be a huge help! I'm sure it's nightmarish to implement and support every edge case, but any sort of workaround would be great. We use aliases for some of our packages to facilitate importing based on the environment (Electron vs React Native for example.) Manually copying our aliases to something like a .unusedexportsrc file would be trivial compared with the benefits of this project.

Thank you for your hard work @jaydenseric!

@jaydenseric
Copy link
Owner

Thinking about this fresh, and especially after working with web standard import maps in browsers and Deno with JSPM, adding support for import maps is probably the best way forward.

I'm currently retooling from Node.js to Deno, so if import maps are relatively easy to add here there is a chance I will get to it in the course of doing client Node.js project work. Otherwise, I might leave it for a bigger Deno rewrite. A lot of things we're doing here are vastly easier in Deno (e.g. globs), but I'm not sure yet how much we want to stick with Babel as there might be better options in Deno land.

@Nantris
Copy link

Nantris commented Sep 17, 2021

Wow cool, I'd never even heard of import maps!

I won't pretend to understand the full difficulties of supporting aliases, but those sound like a really great approach.

As far as Babel support goes, my guess is that they'll end up supporting Deno since it's increasingly gaining traction. There's at least a hint that they might decide to support Deno in 8.x or above.

@jaydenseric jaydenseric changed the title Support aliases Support import maps Nov 5, 2021
@juanmagalhaes
Copy link

+1

My project uses create react app. At first it didn't work cause it was not seeing my babel config on the root folder. I added babel with preset react and the tool started to work but it wasn't taking the path alias into account. With CRA I'm using path aliases through jsconfig however, since I noticed this tool wanted my babel config to work I tried setting up aliases through babel config but it didn't work there.

My project would also benefit from alias support. Even if it is a dumb alias of some kind that we set it ourselves the config.

@himdel
Copy link

himdel commented Jan 13, 2023

👍 for a simple map,

I use aliases to anchor local imports to the module root, so you don't have to think about ../components vs ../../components.

(Webpack: resolve.alias = { src: resolve(__dirname, '../src') } , tsconfig: "paths": { "src/*": ["src/*"] }, imports ...from 'src/components')

Something like find-unused-exports --map='src -> ./src' would be enough for this use case.

(My workaround for now is

perl -i -pe 's/from '\''src\//from '\''..\//' src/*/*.*
perl -i -pe 's/from '\''src\//from '\''..\/..\//' src/*/*/*.*
perl -i -pe 's/from '\''src\//from '\''..\/..\/..\//' src/*/*/*/*.*

npx find-unused-exports --module-glob 'src/**/*.{js,ts,jsx,tsx}' --resolve-file-extensions 'tsx,ts,jsx,js' --resolve-index-files

perl -i -pe 's/from '\''\.\.\//from '\''src\//' src/*/*.*
perl -i -pe 's/from '\''\.\.\/\.\.\//from '\''src\//' src/*/*/*.*
perl -i -pe 's/from '\''\.\.\/\.\.\/\.\.\//from '\''src\//' src/*/*/*/*.*

)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants