Ember-auto-import 1.0 released

ember-auto-import 1.0 is released.

  • zero-config import from NPM.
  • works in every ember-cli version backward to at least 2.12 and forward to the 3.2-beta series.
  • can be used in both apps and addons
  • deduplicates correctly across all addons and the app itself.
  • incremental rebuild cost is nearly zero when you aren’t changing any imports.
  • powered internally by webpack, which gives us pretty solid compatibility with a large fraction of all NPM modules.

I released “1.0.0” because I believe the public API is stable (it’s very narrow), and because we’ve had quite a bit of helpful testing by early adopters. From here out expect compatible patch releases as we get wider testing and more bug fixes.

20 Likes

It seems that this is compatible with future visions (of imports “just working” without extra ceremony), even though the specific implementation may change over time. When do you think that we should propose shipping this in ember-cli by default?

I think we should do it now…

8 Likes

The only part that I wouldn’t consider totally future-safe is that I give people an escape valve for tweaking the webpack config, and if we switch to an entirely different implementation that won’t carry over.

I should add that it’s also not working under ember-cli master right now – the packager changes take away the particular timing in the build pipeline I was relying on, and don’t actually add a good extension point I could use instead. I’m also still looking into Preprocessor regression in master · Issue #7882 · ember-cli/ember-cli · GitHub because it’s feeding ember-auto-import bad data (addons are allowed to use import in addon-test-support, and we should see those as coming from the addon, not from the app, otherwise we can’t properly look up the right NPM package).

Should we also consider an upgrade to or replacement of ember-cli-cjs-transform that works this new way i.e. using webpack rather than broccoli-rollup?

As to including by default in ember-cli, I would be against so long as it doesn’t ship with an empty whiltelist. I do not want it including any dependencies in my app client by default. Most of my dependencies in every app I have should not be shipped to the client.

Of course, that means it wouldn’t be zero config, which may defeat the point of the addon as written. :slight_smile:

I have heard this objection from others too, and I would like to understand it better.

In what scenario do you get an import you don’t actually need? If somebody is typing “import x from ‘y’” in your app, you’d rather that breaks instead of importing the y package from npm? How is breaking better?

I am getting the impression that people think “auto-import” means that it will add all code from devDependencies to your build.

I am under the impression that it just makes ES2015 imports work from packages that exist in your node_modules. So if you never actually import the code in a specific file, it is never included in your build.

I still think my impression is correct, but if others think it has the former behavior, that may be where the objections are coming from.

So, yes, my app sizes are far too big already, so for example if I add to my app:

import moment from ‘moment’;

and moment happens to be a dependency already because I was using it in node, suddenly all of moment is added to my app and shipped to the client, and I didn’t even realize that my build file size changed. I want to know that I did that, and specifically approve it. Getting an error and then adding it to a whitelist accomplishes that. Plus I can read a PR and ‘know’ the new dependency got added and shipped, whereas I might have assumed moment was being shipped to client already.

I realize that this is a great convenience for new users, and I’m not in any way opposed to the addon’s current default behavior. The more I look at it, the more I’m impressed with your addon and your work. I just don’t want it to be a default that suddenly got added the next time I ember-cli-update.

If anything, my objection is that your addon is just too “auto” for large apps.

Ah, I can see what you mean. The biggest usability difference is that you can’t necessarily tell just by looking if you’re the first person to import that module, or if it’s already included. And adding a new one is a bigger deal that should get extra scrutiny.

Might make a nice eslint rule, like no-unapproved-imports. That would let you continue to enforce the rule even if the import implementation changes.

2 Likes

I don’t think handling these “unapproved imports” is part of ember-auto-import or future ember-cli. That’s your responsibility about your code. If it’s becoming messy or hard to discover than write your monitoring tools to handle them or as @ef4 suggests a linter rule, anything like that.

1 Like

I think a linter rule would be a great alternative if for some reason whitelisting is difficult to add as an option.

However, I would prefer a whitelist because I would get an error at build time rather than when I run tests. I don’t think it should be hard, may I go ahead and write a PR?(I’ve opened an issue.)

@gossi Sure I can write my own. And yes, my code is my responsibility. But this is Ember, and we believe in shared solutions to common problems. I’d prefer to write something we can all use and can be built into the addon, if we can reach a consensus.

Done well it’s not super simple.

It needs to be scoped per package (you don’t want to need to update your whitelist just because an addon chose to auto-import a new library). Which sounds like it’s a normal thing all addons do, but ember-auto-import works pretty hard to run a single shared global instance, so that builds have holistic deduplication.

And it needs to be scoped per bundle (approving a package for use in tests is not the same as approving it for use in the app). Right now app and tests are the only bundles, but I expect that to grow to be dynamic as we keep up with other advances in code splitting.

So I’m hesitant to implement a lot of policy that could be implemented cleanly as a separate lint rule addon, where some of these problems wouldn’t even exist (like scoping per package, because lint rules are already scoped per package).

1 Like

Ok, fair enough. Clearly a final solution requires more thought. I’ll do some more thinking.

But my first thought is that I do want to know and approve if an addon auto imports a new package. Bundle download size is that important.

And now that I think about it, I’m not sure I can do that with a lint rule.

As for tests, I’m much less concerned if a package is added to the tests bundle, so maybe we don’t bother with that in the first PR and fix it in the next one?

I actually compared bundle size before and after I switched to ember-auto-import just be sure I did not ship a lot more to users all of the sudden.

So I understand the concern of others about bundle size.

I think the problem is the reverse: the naive solution would be one that doesn’t distinguish between the bundles. But that would mean you would need to put test-only deps into your single whitelist, and then you wouldn’t notice if they snuck into the app bundle.

Yeah, I think if one really wants to keep close control over the bundle size on a large team, they should consider setting a size limit that is just a tiny bit over the current size, and fail CI if it goes over. Then any proposed changes that increase the bundle size will be required to say so explicitly, because you’ll see them editing the maxBundleSize setting.

This has the benefit of catching lots of things other than just extra auto-imports.

1 Like

I agree, and do this. However, it doesn’t answer the question of why the file size increased, requiring us to hunt it down. Plus it is rarely if ever is lowered in practice. :slight_smile:

More importantly, it doesn’t really give us a way to solve the problem if it is being caused by an unintended auto import.

Where can I find more information on this maxBundleSize config?

I don’t think anyone’s made an easy to use addon.

I just wrote some quick and dirty code for leveraging ember-cli/asset-size-printer.js at master · ember-cli/ember-cli · GitHub

1 Like

Maybe post a gist? We won’t judge :sunglasses:

When do you think that we should propose shipping this in ember-cli by default?

Shipped by default as an addon but it could be removed, yes? I need more time to dig into it, but adding this addon to our large-ish app causes our vendor build to increase in size by almost 20%.

Yep, absolutely!

ember-auto-import does utilize broccoli-debug to aide in these sorts of situations, you can turn that debugging on via:

BROCCOLI_DEBUG=ember-auto-import:* ember b

Then look in DEBUG/ember-auto-import/ to get an idea of what is going on.

I do think that perhaps ember-auto-import could expose a bit more debug tooling to help narrow down the increase (e.g. what packages were imported, and from where) though. What do you think @ef4?