다음단일 Express 응용 프로그램의 js, Apollo 클라이언트 및 서버
Next.js
과Apollo Client
api를 단일Apollo Server
응용 프로그램에 결합시킬 수 있습니까?또 다른 중요한 요구 사항은 GraphQL
지원을 얻는 것이다.그것에 대한 정보가 많지 않기 때문에, 이것은 이 안내서의 주요 목적이다.Express
SSR
yarn workspaces
에 잘 구성하고 하나의 무료 계획 응용 프로그램으로 배치할 수 있습니까?너는 그것에 관한 많은 내용을 발견할 수 있지만, 나는 여기서 그것을 내가 진행하고 있는 프로젝트 과정의 일부분으로 삼는다.monorepo
을 쓰고 싶다.검수 기준
너무 길어서 읽을 수가 없어요.
소스 코드 here
단계
1. 디자인
Here is how you would usually want to use graphql - as a API Gateway between client app and back end services:
우리는 기본적으로 같은 일을 하고 있지만, 우리의 서버 루트는 다음과 같이 보인다.
이것은 우리의 주요 소프트웨어 패키지의 의존 관계도입니다.
2. 주문서 반품
We want every service in a single repo, but at the same time decoupled - Heroku
. We can do it seamlessly with the help of TypeScript
.
Folder structure:
root
|- packages
| |- client
| |- graphql
| |- server
|- package.json
|- yarn.lock
monorepo
:
{
"name": "monorepo",
...
"scripts": {
"build": "yarn workspace @monorepo/client run build",
"start": "yarn workspace @monorepo/server run start",
"dev": "export $(cat .env | xargs) && yarn workspace @monorepo/server run dev"
},
"private": true,
"workspaces": ["packages/*"],
"engines": {
"node": "13.x"
}
}
No dependencies here. yarn workspaces
is required by yarn workspaces. package.json
declares where our packages live. Each script executes yarn command in specified workspace. In private": true
script we read local development environment variables from "workspaces": [...]
file before starting dev server. (If it does not work on your OS, replace with what works for you)
dev
:
NODE_ENV=development
PORT=3000
GRAPHQL_URI=http://localhost:3000/graphql
Let's agree on the naming convention for our packages: .env
.
3. GraphQL API 설정
This one is the easiest.
.env
:
{
"name": "@monorepo/graphql",
...
"dependencies": {
"apollo-server-express": "2.12.0"
}
}
@monorepo/package-name
:
import { ApolloServer, gql } from 'apollo-server-express';
const typeDefs = gql`
type Query {
hello: String
}
`;
const resolvers = {
Query: {
hello: () => 'Hello world!',
},
};
const server = new ApolloServer({ typeDefs, resolvers });
export default server;
Everything super simple: schema, reducer. At the end we create Apollo Server, export it, but do not start it right away.
4. 클라이언트 응용 프로그램 설정
This one is trickier. We need to make Next js use Apollo Client for fetching the data and make sure SSR is supported.
To bootstrap the Next.js app, I followed this quick start guide .js 응용 프로그램.하지만 우리는 약간의 수정이 필요하다.packages/graphql/package.json
:{
"name": "@monorepo/client",
...
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
"dependencies": {
...
}
}
별거 아니에요.이제
packages/graphql/index.ts
설정 packages/client/package.json
을 사용하여 next.js/examples/with-apollo 에서 Apollo Client
및 SSR
을 복사합니다.우리는 약간의 수정이 필요하다
/apolloClient.js
:...
export default function createApolloClient(initialState, ctx) {
return new ApolloClient({
ssrMode: Boolean(ctx),
link: new HttpLink({
uri: process.env.GRAPHQL_URI, // must be absolute for SSR to work
credentials: 'same-origin',
fetch,
}),
cache: new InMemoryCache().restore(initialState),
});
}
우리는 링크를 가리킬 것이다./lib/apollo.js
환경 변수를 기반으로 로컬 dev 서버나heroku 호스트의 URL을 가리킵니다.기본적으로, URL은 apolloClient.js
이지만, SSR을 작동하기 위해서는 절대 경로를 거기에 두어야 합니다.왜냐고 묻지 마.우리는 두 개의 페이지가 있는데, 하나는 SSR이 있고, 다른 하나는 없다.
GRAPHQL_URI
:import React from 'react';
import { useQuery } from '@apollo/react-hooks';
import Layout from '../components/Layout';
import gql from 'graphql-tag';
import { withApollo } from '../apollo/apollo';
const QUERY = gql`
query GetHello {
hello
}
`;
const NOSSR = () => {
const { data, loading, error, refetch } = useQuery(QUERY);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<Layout>
<h1>This should be rendered on client side</h1>
<pre>Data: {data.hello}</pre>
<button onClick={() => refetch()}>Refetch</button>
</Layout>
);
};
export default withApollo({ ssr: false })(NOSSR);
훅/graphql
이 얼마나 간결한지 주의하세요.미녀아래쪽에 있는 페이지를 packages/client/pages/index.ts
에 포장하여 SSR을 사용/비활성화하기만 하면 됩니다.우리는 거의 같은 페이지가 하나 더 있을 것이다. useQuery
, 그러나 withApollo({ ssr: false })(NOSSR)
있다.마지막으로
packages/client/pages/ssr.ts
:import next from 'next';
const nextApp = next({
dev: process.env.NODE_ENV !== 'production',
dir: __dirname,
});
export default nextApp;
우리는 다음 것을 만들고 있습니다.js 프로그램을 내보내서 나중에 express에서 사용할 수 있도록 합니다.5. express 서버 설정
Alright, its time to stitch everything together.
ssr: true
:
{
"name": "@monorepo/server",
...
"scripts": {
"start": "ts-node index.ts",
"dev": "nodemon index.ts"
},
"dependencies": {
"express": "4.17.1",
"ts-node": "8.8.2",
"typescript": "3.8.3"
},
"devDependencies": {
"nodemon": "2.0.3",
"@types/node": "13.11.1"
}
}
We'll use packages/client/index.ts
to run our TypeScript app on production, it will compile it and keep the build in cache. We'll use packages/server/package.json
for the hot reload. Latest versions have built in TypeScript support, no need to do anything other than ts-node
. Magic!
And the epxress server itself nodemon
:
import express from 'express';
import nextApp from '@monorepo/client';
import apolloServer from '@monorepo/graphql';
const { PORT } = process.env;
async function main() {
const app = express();
await bootstrapApolloServer(app);
await bootstrapClientApp(app);
app.listen(PORT, (err) => {
if (err) throw err;
console.log(`[ server ] ready on port ${PORT}`);
});
}
async function bootstrapClientApp(expressApp) {
await nextApp.prepare();
expressApp.get('*', nextApp.getRequestHandler());
}
async function bootstrapApolloServer(expressApp) {
apolloServer.applyMiddleware({ app: expressApp });
}
main();
Notice how we import nodemon index.ts
and packages/server/index.ts
packages. That's possible thanks to yarn workspaces simlinking.
Next.js and Apollo Server have different express APIs. Next creates request handler that can be used as express middleware:
await nextApp.prepare();
expressApp.get('*', nextApp.getRequestHandler());
Apollo Server does the same thing, but inside client
method:
apolloServer.applyMiddleware({ app: expressApp });
6. dev 서버 실행
Now that we have all the source code ready, from root run:
yarn install
This will instal all the dependencies and do the simlinking between our packages. If you inspect the content of root graphql
in eg VS Code editor, you'll notice something like this:
루트 node_ 모듈에 monorepo 패키지가 추가된 것처럼 보이지만 화살표 아이콘은 파일 시스템의 상응하는 위치를 가리키는 간단한 링크일 뿐임을 나타냅니다.괜찮은데!
이제 루트에서 계속 실행합니다.
yarn dev
응용 프로그램을 엽니다
applyMiddleware
.네트워크 로그에서 볼 수 있듯이 페이지를 표시한 후
node_modules
에 대한 XHR 요청이 있습니다.http://localhost:3000
를 클릭하거나 링크가 있는 /graphql
페이지로 이동하면 추가 요청이 전송되지 않습니다.데이터가 Apollo 클라이언트 캐시에 이미 존재하고 명확한 지시 없이 다시 추출되지 않기 때문이다.또 마술이 됐어!현재, 만약에 우리가
refetch
페이지를 다시 불러온다면, 우리는 페이지가 표시된 후에 XHR 요청이 없다는 것을 알아차릴 것이다. 만약에 우리가 페이지 원본 코드를 검사한다면, 우리는 SSR
텍스트가 이미 존재하는 것을 볼 수 있을 것이다.SSR은 예상대로 작동합니다.마지막으로
SSR
로 이동합니다.개발 모드에서는 Apollo grapqhl 놀이공원 화면을 볼 수 있습니다.7. heroku 응용 프로그램 설정
I wont describe much about the process of setting up new account and creating the app, but its pretty straight forward and should not take longer than 5 minutes.
- Go to
Data: Hello world!
, crete a free plan account. - Do to your dashboard
http://localhost:3000/graphql
- Click
https://www.heroku.com/
->https://dashboard.heroku.com/apps
, choose app name, region, and clickNew
.
You will land on the page with instructions of how to Create new app
and deploy your app.
One more thing you have to do is to set up Create app
env var. Go to install heroku cli
tab in heroku dashboard. In GRAPHQL_URI
section you will find text Settings
. Copy that url, scroll up to the Domains
section and create new env var with key Your app can be found at https://your-app-name.herokuapp.com/
and value Config Vars
:
8. 배포
heroku login
git init
git add .
git commit -am "make it better"
git push heroku master
This will initiate the deployment process. Now here is the last Magical part. Heroku will recognize that your app is NodeJS based, you don't have to configure anything yourself. Moreover, Heroku will figure out that you use GRAPHQL_URI
as a package manager and will run https://your-app-name.herokuapp.com/graphql
after it fetches the source files. Then it will investigate your root package.json, find yarn
script and run it. Finally it will look for the yarn install
script and use it to start the app by default. Awesome. All the set up literally take about 15 minutes if you don't have an existing account.
네, 당신의 heroku 응용 프로그램 URL로 내비게이션해 주세요. 저희가 다 설정했습니다.
Reference
이 문제에 관하여(다음단일 Express 응용 프로그램의 js, Apollo 클라이언트 및 서버), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/givehug/next-js-apollo-client-and-server-on-a-single-express-app-55l6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)