[mini project] - MDX Editor 만들기 (2) - NPM 배포
§1. 배포하려는 파일의 index.ts 파일 만들기
꼭 파일명이 index.ts 가 아니어도 좋다. 핵심은 배포하려는 대상을 한번에 호출하는 파일을 하나 만들어두는 것이다! 여기서는 이전에 만들었던 'MDXEditor' 를 호출했다. 패키지의 사용자가 import를 해야하므로 export 구문이 포함된다.
// src/components/index.ts
export { default as MDXEditor } from './MDXEditor/MDXEditor'
§2. Vite Config 설정
vite.config.ts
파일을 설정한다. build.lib
를 추가로 설정한 것이 핵심이다.
- rollupOptions: 여기서는 'React'를 썼는데, 실제 라이브러리에 현재 내가 쓴 React가 번들되지 않게 한 것이다. 만약 명시하지 않으면, 이 에디터를 다운받은 프로젝트의 환경의 React를 사용하지 않고, 현재 개발 때 쓰인 React가 쓰여 버전 차이, React 객체도 다름 등 여러가지 문제가 생긴다. vite 공식 문서 참고
- dts: index.d.ts 파일을 생성한다.
npm i -D vite-plugin-dts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import { resolve } from 'path'
import dts from 'vite-plugin-dts'
export default defineConfig({
plugins: [react(), dts()],
server: {
open: true,
port: 5173
},
build: {
lib: {
entry: resolve(__dirname, 'src/components/index.ts'),
name: 'index'
},
rollupOptions: {
external: ['react'],
output: {
globals: {
react: 'React'
}
}
}
}
})
그리고 npm run build
를 실행해보고, dist/index.js, dist/index.umd.cjs 파일이 생겼는지 확인한다.
여기서 파일 이름은 build.lib.name
을 기준으로 생성되었다.
§3. package.json 설정
이제 Package.json에 다음 3개의 필드에 대해서 추가/수정을 한 후에 배포하면 된다.
name
: "@[그룹명]/[프로젝트명]" 형식으로 정했다. 나중에 NPM에서 따로 그룹을 생성해야 한다.exports
: 'main', 'module' 필드대신 사용가능하다. 여러개의 Import Path를 지정할 수 있고, CJS, ESM 모듈에 모두 대응하여 Export 가 가능하다. 추가로, 'Easymde' 컴포넌트에서 쓰는 CSS가 있어서, 해당 파일도 같이 Export 했다. 이것을 해야지 node_modules에 파일을 import 할 수 있다.
{
"name": "@bearlee/mdx-editor",
"private": false,
"version": "1.0.0",
"type": "module",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/mdx-editor.js",
"require": "./dist/mdx-editor.umd.cjs"
},
"./style.css": "./dist/style.css"
}
}
다음은 CJS와 ESM의 차이와 이를 package.json에서 어떻게 다루는지 잘 설명한 글이라 같이 참조한다. commonjs-esm-exports-field
§4. 배포하기
.npmginore 파일이 없으면, 자동으로 .gitignore 파일을 npm은 인식해서 배포한다. 하지만 나는 깃허브에 올릴 소스랑 별개이기 때문에, .npmignore 파일을 생성했다. 그래야 내 패키지를 다운받은 node_modules 안에 다른 쓸떼없는 파일들이 안 들어간다.
§4-1. .npmignore
src
node_modules
.eslint*
.gitignore
.prettierrc.json
tsconfig*
vite*
index.html
package-lock.json
참고로 위에 node_modules를 포함했지만, 나중에 설치해보면 내 패키지 안에 node_modules가 존재한다. 이는 추측이지만 Easymde나 @mdx-js 같은 외부 라이브러리에 의존적이기 때문에 있는 것 같다.
§4-2. 그룹 생성
npm 사이트에 들어가서, 계정이 없다면 새로 생성한다. 그리고 그룹을 하나 생성한다. 나는 아까 내가 package.json의 name에서 지정한 'bearlee'라고 지었다.
§4-2. npm 배포
# 로그인
npm login
# 로그인 유저 확인
npm whoami
# 배포하기
npm publish --access public
짠 내가 생성한 프로젝트가 잘 배포된 것을 확인할 수 있다!
만일 재 배포하고 싶다면, package.json의 version을 변경한 후에 배포 명령어를 다시 입력하면 된다.
npm publish --access public
§5. 설치해보기
현재 내 블로그에서 설치하고, 호출해보는 것으로 결정했다! 먼저 패키지를 설치한다.
npm i @bearlee/mdx-editor
에디터라서 클라이언트 사이드로 작성하고...
'use client'
import { MDXEditor as LibMDXEditor } from '@bearlee/mdx-editor'
import { useEffect, useState } from 'react'
import '@bearlee/mdx-editor/style.css'
function Highlight({ children, color }: { children: React.ReactNode; color: string }) {
return (
<span
style={{
backgroundColor: color,
borderRadius: '2px',
color: '#fff',
padding: '0.2rem',
}}
>
{children}
</span>
)
}
export default function MDXEditor() {
const [isMounted, setIsMounted] = useState(false)
useEffect(() => {
setIsMounted(true)
}, [])
return isMounted ? <LibMDXEditor components={{ Highlight }} defaultValue='test!!' /> : 'Nope...'
}
실제로 호출하면, 짠 다음과 같이 나온다! 내 블로그의 css와 혼합되는 경우가 있어서 일부 css 변경했다.
§삭제
일반적으로 배포한 패키지는 72시간 내에 삭제하면 된다! 이후에는 삭제가 불가능하니 잘 확인하자. 72시간이 지나도 삭제가 가능한 경우는, 다음 3개의 조건을 모두 충족해야 한다.
- 내 패키지를 의존하는 패키지가 없을 경우
- 지난 주에 300 다운로드보다 낮게 받은 패키지의 경우
- 딱 한 명의 소유/유지보수 하는 사람만 있을 경우