✏️ Ditto / Ditto-cli

박영은·2023년 10월 22일
0


(뉴진스 ditto 아님)

☘️ Ditto

  • 엔드투엔드 프로세스를 만들어줌.
  • 전역상태관리를 위한 Provider를 감싸주듯 App.tsx(최상단)파일을 DittoProvider로 감싸서 변형을 전달함.
  • 복수형도 자동으로 처리 = 복잡하고 보기 어려운 코드 정리 good.
  • 개발자 이점 외에도 Ditto의 웹 앱과 Figma 플러그인은 모두 맞춤법 및 문법 오류를 방지하기 위한 문법 지원 기능을 갖춤. = 디자인부터 개발까지 텍스트를 체계화.
  • Ditto = GraphQL 클라이언트를 통해 데이터를 가져오고 업데이트함.
  • 텍스트들을 하나하나 넣지 않아도 디자이너가 Figma에서 ditto로 동기화한 데이터를 id로 연결해서 가져올 수 있음.
  • Ditto의 텍스트 편집 내용 = Ditto CLI를 통해 자동으로 가져올 수 있음.
    = 개발자가 완료해야 하는 수동 복사/붙여넣기 오류 및 복사 업데이트 작업을 방지함.
    - CLI는 플랫 JSON, 구조화된 JSON, iOS 문자열, XML 등 개발자의 기존 워크플로에 맞는 형식으로 텍스트를 가져옴.
    • 모든 변수 및 복수형 데이터를 포함하는 구조화된 JSON의 예:이 JSON 파일은 Ditto React 라이브러리가 데이터를 소스로 삼는 곳이며 CLI가 새 정보를 가져오도록 요청할 때마다 업데이트됨.



🌱 Ditto Cli

npm install @dittowords/cli
👉 간단 설명
: 디자이너가 figma에서 특정 텍스트나 이미지 등 자원 수정 후 ditto 플러그인을 통해 저장
-> ditto-cli pull or node_modules/.bin/ditto-cli 명령어 실행
-> ditto 폴더 > json 파일들 : 업데이트된 json파일을 확인할 수 있음. (연결 다 해둔 상태라면 코드 수정할 필요 없이 저장, 확인해보면 바로 다 업데이트 된 화면 볼 수 있음.)

  • 코드베이스를 Ditto와 동기화하는 프로세스를 단순화하고 자체 Http 요청을 할 필요 없이 즉시 데이터를 가져올 수 있게 함.
// 나는 이미 브랜치에 cli 있고 내부 공유 api key만 입력하면 되어서  npm install --save-dev @dittowords/cli 함.
// 한 브랜치 꼬여서 ~~ --force
$ npx @dittowords/cli

┌──────────────────────────────────┐
│                                  │
│   Welcome to the Ditto CLI.      │
│                                  │
│   We're glad to have you here.   │
│                                  │
└──────────────────────────────────┘
    
What is your API key? >  key 입력 후 enter
// 내부적으로 Ditto api를 사용하기 때문에 최초 실행 시 key 요청.

✔ What is your API key? · xxx-xxx-xxx
// key 입력 성공 시 확인되는 메세지
Thanks for authenticating.  
We'll save the key to: /Users/username/.config/ditto

- 여기까지 하면 key 등록완료.

  • key 인증 후 명령 실행하고 동기화할 프로젝트 선택해 1개 이상의 디렉터리에서 사용할 수 있도록 ditto cli 활성화 할 수 있음.
  • 설치 후 ditto라는 폴더 생성됨.
    프로젝트 폴더로 이동한 후,
    ditto init 명령어 실행 -> Ditto 설정 파일(ditto.config.js)이 프로젝트 루트 폴더에 생성됨.

    ditto > config.yml
    - 현재 디렉터리와 동기화해야하는 프로젝트, 저장해야하는 데이터 형식, 변형데이터를 포함해야 하는지 등의 Ditto 서버 및 스키마 설정을 구성함.(아래 명령어로 추가/삭제)
    - ditto-cli project add, ditto-cli project remove
  • ditto-cli pull : 프로젝트 목록을 읽고 ditto/config.yml ditto api를 사용해 ditto앱에서 사용할 프로젝트의 데이터를 가져오고 저장함.



🌱 사용법

  • ditto에서 해당 컴포넌트의 데이터를 내려받을 수 있다
  • 이처럼 json 파일을 구조도 선택 가능함.
1. Ditto로 이동하여 구성 요소의 ID를 가져온다.
2. 검색 도구를 사용하여 프로젝트에서 텍스트의 모든 인스턴스를 찾는다.
3. JSX 코드의 일부가 아닌 문자열의 인스턴스(예: 함수 이름, 주석 등)를 필터링한다.
4. 텍스트를 <DittoComponent componentId=<id> /> 로 바꿔 적용.
// ----- 🗂️ ditto > config.yml ----
// ditto 샘플
sources:
  components:
    enabled: true
variants: true
format: flat


// 아래와 같이 프로젝트 아이디 등 각각 설정 가능
sources:
  
  projects:
    - id: a1b2c3d4e5f6g7h8i9j10k11l12
      name: TRIP YOUNGDVISOR my project (English)
 	- id: a1b2c3d4e5f6g7h8i9j10k11l122
      name: TRIP YOUNGDVISOR my project2 (English)
	  exclude_components: true
variants: true
format: structured

// source - projects
//   : 텍스트를 가져올 프로젝트 목록
// name
//   : cli에서 프로젝트를 참조할 때 표시 목적으로 사용되지만, Ditto의 프로젝트 이름과 정확히 일치할 필요는 없음.
// exclude_components
//   : 구성 요소와 연결되지 않은 텍스트 항목만 가져와야 함을 나타내기 위해 프로젝트별로 속성을 추가할 수 있음.
// variants
//   : 구성된 소스에 대한 텍스트 데이터를 가져올 때 변형 정보를 포함할 수 있음. (false지정하지 않으면 기본값)
// format
//   : 지정하지 않으면 기본값. (지정가능 값 = flat, structured, android, ios-strings, ios-stringsdict)
//   : 동일한 구성에서 여러 JSON 형식을 지정하면 x -> 디스크에 쓸 때 서로 덮어쓰게 되기 때문.

// 이 외에도 status, root, components 등이 있음. (ditto cli 깃 readme 참조)




// ----- 🗂️ ditto > ex) ditto-component-file-name-example_kr-ko.json ----
{
  "my_project_title" : {
  	"text" : "여행 프로젝트",
    "api_id" : "my_project_title-1"
  },
  "my_project_title-2" : {
  	"text" : "식단 프로젝트",
    "api_id" : "my_project_title-2"
  },
      "my_project_placeholder" : {
  	"text" : "추가할 프로젝트명을 입력하세요.",
    "api_id" : "my_project_placeholder"
  },
  .
  .
  .
}
// 이하 ditto 샘플 json
{
  "footer.about.blog": "Blog",
  "footer.about.careers": "Careers",
  "footer.about.company": "Company",
  .
  .
  .
}




// ----- 🗂️ ditto > index.js -----
// ditto로 적용할 각 key와 source목록
// source목록 = ditto 폴더 하위로 저장된 json데이터들
module.exports = {
	"ditto_project_id_example_pye_1" : {
      // 아래 json 데이터들은 ditto 폴더 하위로 저장된 json 파일들이다. (코드 아래 사진 참고)
    	"base" : require('./ditto-component-file-name-example_kr-ko.json'),
     	"spanish" : require('./ditto-component-file-name-example_spanish.json'),
      	"us_en" : require('./ditto-component-file-name-example_us-en.json'),
    },
  	"ditto_project_id_example_pye_2" : {
    	"cn" : require('./ditto-component-file-name-example_cn.json'),
     	"jp" : require('./ditto-component-file-name-jp.json'),
	},
  .
  .
  .
}




// ----- 🗂️ app.tsx -----
import {DittoProvider} from "ditto-react";
import dittoSource from  "@ditto/.";  // 위의 ditto > index.js
//  = import dittoSource from  "./ditto";  

const projectId = Object.keys(dittoSource);
// const [variant, setVariant] = useState("base")

return (
...
// <DittoProvider source={dittoSource} variant={variant} >
	// * projectId = 적용시킬 'ditto 의 해당 json 파일'
	// * variant = "us-en"을 적용하면 위의 json 파일 중 us-en으로 설	정한 파일이 적용됨. 
	//   기본으로 하고싶으면 그냥 variant안쓰면 됨.
  <DittoProvider source={dittoSource} projectId={projectId[0]} variant="us-en">
    <Component {...pageProps} />
  </DittoProvider>
...
)




// ----- 🗂️ component -- ditto 데이터를 사용할 컴포넌트
import {Ditto} from "ditto-react"

const myTitle = "이사"

return(
...
  <div>
  	<input placeholder={`${my_project_placeholder}`} />
  	<h1><Ditto textId="my_project_title-1" /></h1>
  	<span><Ditto textId="my_project_text" /></span>
  </div>
...

)

👉 ditto에서 제공하는 예시 샘플 소스




🌱 Ditto에 변수처리 및 복수형 등 요소들

{
  .
  .
   "my_project_title-3" : {
  	"text" : "{{title}} 프로젝트",   
    // 변수로 처리할 부분을 {{중괄호 두 개}}로 감싸줌. 💥
    "api_id" : "my_project_title-3"
  },
  .
  .
}

<h1>
  <Ditto textId="my_project_title-1" variables={{title : myTitle}}  count={2}/>
// variables에 변수 적용
// count = 복수형 지정 시 사용
</h1> 



🌱 Ditto 타입 string으로 변환하기 (useDittoSingleText)

  • textId, componentId 상관없이 ditto의 초기 type = object
  • 변환 방법
...
// useDittoComponent는 아직 안해봄.. 
import { Ditto, , useDittoSingleText } from "ditto-react";

//const id = useDittoSingleText({textId : "text-id-1"})
const textName = "text-id-1"
const text = useDittoSingleText({textId : textName });
console.log(text) // "안녕하세요."
console.log(typeof(text)) // string


// 내가 한 것
const [label , setLabel] = useState("");

const textName = "text-id-"
const text = useDittoSingleText({textId : textName + label })

onClick={()=>setLabel(
	value === "호두"
		? "1"
  		: value === "자두"
  		? "2"
		: "3"
);}
  
...



🌱 Ditto component Property

🏷️ componentId
<h2><Ditto componentId="footer.about.blog" /></h2>
// - Ditto를 사용하여 특정 컴포넌트 또는 섹션에 연결된 고유한 식별자를 나타내는 속성. 
//   (컴포넌트 레벨에서 다국어 번역 또는 다른 변수를 관리)
// - 이를 통해 Ditto는 해당 컴포넌트와 관련된 다국어 번역 또는 다른 변수 데이터를 제공.

🏷️ textId
<h2><Ditto textId="my_project_text" /></h2>
// - 특정 텍스트 또는 문자열의 식별자를 나타내는 속성.
// - 특정 텍스트 또는 문자열과 관련된 데이터를 제공.

🏷️ locale
<Ditto componentId="example" locale="fr-FR" />
// - Ditto에서 사용할 로컬(언어 및 지역 설정)을 정의.
// - 이를 통해 다국어 지원을 위해 다른 언어로 텍스트를 렌더링하거나 다른 지역 설정에 맞게 형식을 지정할 수 있음.

🏷️ variant
<Ditto componentId="button" variant="primary" />
<Ditto textId="call-to-action" variant="urgent" />
// -  특정 컴포넌트 또는 텍스트에 대한 여러가지 변수 관리.
// - 사용 예) 버튼 컴포넌트의 다양한 스타일을 나타내거나 텍스트의 강조 효과를 변경 등.
  
🏷️ format
<Ditto textId="date" format="longDate" />
<Ditto textId="price" format="currency" />
// - 텍스트 또는 숫자와 같은 값을 형식화하기 위해 사용.
// - 날짜, 시간 또는 숫자와 관련된 형식을 제어하며, 로케일에 따라 다른 형식을 적용할 수 있음. 
  
🏷️ data
<Ditto componentId="product-description" data={productData} />
<Ditto textId="user-greeting" data={userData} />
// - 컴포넌트 또는 텍스트와 관련된 추가 데이터를 전달하는 데 사용.
// - 사용 예)  동적 데이터를 가져와서 텍스트와 함께 렌더링, 다른 사용자 지정 데이터를 전달 등.
  
🏷️ fallback
<Ditto componentId="example" fallback="Default Text" />
<Ditto textId="greeting" fallback="Hello, Guest" />
// - 주어진 컴포넌트 또는 텍스트의 다국어 지원이 없는 경우에 대비한 기본 텍스트 또는 값.
// - 로컬에 대응하는 번역이 없을 때 사용함.
  
🏷️ placeholders
<Ditto componentId="loading" placeholders={{ text: 'Loading...', component: <Spinner /> }} />
// - 비동기 데이터를 로드할 때 표시할 placeholder 문구 또는 구성 요소를 정의하는 데 사용.



🌱 richText

  • 사실 얘의 역할을 정확히 이게 맞는지는 모르겠다만.. html로 인식되게 하는 것 같다.
출력 예시   :
    			안녕하세요
    			저는 자두입니다.

ditto : 
"textDitto" :{
  "text": "안녕하세요\n 저는 자두입니다.",
}
  
code : 
  <span className="whitespace-pre"> 
      <Ditto textId="textDitto" />  // x 이렇게하면 \n무시되고 한 줄로 나옵니다.
      <Ditto textId="textDitto" richText/>  // o
  </span>
  
  



🍃 ditto 내부에 스타일처리

  • parse 활용 + ditto text에 style 추가

// ditto json
...
"ditto-Body-Id":{
	"text" : "{{text}}의 <span style='color:red;'>{{name}}</span>입니다.",
	"api-id" : "ditto-Body-Id",
    "variants" : {
    	"KR-ko" : {
        	"text" : "{{text}}의 <span style='color:red;'>{{name}}</span>입니다."
        }
     	.
        .
        .
    }
}

// DittoTest.tsx
import parse from "html-react-parser";

const DittoTest = () => {
  	const city = "서울"
    const age = "2"
    //const dittoAge = useDittoSingleText({
      	// "{{age}}살 입니다."
    	//textId : "ditto-text-id",
      	//variables : {
       // 	text : `${age}${"살입니다."}`
        //}
    //})
	const dittoBodyId = useDittoSingleText({
      	// "{{text}}의 {{name}}입니다."
    	textId : "ditto-Body-Id",
      	variables : {
        	text: `${city}`,
          	name: `${"호두자두뚜뚜"}
        }
    });


  
	return (
    	<div>
      		<span>
				<Ditto textId="ditto-header-id" />
			</span>
			<span>
				{ parse( dittoBodyId ) }
			</span>
			<span>
				<Ditto textId="ditto-text-id" variables={{ age : age }} />
			</span>
        </div>
    )
}

export default DittoTest;
  
  

🟢 Ditto 사용 후기

  • 제대로 연결만 잘 하면 정말 너어어무 편할 것 같음.
    - figma와 코드를 연동해두면 개발자가 하나하나 텍스트를 수정하지 않아도 알아서 pull받으면 값이 자동으로 업데이트 되니까 지이인짜 편할 것 같긴 함.

  • 최대한 클라이언트단 개발을 처음 들어갈 때부터 적용할 수 있도록 기획-디자인-디토 세팅-개발 순으로 가는게 맞는것 같음.
    - 이미 개발된 파일 100개 이상의 텍스트들을 하나하나 디토로 다 바꾸려니까 시간이 너무 많이 소요됨.

  • 공통 컴포넌트는 하나로 따로 빼서 쓰는 게 좋을 것 같음. (내 생각)
    - '확인, 취소, 닫기, 완료'처럼 명확하게 바뀌지 않을 요소들을 모든 페이지마다 각각 처리하게 되니까 ditto 중복이 심하게 많음..
// ex) 홈, 마이페이지, 설정 화면에 '닫기'버튼이 모두 있는 경우
// base.json
"home-close":{
	"text" : "닫기",
	"api-id" : "home-close",
    "variants" : {
    	"kr-ko" : {"text" : "닫기"},
        "us-en" : {"text" : "Close"},
    }
},
"myPage-close":{
	"text" : "닫기",
	"api-id" : "myPage-close",
    "variants" : {
    	"kr-ko" : {"text" : "닫기"},
        "us-en" : {"text" : "Close"},
    }
},
"settings-close":{
	"text" : "닫기",
	"api-id" : "settings-close",
    "variants" : {
    	"kr-ko" : {"text" : "닫기"},
        "us-en" : {"text" : "Close"},
    }
},
// 바뀌지 않을 ditto 중복이 너무 많다.
// (내 생각 - 명확한 것은 요소를 공통 사용하고 혹시 앞뒤로 내용이 달라진다면 앞뒤의 새로운 요소만 추가하면 되지 않을까?)
"close":{
	"text" : "닫기",
	"api-id" : "close",
    "variants" : {
    	"kr-ko" : {"text" : "닫기"},
        "us-en" : {"text" : "Close"},
    }
},

  • 디토 error
    1) ditto 페이지, ditto json 전부 정상 적용된 상태인데 보여지는 출력 결과는 다른 경우가 2회정도 있었음.
    2) 이미 연결되어있는 figma페이지 ditto의 ui에 새로운 요소를 추가하거나 수정하면 거의 새로운 ditto id값으로 생성되지만, 가끔 기존 ditto 요소와 id가 꼬이거나, 기존 id가 삭제되는 경우가 있었음.
    → 이미 ditto를 모두 적용시켜둔 상태에서 이러한 에러가 발생하면,,,에러 메세지로 어느 ditto요소에서 에러가 발생했다고 말하지 않기 때문에, 어느 ditto의 id가 에러인건지 하나하나 찾아야 했음...(이게 가장 크리티컬 한 것 같다.)
    3) source json이 1개면 상관 없을 것 같은데, 2개 이상일 때에는 둘 중 하나의 ditto라도 없으면 에러가 발생한다. 꼭 모든 json을 체크할 것.
    (만약 둘 중 하나의 언어의 ditto 요소를 수정했는데, 거기서 2)번의 에러가 발생한다면...ㅎㅎ)

Ditto
Ditto Cli
Ditto SDK (ditto-react)

profile
Front-end

0개의 댓글