I would like to serve my build/dist folder for my static assets when developing/deploying to now or any server. For that I need to install express again and use the static function from there.
It would be great if graphql-yoga had this inbuilt for my static assets otherwise it would good enough to re-export the express library for public use.
This is what I'm doing now
import express from 'express';
server.express.use(express.static('dist'));
Something like this would be more easier,
import GraphQLYoga from 'graphql-yoga';
const { GraphQLServer, express } = GraphQLYoga;
const server = new GraphQLServer({ typeDefs, resolvers, options })
server.express.use(express.static('dist'));
else more like this,
const server = new GraphQLServer({ typeDefs, resolvers, options: {
static: 'dist',
}});
BTW Great library. I had the same amount of code throughout my projects. This unifies it and also the apollo-upload-server is a plus that too it got recently released too.
+1
I like server.express.use(express.static('dist')); better.
more flexible
Hi @pyros2097, isn't what you suggested already possible?
I needed to install the express library and then use the static option from it. I understand the express server is exposed by the server but not the library. So I need to install express additionally to use say ... express.Router() if I needed to add a route or something like that.
That's why I made this change
https://github.com/pyros2097/graphql-yoga/blob/master/src/index.ts#L15
I just wanted it to be consistent on what express library I used.
Installing the express library is the way to go for now.
Yes, I saw that in the PR too. I agree with @schickling that if you need anything from express, you should add that dependency yourself, instead of having graphql-yoga export it.
Ok. I understand now. I just thought, that way we could make graphql-yoga a single dependency for all your server needs. Maybe that's now what graphql-yoga is trying to solve. Again it was just my reasoning. @kbrandwijk I initially followed that approach.
hi all, is really can add static folder to yoga?
what i do is,
//**********************************************************
server.express.use(express.static(path.join(__dirname, '../client/build')));
// server.express.get('/', res => res.sendFile(path.join(__dirname, '../client/build/index.html')));
//**********************************************************
const options = {
port: 3000,
endpoint: '/graphql',
subscriptions: '/subscriptions',
playground: '/playground',
};
server.start(options, ({ port }) => console.log(`Server is running at http://localhost:${port}`));
when i add the static folder, i cannot access /playground and /graphql anymore.
who can tell me why ?
@geminiyellow I don't know if this is the right place to ask this question. But anyways the /graphql, /playground paths will get caught by the static middleware since it is a middleware.
You can try to mount the static assets to a path like this,
server.express.use('/build', express.static(path.join(__dirname, '../client/build')));
and then you will be able to access your assets from the build path like this /build/index.html
@pyros2097 thank you
For anyone else stumbling upon this and wanting to have 1 app that serves both your backend and frontend, I suggest you do:
- backend
- yoga.js
- frontend
- react.js
- package.json
- server.js
// ./package.json
{
"scripts": {
"dev": "npm-run-all --parallel dev:*",
"dev:frontend": "nodemon ./server.js", // catch-all routes --> your react app's index.html
"dev:backend": "nodemon ./backend/yoga.js"
}
}
// ./server.js
const port = process.env.PORT || 5000
app.listen(port)
console.log(`./server.js: http://localhost:${port}`)
// ./backend/yoga.js
// ...
const port = 1337
server.start({ port }, () => console.log(`./backend/yoga.js: http://localhost:${port}`))
Replace "dev" scripts with "start", and nodemon with node, and this should work on Heroku as well.
The idea is Heroku can run 1 start script. Within that start script we're parallel running both servers (our generic Express app to catch-all towards React _and_ our graphql-yoga app).
React will run on Heroku's default port so example.herokuapp.com will be your React app. Since your graphql-yoga server is on a different port, example.herokuapp.com:1337 will display your Playground.
@geminiyellow this worked for me
// Serve static files
server.express.use(express.static(path.join(__dirname, '../client/build')));
// Serve other routes to index...typical for Angular frontend app
server.express.get('*', (req, res, next) => {
// Handle graphql-yoga specific routes
if(req.url == options.playground ||
req.url == options.subscriptions ||
req.url == options.endpoint) {
// Return next() so that the GraphQLServer will handle it
return next();
}
res.sendFile(path.join(__dirname, '../client/build/index.html'))
});
I know this issue is closed, but I felt like contributing a solution that worked for me.
looks good
@newtmex That feels like the correct way how to do this! Kudos!
@newtmex Thank you!
I don't fully understand the above solution, as I can't seem to get this working. I'm using next.js and apollo. How might I do this when using next.js as my front end framework?
this worked for me
const { GraphQLServer } = require('graphql-yoga');
const serveStatic = require('serve-static');
const { join } = require('path');
const server = new GraphQLServer({ typeDefs, resolvers, options });
server.express.use(
serveStatic(join(__dirname + '/../public/'), {
cacheControl: false,
}),
);
Most helpful comment
@geminiyellow this worked for me
I know this issue is closed, but I felt like contributing a solution that worked for me.