Fullstack Javascript Monorepo 예
프런트엔드에는 네트워크와 모바일 클라이언트가 있고 백엔드에는 각종 서비스가 있다.
응용 프로그램의 모든 부분은 다른 부분과 결합하여 작업하고 심지어 개발 단계에서 프로젝트를 시작하는 것은 고통스러운 일이다...
만약 그렇다면, 단품 환매에 대한 나의 견해를 들어 보세요.
( source code )
무엇이 단환매입니까?
Wikipedia의 설명과 같이
A monorepo is a software development strategy
where code for many projects is stored in the same
repository.
간단명료하다.
다음은 전형적인javascript monorepo 구조입니다.
repo-root/
package.json
projects/
project-1/
package.json
project-2/
package.json
도구
자바스크립트와 함께 사용할 때, 우리는 최소한 두 개의 도구를 사용하여 하나의 저장소의 항목을 관리할 수 있다.
사선
Yarn는 모두가 알고 있는 의존 관계 관리 도구(npm에 해당)이다.또한 workspaces라고 불리는 다중 패키지 관리 원어를 프로젝트 관리 도구로 제공하기 위한 것입니다.
Workspaces are a new way to set up your package architecture that’s
available by default starting from Yarn 1.0. It allows you to setup
multiple packages in such a way that you only need to runyarn
once to install all of them in a single pass.
install
기본적으로 이런 기능을 사용하면 우리는 단일한 실이 있을 것이다.자물쇠와 루트 단계의 단일 node_modules 폴더입니다. 이것은 yarn이 설치할 때 성능을 향상시킬 수 있도록 모든 프로젝트 의존항을 함께 설치할 것입니다.
또한 0 개의 추가 설정을 가진 내부 패키지 간의 의존 관계를 정의할 수 있습니다.
레르나
A tool for managing JavaScript projects with multiple packages.
Lerna는 특정 하위 프로젝트에서 사용자 정의 스크립트를 실행하고 저장소에서 변경된 내용을 기반으로 버전 제어 및 패키지 발표를 할 수 있는 통합 솔루션 () 과 같은 유틸리티를 제공합니다.
완전성을 위해 방사선 작업구역 본기에서 실현된 모든 기능을 제공했지만 이를 통합할 가능성도 제공했다. 우리는 두 번째 옵션을 선택할 것이다.
사선, 레나, 모노포스에 대한 더 상세한 토론은 이 좋은 것을 추천합니다article.
샘플 항목
우리의 예시 항목은 장난감 응용 프로그램으로 백엔드에서 책을 얻고 웹 인터페이스를 통해 그것을 보여 준다.
그러나 이를 실현하기 위해 다음과 같은 구조를 선택했습니다.
폴더 구조
우리는 프로젝트를 두 개의 다른 폴더로 나눌 것이다. 그것이 바로 응용 프로그램과 패키지이다.
응용 프로그램 폴더는 실행할 때 프로그램을 구성하는 모든 구성 요소를 포함하며, 이 예에서는graphqlapi와reactjs 클라이언트입니다.
패키지 폴더는 응용 프로그램이 공유하는 모듈을 포함합니다. 예시는reactcomponents 패키지입니다.
최종 폴더 구조는 다음과 같습니다.
repo-root/
package.json
packages/
design-system/
package.json
applications/
client/
package.json
api/
package.json
사선/레나 설정
우선, 모노르포를 위한 관리 도구를 설정해야 합니다.
루트:
yarn init
주의: 방사선 작업장에는 뿌리가 필요합니다.json은 개인이기 때문에 실을 초기화하는 과정에서 개인 로고를true로 설정하는 것을 확보한다.그런 다음 lerna를 설치해야 합니다.
yarn add lerna -D
yarn lerna init
나는 항상 이런 의존항을 devdependency로 설치하는 것을 좋아한다.다음은 프로젝트 구조에 따라 방사선 작업 구역을 정의합니다.
// package.json
{
…
"private": true,
"workspaces": [
"applications/*",
"packages/*"
],
…
}
그리고 우리는 레나가 자신과 실의 작업 공간을 어떻게 통합하는지 지도한다.// lerna.json
{
...
"packages": [
"applications/*",
"packages/*"
],
"npmClient": "yarn",
"useWorkspaces": true,
...
}
마지막으로 개발 과정에서 응용 프로그램을 시작하는 사용자 정의 스크립트를 추가했습니다.// package.json
{
…
"scripts": {
"start": "yarn lerna run development:start --parallel"
},
…
}
api 프로그램 작성
백엔드에 대해graphql를 선택했습니다.특히, 우리는 getting started tutorial of the official apollo website (babel을 추가하여 자바스크립트 ES6 문법을 이용할 것) 을 실현할 것이다.
우선, 우리는 새로운 디렉터리와 cd를 만들어야 한다.
mkdir -p applications/api
cd applications/api
그리고 우리는 프로젝트 의존항을 초기화해야 한다yarn init -y
yarn workspace applications/api add @babel/core @babel/cli @babel/node @babel/preset-env nodemon -D
yarn add apollo-server graphql
yarn install
그리고 그의 서류와 폴더mkdir src
touch src/index.js
touch .babelrc
다음으로, 우리는 약간의 설정을 추가해야 한다.여기서 graphql 응용 프로그램을 시작하는 스크립트를 정의했습니다.
// applications/api/package.json
{
...
"scripts": {
...
"development:start": "yarn nodemon --exec babel-node src/index.js ",
...
},
...
}
여기에서 우리는 우리의 Babel 컴파일러를 위해 사전 설정을 정의했다.// applications/api/.babelrc
{
"presets": ["@babel/preset-env"]
}
마지막으로 코드를 추가할 수 있습니다.// applications/api/src/index.js
import { ApolloServer, gql } from "apollo-server";
const typeDefs = gql`
type Book {
title: String
author: String
}
type Query {
books: [Book]
}
`;
const books = [
{
title: "Harry Potter and the Chamber of Secrets",
author: "J.K. Rowling"
},
{
title: "Jurassic Park",
author: "Michael Crichton"
}
];
const resolvers = {
Query: {
books: () => books
}
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
이제 다음 명령을 실행하여 테스트를 수행할 수 있습니다.yarn development:start
또는cd ../..
yarn start
클라이언트 응용 프로그램 인코딩
클라이언트에 대해, 우리는apollo 클라이언트를 사용하여react 웹 응용 프로그램을 구축하여graphql 백엔드와 협조하여 사용할 것입니다.
우선, 우리는 새로운cra 프로젝트를 시작했습니다.
npx create-react-app applications/client
기억해라, 우리는 실 하나만 필요로 한다.자물쇠, 뿌리 수준에 두어야 하기 때문에cra가 실을 만들지 않았는지 확인하십시오.자물쇠그렇지 않으면rm applications/client/yarn.lock
다음으로 의존 항목을 설치합니다.cd applications/client
yarn add @apollo/client graphql
그리고 우리는 몇 가지 설정을 추가했다.// applications/client/package.json
{
...
"scripts": {
"development:start": "CI=true yarn react-scripts start",
...
}
...
}
마지막으로 코드를 추가했습니다.// applications/client/src/App.js
import React from "react";
import { ApolloClient, ApolloProvider, InMemoryCache } from "@apollo/client";
import Books from "./components/Books";
const client = new ApolloClient({
uri: "http://localhost:4000",
cache: new InMemoryCache()
});
function App() {
return (
<ApolloProvider client={client}>
<Books />
</ApolloProvider>
);
}
export default App;
여기서 응용 프로그램의 내용을 만들고 있습니다.mkdir src/components
touch src/components/Books.js
// applications/client/src/components/Books.js
import React from "react";
import { useQuery, gql } from "@apollo/client";
const ALL_BOOKS = gql`
query GetAllBooks {
books {
title
author
}
}
`;
function Books() {
const { loading, error, data } = useQuery(ALL_BOOKS);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
return data.books.map(({ title, author }) => (
<div key={title}>
<p>
{title} by {author}
</p>
</div>
));
}
export default Books;
실행을 통한 테스트:cd ../..
yarn start
이api 프로그램을 어떻게 시작하는지 주의하십시오.인코딩 설계 시스템 패키지
여기서, 우리는react 구성 요소를 포장할 것입니다.
우선, 우리는 새로운 디렉터리와 cd를 만들어야 한다.
mkdir -p packages/design-system
cd packages/design-system
그리고 우리는 우리의 프로젝트와 그의 구조를 초기화해야 한다.yarn init -y
yarn add react@^16.0.0 -P
yarn add microbundle-crl -D
mkdir src
touch src/index.js
mkdir src/components
touch src/components/List.js
touch src/components/ListItem.js
다음 구성은 다음과 같습니다.// packages/design-system/package.json
{
...
"main": "dist/index.js",
"module": "dist/index.modern.js",
"source": "src/index.js",
"scripts": {
...
"development:start": "yarn microbundle-crl watch --no-compress --format modern,cjs"
...
},
...
}
마지막으로 코드를 추가했습니다.// packages/design-system/src/index.js
import List from "./components/List";
export { List };
// packages/design-system/src/components/ListItem.js
import React from "react";
import PropTypes from "prop-types";
// I'm not using css files because they will not work when exported!
// Consider to use styled components for your project...
function ListItem(props) {
return (
<div
style={{
margin: "10px",
padding: "10px",
border: "1px solid #bbb",
backgroundColor: "#eee"
}}
>
<span
style={{
fontSize: "1.2em",
textDecoration: "none",
color: "#333"
}}
>
{props.text}
</span>
</div>
);
}
ListItem.propTypes = {
text: PropTypes.string.isRequired
};
export default ListItem;
// packages/design-system/src/components/List.js
import React from "react";
import PropTypes from "prop-types";
import ListItem from "./ListItem";
function List(props) {
return (
<div>
{props.items.map((content, index) => (
<ListItem key={index} text={content || ""} />
))}
</div>
);
}
List.propTypes = {
items: PropTypes.arrayOf(PropTypes.string).isRequired
};
export default List;
마지막으로 클라이언트 응용 프로그램을 업데이트해야 합니다.// applications/client/src/components/Books.js
import React from "react";
import { useQuery, gql } from "@apollo/client";
import { List } from "design-system";
const ALL_BOOKS = gql`
query GetAllBooks {
books {
title
author
}
}
`;
function Books() {
const { loading, error, data } = useQuery(ALL_BOOKS);
if (loading) return <p>Loading…</p>;
if (error) return <p>Error :(</p>;
return (
<List
items={data.books.map(({ title, author }) => `${title} by ${author}`)}
/>
);
}
export default Books;
종속성:yarn add design-system@^1.0.0
이제 최종 어플리케이션을 테스트할 수 있습니다.cd ../..
yarn start
주의: 현재react의 개발 서버에 버그가 있는 것 같습니다.처음 시작한 후에는 페이지를 새로 고쳐야 합니다.공간 개선
우리의 응용 프로그램은 이렇게 간단하고, 이렇게 복잡한 구조는 보기에 완전히 불합리해 보일 수도 있다.
하지만 이렇게 생각하면...너는 이 도서 출시 응용 프로그램이 세계에서 가장 좋은 온라인 서점이 되기를 바란다.
클라이언트에서는 최소한 고객에게 상점 응용 프로그램을 제공하고 공급업체에 대시보드를 제공해야 합니다.
서버 쪽에서 밑바닥 데이터 모델이 폭발할 것이다.너는 반드시 너의 사용자를 관리하고 주문서를 추적해야 한다.즉, 당신은 반드시 톤의 업무 논리 코드 줄을 작성해야 하며, 제3자 시스템에 통합해야 할 수도 있다.코드에서 낮은 결합과 높은 내적 집합의 원칙을 유지하기 위해서는 많은 응용 프로그램과 모듈에서 이 논리를 분리해야 합니다.
응용 프로그램이 더 이렇게 보일 수도 있습니다.
의안된 monorepo 구조에 따라 코드를 관리할 수 있는 동시에 프로젝트를 확장하기 쉽다.필요한 모든 새 패키지 및/또는 응용 프로그램을 적절한 폴더 아래에 작성하기만 하면 됩니다.
결론
javascript는 웹 개발 분야의 전복적인 굴기는 이미 가장 선진적인 수준에 이르렀고 프로그래밍 언어로 매우 복잡한 응용 프로그램을 개발할 수 있다.
이런 상황은 몇 가지 장점을 제공했다. 예를 들어 여기 부분에서 묘사한 집중 프로젝트 관리의 가능성이다.
나는 이 문제에 대한 나의 생각이 당신의 현재나 다음 항목에 도움이 될 것이라고 진심으로 희망합니다.
당신의 어떤 피드백도 매우 감사합니다!
Reference
이 문제에 관하여(Fullstack Javascript Monorepo 예), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/alecap7/have-you-ever-heard-of-javascript-monorepos-here-is-an-example-3g7m텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)