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

Browser Friendly Relative Imports with .js extension #3047

Closed
bennypowers opened this issue Feb 20, 2018 · 10 comments
Closed

Browser Friendly Relative Imports with .js extension #3047

bennypowers opened this issue Feb 20, 2018 · 10 comments

Comments

@bennypowers
Copy link
Contributor

bennypowers commented Feb 20, 2018

All modern browsers (including firefox) support es modules, but there is not 'module resolver' on the web, which means that browsers require relative URLs for module files.

import foo from 'foo' // sad browser 😢
import bar from '../bar/bar.js' // happy browser 😃

For users that do not need a complicated (or any) build step, apollo-client should provide a browser-friendly package with relative imports. This can be mechanically prepared.

Intended outcome:
This Just Works:

<script type="module">
  import { ApolloClient } from '/node_modules/apollo-client/ApolloClient.js';
</script>

Actual outcome:

Chrome 64:

Uncaught TypeError: Failed to resolve module specifier "apollo-link". Relative references must start with either "/", "./", or "../".

How to reproduce the issue:

Same as Intended outcome

Version

  • apollo-client@2.2.5

Notes
I was unable to find a rollup plugin which would do this automatically, but I'm reasonably confident that such a plugin would not be hard to implement.

@fbartho
Copy link

fbartho commented Mar 29, 2018

That sounds like a lot of exposure of internal state. What if ApolloClient.js is renamed?

I wouldn’t recommend this as a supported feature of Apollo as every single source-file becomes part of public interface.

Wouldn't it be easier to write a rollup plugin that re-writes from 'apollo-client' to a relative path?

@hwillson
Copy link
Member

Thanks for the suggestion @bennypowers. This isn't something the Apollo Client team is considering at this time. Closing for now - thanks!

@heruan
Copy link

heruan commented Jun 13, 2018

I'd be very interested in this, since I'm porting many apps from Polymer 2 to Polymer 3 (i.e. ES modules) and I still need to bundle Apollo Client to make it work (see e.g. #3571).

Hope to see this reconsidered to be able to use Apollo Client with ES module as per spec!

@Westbrook
Copy link

Seems like a bit of a reach to call something "fully-featured, production ready," and for use in the browser when you're required to use a third party tool just to prep the code even just to dev/test.

Wouldn't the easiest thing be to leverage the power of modules to centralize all of your exports internally via export {foo} from 'foo.js'; syntax whereby there would be no greater need to expose internal state then your solution as it is now?

// /node_modules/apollo-client/Apollo.js or similar
export { ApolloClient } from './ApolloClient.js';
export { ApolloOtherThing } from './ApolloOtherThing.js';
...etc...

This way getting into Apollo Client usage would have a significantly lower barrier or entry while we could rely of much more established functionality around tree shaking and the like from RollUp and friends to ensure that code is optimized for Production?

@bennypowers
Copy link
Contributor Author

Perhaps now that redux is releasing a web bundle, it's time to reconsider this issue?

reduxjs/redux#3143

@bennypowers
Copy link
Contributor Author

That sounds like a lot of exposure of internal state. What if ApolloClient.js is renamed?

I wouldn’t recommend this as a supported feature of Apollo as every single source-file becomes part of public interface.

I find it highly unlikely that many users will be importing scheduler or ObservableQuery, but if they do, that's what semver is for.

Please reconsider this issue. I'm advocating for a tree-shakable, performance-oriented, developer-friendly approach to publishing this library. Every time I start an apollo project, it's knowing that I'll have to spend at least a few hours wrestling with my bundler, patching transpiled node_module dependencies, trying to get out of dependency hell, etc.

There's nothing intrinsic to graphql or the apollo library which necessitates all this tooling, it's a choice to saddle web developers with all that baggage. But there is a ready, standardized alternative that's been available for years now: Modern Javascript and the evergreen browser!

Recently in a JS developer chat, a colleague commented:

Library authors need to publish to the lowest common denominator.

This is not true. In fact, some app authors need to serve to the lowest common denominator, but only if they are not using differential serving to send efficient modern es modules to capable browsers, and only serving bloated transpiled bundles to older UAs.

djdg3wsvaaacfow jpg large

Even in the best case scenario, transpiling doubled the size of this simple module.

Apollo Client bundles together at 1mb. That's 1mb of gzipped JS that has to be sent over the wire via 3g then parsed on a low-CPU device, and a lot of that is babel boilerplate, polyfills, etc. that don't need to be shipped or parsed to the majority of users. I'm not saying that app authors should throw older browsers out the window, I'm saying that library authors shouldn't make the rest of us suffer because of it 😄

Typescript compiles to standard ECMAScript modules, that's really the lion's share of what is needed to do here. App authors that for some reason need CJS can perform those transformations on their own, as a development-time build step, not as a library-mandated postinstall script.

Please reconsider publishing a standard, browser-ready, modular, modern JavaScript apollo client, so that app authors can get up and running faster, and deliver smaller, faster bundles to their users.

@bennypowers
Copy link
Contributor Author

Regarding the desire to not have to bump semver for internal modules - this could be solved with a postinstall step that doesn't saddle the user with bloated modules - simply bundle internal modules into util or something, and have the 'public-facing' modules import from there. All of those modules should be idiomatic es2018.

Regarding the larger shift in the javascript community towards the now three-year-old module standard, consider the pikapkg project. More and more developers are seeking standard alternatives to the old-school cjs libraries.

@fineline
Copy link

fineline commented Mar 4, 2019

Is there at least some guide to setting up rollup or similar to get a bundled version of apollo-client that I can use as a browser ES module for evaluation and development?

I am just getting into Apollo Client and this is a problem for me too. I don't use any build step in my dev process, only when preparing for production. I agree with Benny that there will be more people working this way as approaches like lit-html get adoption. I know that projects using JSX, TypeScript, etc. are forced to use a build step in dev, but not all of us do.

@fineline
Copy link

fineline commented Mar 4, 2019

For others having this problem, I followed Benny's link to pikapkg and from there to https://github.com/pikapkg/web, and using this I created a package in web_modules for apollo-client, as well as graphql. I can now use the former to import ApolloClient in a web module. That's as much as I have time for now but thought it might help someone.

@justinfagnani
Copy link
Contributor

I just hit this problem today when I tried adding Apollo client to an existing project that's otherwise only using standard JS modules. Given that it's almost 2021 and browsers have support native JS modules for many years now, would the Apollo team be interested in publishing modules that actually load in the environment they're supposed to be used in now? @hwillson

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants