Open eric-burel opened 4 years ago
Next.js has it's own tree shaking function for removing SSR code from the client bundle: https://github.com/vercel/next.js/pull/27552
We could do something similar to remove resolver
field from schemas client-side.
Describe the problem you want to solve or enhancement you want to bring
Ability to write full-stack "feature-oriented" packages with both server and client features, in NPM, as we are used to do in Meteor.
@vulcanjs/graphql
is a good example of this, as it generates the graphql backend, the client fragments, and both are very tied.Define relevant concepts
Full-stack package: A package that export server-specific code and client-specific code. But it could apply to any package that expose different code depending on various environment (server, mobile, client).
Meteor packages are example of fullstack package with their
client
andserver
logic.This is different from just having code that works everywhere, like a low-level library. We are talking about code that is actually specific to the env (calling
window
on the client for instance).We should be able to do something like
import createServer from "@vulcanjs/graphql/server"
,import someHook from "@vulcanjs/graphql/client"
andimport someSharedCode from "@vulcanjs/graphql"
Isomorphic import: Using a fullstack package transparently.
Example: a full-stack package could expose
@vulcanjs/graphql/server
and@vulcanjs/graphql/client
. An isomorphic import would beimport foobar from "@vulcanjs/graphql"
and let the the build system add/client
or/server
depending on the context.Meteor is also doing that.
Limitation: the text editor can't know the environment where the code is run. So, for static typing, you have to explose a generic version. Meteor is subject to this limitation. Blitz.js has something similar, but with "unbalanced isomorphism", limited to how they consume the server using a custom
query
system. The typing is coming from the server, that contains the actual logic, as the client version is just a dull wrapper that does an HTTP call.True isomorphism: you write a single piece of code and let the build system modify it depending on the execution environment. Next
pages
fall into this category.getServerSideProps
andgetStaticProps
functions exported in a page are server-only methods. The rest React (so client but also compatible with server-side rendering). At build time, those methods are removed from the client bundle.This is something we would want to achieve for Vulcan model's:
In this example, the schema mixes shared elements, like the type for "Foo.foobar", and server only methods like the graphql resolver. The power of Vulcan is to let you write only one schema with everything. The limitation is that you don't want the client bundle to contain server code, and sometimes vice-versa. You can bypass this with ugly
require
or playing around with GraphQL context, but only so much.Related
Describe your solution
First step is implementing full-stack packages.
Then isomorphic import could be kept as a "magic" helper specific to Vulcan. But it is not mandatory (like if you create an Express server and don't use weback, you just do
import foobar from "@vulcanjs/graphql/server"
as usual). This feature is more comfort for people used to Meteor.Questions to the community:
For full-stack package: Multi entry Webpack export/TypeScript. It should not be too hard, but I've never done that before, there are a lot of moving pieces. So help welcome!
For isomorphic import: there is a demo package
multi-env
that does exactly this. The way it works, it imports eitherindex.server
orindex.client
, using Webpack magic.For the text editor autocompletion, or common code, we can also add an
index
that exports both. That's a prototype so again help and feedback welcome.A good example to get started is the
graphql
package, that contains both server and client logic.For true isomorphism: it's not easy at all to mix server and client stuff at the same place.
foobar.ts
:And then you create the full model using some build time magic. This is still a bit blurry, that's the part that require the most thinking.