모듈 작성자 가이드
Nuxt 애플리케이션을 통합, 향상 또는 확장하기 위한 Nuxt 모듈을 만드는 방법을 배워보세요.
Nuxt의 구성 및 훅 시스템을 통해 Nuxt의 모든 측면을 사용자 정의하고 필요한 모든 통합을 추가할 수 있습니다 (Vue 플러그인, CMS, 서버 경로, 컴포넌트, 로깅 등).
Nuxt 모듈은 nuxt dev
를 사용하여 개발 모드에서 Nuxt를 시작하거나 nuxt build
로 프로덕션을 위한 프로젝트를 빌드할 때 순차적으로 실행되는 함수입니다. 모듈을 사용하면 불필요한 보일러플레이트를 프로젝트에 추가하지 않고도 사용자 정의 솔루션을 npm 패키지로 캡슐화하고 적절히 테스트하며 공유할 수 있으며, Nuxt 자체에 대한 변경을 요구하지 않습니다.
빠른 시작
Nuxt 모듈을 시작하려면 스타터 템플릿을 사용하는 것을 권장합니다:
npm create nuxt -- -t module my-module
이렇게 하면 모듈을 개발하고 게시하는 데 필요한 모든 보일러플레이트가 포함된 my-module
프로젝트가 생성됩니다.
다음 단계:
- 원하는 IDE에서
my-module
을 엽니다. - 선호하는 패키지 관리자를 사용하여 종속성을 설치합니다.
npm run dev:prepare
를 사용하여 개발을 위한 로컬 파일을 준비합니다.- 이 문서를 따라 Nuxt 모듈에 대해 더 알아보세요.
스타터 사용하기
모듈 스타터로 기본 작업을 수행하는 방법을 배워보세요.
Nuxt 모듈 스타터 템플릿에 대한 Vue School 비디오를 시청하세요.
개발 방법
모듈 소스 코드는 src
디렉토리에 있지만, 대부분의 경우 모듈을 개발하려면 Nuxt 애플리케이션이 필요합니다. playground
디렉토리가 바로 그것입니다. 이는 모듈과 함께 실행되도록 이미 구성된 Nuxt 애플리케이션입니다.
다른 Nuxt 애플리케이션과 마찬가지로 playground와 상호작용할 수 있습니다.
npm run dev
로 개발 서버를 시작하면src
디렉토리에서 모듈을 변경할 때마다 자동으로 다시 로드됩니다.npm run dev:build
로 빌드합니다.
다른 모든 nuxt
명령은 playground
디렉토리에 대해 사용할 수 있습니다 (예: nuxt <COMMAND> playground
). 편의를 위해 package.json
내에 추가적인 dev:*
스크립트를 선언할 수 있습니다.
테스트 방법
모듈 스타터에는 기본 테스트 스위트가 포함되어 있습니다:
- ESLint로 구동되는 린터,
npm run lint
로 실행합니다. - Vitest로 구동되는 테스트 러너,
npm run test
또는npm run test:watch
로 실행합니다.
이 기본 테스트 전략을 필요에 맞게 확장할 수 있습니다.
빌드 방법
Nuxt 모듈은 @nuxt/module-builder
에서 제공하는 자체 빌더를 가지고 있습니다. 이 빌더는 구성 없이도 TypeScript를 지원하며, 자산이 다른 Nuxt 애플리케이션에 배포될 수 있도록 적절히 번들링되도록 보장합니다.
npm run prepack
을 실행하여 모듈을 빌드할 수 있습니다.
모듈을 빌드하는 것이 유용한 경우도 있지만, 대부분의 경우 직접 빌드할 필요는 없습니다. 개발 중에는 playground
가 이를 처리하며, 게시할 때도 릴리스 스크립트가 이를 처리합니다.
게시 방법
모듈을 npm에 게시하기 전에 npmjs.com 계정이 있고, npm login
으로 로컬에서 인증되었는지 확인하세요.
모듈의 버전을 올리고 npm publish
명령을 사용하여 모듈을 게시할 수 있지만, 모듈 스타터에는 모듈의 작동 버전을 npm에 게시할 수 있도록 도와주는 릴리스 스크립트가 포함되어 있습니다.
릴리스 스크립트를 사용하려면 먼저 모든 변경 사항을 커밋하세요 (자동 버전 증가 및 변경 로그 업데이트를 활용하기 위해 Conventional Commits를 따르는 것을 권장합니다). 그런 다음 npm run release
로 릴리스 스크립트를 실행하세요.
릴리스 스크립트를 실행하면 다음이 수행됩니다:
- 먼저 테스트 스위트를 실행합니다:
- 린터 실행 (
npm run lint
) - 단위, 통합, e2e 테스트 실행 (
npm run test
) - 모듈 빌드 (
npm run prepack
)
- 린터 실행 (
- 그런 다음 테스트 스위트가 잘 진행되면 모듈을 게시합니다:
- 모듈 버전을 올리고 Conventional Commits에 따라 변경 로그를 생성합니다.
- 모듈을 npm에 게시합니다 (이를 위해 모듈은 게시된 아티팩트에 업데이트된 버전 번호가 반영되도록 다시 빌드됩니다).
- 새로 게시된 버전을 나타내는 git 태그를 git 원격 저장소에 푸시합니다.
다른 스크립트와 마찬가지로, 필요에 맞게 package.json
의 기본 release
스크립트를 조정할 수 있습니다.
모듈 개발
Nuxt 모듈은 Nuxt 애플리케이션을 거의 모든 방식으로 변경할 수 있는 다양한 강력한 API와 패턴을 제공합니다. 이 섹션에서는 이를 활용하는 방법을 배웁니다.
모듈 해부
Nuxt 모듈은 두 가지 종류로 나눌 수 있습니다:
- 게시된 모듈은 npm에 배포됩니다 - Nuxt 웹사이트에서 일부 커뮤니티 모듈 목록을 볼 수 있습니다.
- "로컬" 모듈은 Nuxt 프로젝트 자체 내에 존재하며, Nuxt 구성에 인라인되거나
modules
디렉토리의 일부로 존재합니다.
어느 경우든 그 해부학은 유사합니다.
모듈 정의
스타터를 사용할 때, 모듈 정의는 src/module.ts
에 있습니다.
모듈 정의는 모듈의 진입점입니다. 이는 Nuxt 구성 내에서 모듈이 참조될 때 Nuxt에 의해 로드됩니다.
낮은 수준에서, Nuxt 모듈 정의는 인라인 사용자 옵션과 Nuxt와 상호작용하기 위한 nuxt
객체를 수락하는 간단한, 잠재적으로 비동기적인 함수입니다.
export default function (inlineOptions, nuxt) {
// 여기서 원하는 작업을 수행할 수 있습니다.
console.log(inlineOptions.token) // `123`
console.log(nuxt.options.dev) // `true` 또는 `false`
nuxt.hook('ready', async nuxt => {
console.log('Nuxt is ready')
})
}
이 함수에 대한 타입 힌트 지원을 받으려면 Nuxt Kit에서 제공하는 상위 수준의 defineNuxtModule
헬퍼를 사용할 수 있습니다.
import { defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule((options, nuxt) => {
nuxt.hook('pages:extend', pages => {
console.log(`Discovered ${pages.length} pages`)
})
})
그러나, 이 낮은 수준의 함수 정의를 사용하는 것을 권장하지 않습니다. 대신, 모듈을 정의할 때, 특히 npm에 게시할 때 모듈을 식별하기 위해 meta
속성이 있는 객체 구문을 사용하는 것을 권장합니다.
이 헬퍼는 모듈 작성자와 사용자 모두에게 경험을 개선하고, 모듈의 미래 호환성을 보장하며, 모듈에 필요한 많은 일반적인 패턴을 구현하여 Nuxt 모듈을 더 쉽게 작성할 수 있게 합니다.
import { defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
meta: {
// 보통 모듈의 npm 패키지 이름
name: '@nuxtjs/example',
// 모듈 옵션을 보유하는 `nuxt.config`의 키
configKey: 'sample',
// 호환성 제약 조건
compatibility: {
// 지원되는 nuxt 버전의 Semver 버전
nuxt: '>=3.0.0'
}
},
// 모듈의 기본 구성 옵션, 이러한 옵션을 반환하는 함수일 수도 있습니다.
defaults: {},
// Nuxt 훅을 등록하기 위한 간단한 방법
hooks: {},
// 모듈 로직을 보유하는 함수, 비동기일 수 있습니다.
setup(moduleOptions, nuxt) {
// ...
}
})
궁극적으로 defineNuxtModule
은 낮은 수준의 (inlineOptions, nuxt)
모듈 서명을 가진 래퍼 함수를 반환합니다. 이 래퍼 함수는 setup
함수를 호출하기 전에 기본값 및 기타 필요한 단계를 적용합니다:
- 모듈 옵션을 자동으로 병합하기 위해
defaults
및meta.configKey
지원 - 타입 힌트 및 자동 타입 추론
- 기본 Nuxt 2 호환성을 위한 셰임 추가
meta.name
또는meta.configKey
에서 계산된 고유 키를 사용하여 모듈이 한 번만 설치되도록 보장- Nuxt 훅 자동 등록
- 모듈 메타 기반의 호환성 문제 자동 확인
- Nuxt의 내부 사용을 위한
getOptions
및getMeta
노출 - 최신 버전의
@nuxt/kit
에서defineNuxtModule
을 사용하는 한, 하위 및 상위 호환성 보장 - 모듈 빌더 도구와의 통합
런타임 디렉토리
스타터를 사용할 때, 런타임 디렉토리는 src/runtime
에 있습니다.
모듈은 Nuxt 구성의 모든 것처럼 애플리케이션 런타임에 포함되지 않습니다. 그러나 모듈이 설치된 애플리케이션에 런타임 코드를 제공하거나 주입하고 싶을 수 있습니다. 런타임 디렉토리는 이를 가능하게 합니다.
런타임 디렉토리 내에서 Nuxt 앱과 관련된 모든 종류의 자산을 제공할 수 있습니다:
- Vue 컴포넌트
- Composables
- Nuxt 플러그인
서버 엔진 Nitro에:
- API 경로
- 미들웨어
- Nitro 플러그인
또는 사용자의 Nuxt 애플리케이션에 주입하고 싶은 다른 종류의 자산:
- 스타일시트
- 3D 모델
- 이미지
- 등등
그런 다음 모듈 정의에서 애플리케이션 내에 이러한 모든 자산을 주입할 수 있습니다.
레시피 섹션에서 자산 주입에 대해 더 알아보세요.
게시된 모듈은 런타임 디렉토리 내의 자산에 대한 자동 가져오기를 활용할 수 없습니다. 대신 #imports
또는 유사한 경로에서 명시적으로 가져와야 합니다.
:br :br
실제로, 성능상의 이유로 node_modules
내의 파일에 대해 자동 가져오기가 활성화되지 않습니다 (게시된 모듈이 결국 위치하게 될 장소).
도구
모듈은 개발을 돕기 위한 일련의 1차 도구를 제공합니다.
@nuxt/module-builder
Nuxt Module Builder는 모듈을 빌드하고 배포하는 데 필요한 모든 무거운 작업을 처리하는 제로 구성 빌드 도구입니다. 이는 Nuxt 애플리케이션과의 모듈 빌드 아티팩트의 적절한 호환성을 보장합니다.
@nuxt/kit
Nuxt Kit는 모듈이 Nuxt 애플리케이션과 상호작용할 수 있도록 돕는 컴포저블 유틸리티를 제공합니다. 가능한 경우 수동 대안보다 Nuxt Kit 유틸리티를 사용하는 것이 모듈의 호환성과 코드 가독성을 보장하는 데 권장됩니다.
이것도 참고 guide > going-further > kit@nuxt/test-utils
Nuxt Test Utils는 모듈 테스트 내에서 Nuxt 애플리케이션을 설정하고 실행하는 데 도움을 주는 유틸리티 모음입니다.
레시피
모듈을 작성하는 데 사용되는 일반적인 패턴을 여기에서 찾을 수 있습니다.
Nuxt 구성 변경
Nuxt 구성은 모듈에 의해 읽고 변경될 수 있습니다. 다음은 실험적 기능을 활성화하는 모듈의 예입니다.
import { defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup (options, nuxt) {
// `experimental` 객체가 아직 존재하지 않는 경우 생성합니다.
nuxt.options.experimental ||= {}
nuxt.options.experimental.componentIslands = true
}
})
더 복잡한 구성 변경을 처리해야 할 때는 defu를 사용하는 것을 고려해야 합니다.
Nuxt 구성 변경에 대한 Vue School 비디오를 시청하세요.
런타임에 옵션 노출
모듈은 애플리케이션 런타임의 일부가 아니므로, 모듈의 옵션도 그렇지 않습니다. 그러나 많은 경우 런타임 코드 내에서 이러한 모듈 옵션 중 일부에 액세스해야 할 수 있습니다. Nuxt의 runtimeConfig
를 사용하여 필요한 구성을 노출하는 것을 권장합니다.
import { defineNuxtModule } from '@nuxt/kit'
import { defu } from 'defu'
export default defineNuxtModule({
setup (options, nuxt) {
nuxt.options.runtimeConfig.public.myModule = defu(nuxt.options.runtimeConfig.public.myModule, {
foo: options.foo
})
}
})
사용자가 제공한 공개 런타임 구성을 덮어쓰지 않고 확장하기 위해 defu
를 사용합니다.
그런 다음 플러그인, 컴포넌트, 애플리케이션에서 다른 런타임 구성처럼 모듈 옵션에 액세스할 수 있습니다:
const options = useRuntimeConfig().public.myModule
공개 런타임 구성에 민감한 모듈 구성을 노출하지 않도록 주의하세요. 예를 들어, 비공개 API 키는 공개 번들에 포함될 수 있습니다.
Nuxt 모듈 옵션 전달 및 노출에 대한 Vue School 비디오를 시청하세요.
addPlugin
으로 플러그인 주입
플러그인은 모듈이 런타임 로직을 추가하는 일반적인 방법입니다. addPlugin
유틸리티를 사용하여 모듈에서 플러그인을 등록할 수 있습니다.
import { defineNuxtModule, addPlugin, createResolver } from '@nuxt/kit'
export default defineNuxtModule({
setup (options, nuxt) {
// 상대 경로를 해결하기 위한 리졸버 생성
const resolver = createResolver(import.meta.url)
addPlugin(resolver.resolve('./runtime/plugin'))
}
})
이것도 참고 guide > going-further > kit
addComponent
로 Vue 컴포넌트 주입
모듈이 Vue 컴포넌트를 제공해야 하는 경우, addComponent
유틸리티를 사용하여 Nuxt가 해결할 수 있도록 자동 가져오기로 추가할 수 있습니다.
import { defineNuxtModule, addComponent } from '@nuxt/kit'
export default defineNuxtModule({
setup(options, nuxt) {
const resolver = createResolver(import.meta.url)
// 런타임 디렉토리에서
addComponent({
name: 'MySuperComponent', // vue 템플릿에서 사용될 컴포넌트 이름
export: 'MySuperComponent', // (선택 사항) 컴포넌트가 명명된 (기본이 아닌) 내보내기인 경우
filePath: resolver.resolve('runtime/components/MySuperComponent.vue')
})
// 라이브러리에서
addComponent({
name: 'MyAwesomeComponent', // vue 템플릿에서 사용될 컴포넌트 이름
export: 'MyAwesomeComponent', // (선택 사항) 컴포넌트가 명명된 (기본이 아닌) 내보내기인 경우
filePath: '@vue/awesome-components'
})
}
})
또한 addComponentsDir
을 사용하여 전체 디렉토리를 추가할 수 있습니다.
import { defineNuxtModule, addComponentsDir } from '@nuxt/kit'
export default defineNuxtModule({
setup(options, nuxt) {
const resolver = createResolver(import.meta.url)
addComponentsDir({
path: resolver.resolve('runtime/components')
})
}
})
addImports
및 addImportsDir
로 Composables 주입
모듈이 composables를 제공해야 하는 경우, addImports
유틸리티를 사용하여 Nuxt가 해결할 수 있도록 자동 가져오기로 추가할 수 있습니다.
import { defineNuxtModule, addImports, createResolver } from '@nuxt/kit'
export default defineNuxtModule({
setup(options, nuxt) {
const resolver = createResolver(import.meta.url)
addImports({
name: 'useComposable', // 사용될 composable의 이름
as: 'useComposable',
from: resolver.resolve('runtime/composables/useComposable') // composable의 경로
})
}
})
또한 addImportsDir
을 사용하여 전체 디렉토리를 추가할 수 있습니다.
import { defineNuxtModule, addImportsDir, createResolver } from '@nuxt/kit'
export default defineNuxtModule({
setup(options, nuxt) {
const resolver = createResolver(import.meta.url)
addImportsDir(resolver.resolve('runtime/composables'))
}
})
addServerHandler
로 서버 경로 주입
import { defineNuxtModule, addServerHandler, createResolver } from '@nuxt/kit'
export default defineNuxtModule({
setup(options, nuxt) {
const resolver = createResolver(import.meta.url)
addServerHandler({
route: '/api/hello',
handler: resolver.resolve('./runtime/server/api/hello/index.get')
})
}
})
동적 서버 경로도 추가할 수 있습니다:
import { defineNuxtModule, addServerHandler, createResolver } from '@nuxt/kit'
export default defineNuxtModule({
setup(options, nuxt) {
const resolver = createResolver(import.meta.url)
addServerHandler({
route: '/api/hello/:name',
handler: resolver.resolve('./runtime/server/api/hello/[name].get')
})
}
})
다른 자산 주입
모듈이 다른 종류의 자산을 제공해야 하는 경우, 이를 주입할 수도 있습니다. 다음은 Nuxt의 css
배열을 통해 스타일시트를 주입하는 간단한 예제 모듈입니다.
import { defineNuxtModule, addPlugin, createResolver } from '@nuxt/kit'
export default defineNuxtModule({
setup (options, nuxt) {
const resolver = createResolver(import.meta.url)
nuxt.options.css.push(resolver.resolve('./runtime/style.css'))
}
})
그리고 Nitro의 publicAssets
옵션을 통해 자산 폴더를 노출하는 더 고급 예제입니다:
import { defineNuxtModule, createResolver } from '@nuxt/kit'
export default defineNuxtModule({
setup (options, nuxt) {
const resolver = createResolver(import.meta.url)
nuxt.hook('nitro:config', async (nitroConfig) => {
nitroConfig.publicAssets ||= []
nitroConfig.publicAssets.push({
dir: resolver.resolve('./runtime/public'),
maxAge: 60 * 60 * 24 * 365 // 1년
})
})
}
})
모듈 내에서 다른 모듈 사용
모듈이 다른 모듈에 의존하는 경우, Nuxt Kit의 installModule
유틸리티를 사용하여 추가할 수 있습니다. 예를 들어, 모듈 내에서 Nuxt Tailwind를 사용하려면 아래와 같이 추가할 수 있습니다:
import { defineNuxtModule, createResolver, installModule } from '@nuxt/kit'
export default defineNuxtModule<ModuleOptions>({
async setup (options, nuxt) {
const resolver = createResolver(import.meta.url)
// Tailwind의 지시어를 포함하는 CSS 파일을 주입할 수 있습니다.
nuxt.options.css.push(resolver.resolve('./runtime/assets/styles.css'))
await installModule('@nuxtjs/tailwindcss', {
// 모듈 구성
exposeConfig: true,
config: {
darkMode: 'class',
content: {
files: [
resolver.resolve('./runtime/components/**/*.{vue,mjs,ts}'),
resolver.resolve('./runtime/*.{mjs,js,ts}')
]
}
}
})
}
})
훅 사용
라이프사이클 훅을 사용하면 Nuxt의 거의 모든 측면을 확장할 수 있습니다. 모듈은 프로그래밍 방식으로 또는 정의 내의 hooks
맵을 통해 훅에 연결할 수 있습니다.
import { defineNuxtModule, addPlugin, createResolver } from '@nuxt/kit'
export default defineNuxtModule({
// `hooks` 맵을 통해 `app:error` 훅에 연결
hooks: {
'app:error': (err) => {
console.info(`이 오류가 발생했습니다: ${err}`);
}
},
setup (options, nuxt) {
// 프로그래밍 방식으로 `pages:extend` 훅에 연결
nuxt.hook('pages:extend', (pages) => {
console.info(`발견된 페이지 수: ${pages.length}`);
})
}
})
이것도 참고 api > advanced > hooks
모듈에서 Nuxt 라이프사이클 훅을 사용하는 방법에 대한 Vue School 비디오를 시청하세요.
모듈 정리
:br
:br
모듈이 파일을 열거나, 핸들링하거나, 감시자를 시작하는 경우, Nuxt 라이프사이클이 완료되면 이를 닫아야 합니다. 이를 위해 close
훅이 제공됩니다.
import { defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
setup (options, nuxt) {
nuxt.hook('close', async nuxt => {
// 사용자 정의 코드
})
}
})
템플릿/가상 파일 추가
사용자의 앱에 가져올 수 있는 가상 파일을 추가해야 하는 경우, addTemplate
유틸리티를 사용할 수 있습니다.
import { defineNuxtModule, addTemplate } from '@nuxt/kit'
export default defineNuxtModule({
setup (options, nuxt) {
// 파일은 Nuxt의 내부 가상 파일 시스템에 추가되며 '#build/my-module-feature.mjs'에서 가져올 수 있습니다.
addTemplate({
filename: 'my-module-feature.mjs',
getContents: () => 'export const myModuleFeature = () => "hello world !"'
})
}
})
서버의 경우, addServerTemplate
유틸리티를 대신 사용해야 합니다.
import { defineNuxtModule, addServerTemplate } from '@nuxt/kit'
export default defineNuxtModule({
setup (options, nuxt) {
// 파일은 Nitro의 가상 파일 시스템에 추가되며 서버 코드에서 'my-server-module.mjs'로 가져올 수 있습니다.
addServerTemplate({
filename: 'my-server-module.mjs',
getContents: () => 'export const myServerModule = () => "hello world !"'
})
}
})
타입 선언 추가
사용자의 프로젝트에 타입 선언을 추가하고 싶을 수도 있습니다 (예: Nuxt 인터페이스를 확장하거나 자체 글로벌 타입을 제공하기 위해). 이를 위해 Nuxt는 addTypeTemplate
유틸리티를 제공하여 디스크에 템플릿을 작성하고 생성된 nuxt.d.ts
파일에 참조를 추가합니다.
모듈이 Nuxt에서 처리하는 타입을 확장해야 하는 경우, addTypeTemplate
을 사용하여 이 작업을 수행할 수 있습니다:
import { defineNuxtModule, addTemplate, addTypeTemplate } from '@nuxt/kit'
export default defineNuxtModule({
setup (options, nuxt) {
addTypeTemplate({
filename: 'types/my-module.d.ts',
getContents: () => `// Generated by my-module
interface MyModuleNitroRules {
myModule?: { foo: 'bar' }
}
declare module 'nitropack' {
interface NitroRouteRules extends MyModuleNitroRules {}
interface NitroRouteConfig extends MyModuleNitroRules {}
}
export {}`
})
}
})
더 세밀한 제어가 필요한 경우, prepare:types
훅을 사용하여 타입을 주입할 콜백을 등록할 수 있습니다.
const template = addTemplate({ /* template options */ })
nuxt.hook('prepare:types', ({ references }) => {
references.push({ path: template.dst })
})
템플릿 업데이트
템플릿/가상 파일을 업데이트해야 하는 경우, updateTemplates
유틸리티를 다음과 같이 활용할 수 있습니다:
nuxt.hook('builder:watch', async (event, path) => {
if (path.includes('my-module-feature.config')) {
// 등록한 템플릿을 다시 로드합니다.
updateTemplates({ filter: t => t.filename === 'my-module-feature.mjs' })
}
})
테스트
테스트는 모듈이 다양한 설정에서 예상대로 작동하는지 확인하는 데 도움이 됩니다. 이 섹션에서는 모듈에 대해 다양한 종류의 테스트를 수행하는 방법을 알아봅니다.
단위 및 통합
Nuxt 모듈에 대한 단위 및 통합 테스트를 용이하게 하는 방법을 논의하고 탐색 중입니다. :br :br 이 RFC를 확인하여 대화에 참여하세요.
엔드 투 엔드
Nuxt Test Utils는 모듈을 엔드 투 엔드 방식으로 테스트하는 데 도움이 되는 라이브러리입니다. 다음은 이를 사용하는 워크플로우입니다:
- "고정물"로 사용될 Nuxt 애플리케이션을
test/fixtures/*
에 생성합니다. - 테스트 파일 내에서 이 고정물로 Nuxt를 설정합니다.
@nuxt/test-utils
의 유틸리티를 사용하여 고정물과 상호작용합니다 (예: 페이지 가져오기).- 이 고정물과 관련된 검사를 수행합니다 (예: "HTML에 ... 포함").
- 반복합니다.
실제로, 고정물:
// 1. "고정물"로 사용될 Nuxt 애플리케이션 생성
import MyModule from '../../../src/module'
export default defineNuxtConfig({
ssr: true,
modules: [
MyModule
]
})
그리고 그 테스트:
import { describe, it, expect } from 'vitest'
import { fileURLToPath } from 'node:url'
import { setup, $fetch } from '@nuxt/test-utils/e2e'
describe('ssr', async () => {
// 2. 테스트 파일 내에서 이 고정물로 Nuxt 설정
await setup({
rootDir: fileURLToPath(new URL('./fixtures/ssr', import.meta.url)),
})
it('인덱스 페이지를 렌더링합니다', async () => {
// 3. `@nuxt/test-utils`의 유틸리티를 사용하여 고정물과 상호작용
const html = await $fetch('/')
// 4. 이 고정물과 관련된 검사 수행
expect(html).toContain('<div>ssr</div>')
})
})
// 5. 반복
describe('csr', async () => { /* ... */ })
이러한 워크플로우의 예는 모듈 스타터에서 확인할 수 있습니다.
Playground 및 외부에서 수동 QA
모듈을 개발할 때 테스트할 수 있는 Playground Nuxt 애플리케이션을 갖는 것은 매우 유용합니다. 모듈 스타터는 이를 위한 하나를 통합합니다.
다른 Nuxt 애플리케이션 (모듈 저장소의 일부가 아닌 애플리케이션)과 함께 로컬에서 모듈을 테스트할 수 있습니다. 이를 위해 npm pack
명령 또는 패키지 관리자에 해당하는 명령을 사용하여 모듈에서 tarball을 생성할 수 있습니다. 그런 다음 테스트 프로젝트에서 package.json
패키지에 모듈을 다음과 같이 추가할 수 있습니다: "my-module": "file:/path/to/tarball.tgz"
.
그 후, 일반 프로젝트에서처럼 my-module
을 참조할 수 있어야 합니다.
모범 사례
큰 힘에는 큰 책임이 따릅니다. 모듈은 강력하지만, 모듈을 작성할 때 애플리케이션의 성능과 개발자 경험을 유지하기 위해 염두에 두어야 할 몇 가지 모범 사례가 있습니다.
비동기 모듈
앞서 보았듯이 Nuxt 모듈은 비동기일 수 있습니다. 예를 들어, 일부 API를 가져오거나 비동기 함수를 호출해야 하는 모듈을 개발할 수 있습니다.
그러나 비동기 동작에 주의해야 합니다. Nuxt는 모듈이 설정될 때까지 기다린 후 다음 모듈로 이동하고 개발 서버, 빌드 프로세스 등을 시작합니다. 시간이 많이 소요되는 로직은 Nuxt 훅으로 연기하는 것이 좋습니다.
모듈 설정에 1초 이상 걸리면 Nuxt는 이에 대한 경고를 표시합니다.
노출된 인터페이스에 항상 접두사 추가
Nuxt 모듈은 다른 모듈 및 내부와의 충돌을 피하기 위해 노출된 구성, 플러그인, API, composable 또는 컴포넌트에 명시적인 접두사를 제공해야 합니다.
이상적으로는 모듈의 이름으로 접두사를 붙여야 합니다 (예: 모듈 이름이 nuxt-foo
인 경우 <FooButton>
및 useFooBar()
를 노출하고 <Button>
및 useBar()
를 노출하지 않습니다).
TypeScript 친화적이어야 함
Nuxt는 최고의 개발자 경험을 위해 TypeScript 통합을 제공합니다.
타입을 노출하고 TypeScript를 사용하여 모듈을 개발하면 TypeScript를 직접 사용하지 않더라도 사용자에게 이점을 제공합니다.
CommonJS 구문 피하기
Nuxt는 네이티브 ESM을 사용합니다. 자세한 내용은 네이티브 ES 모듈을 참조하세요.
모듈 사용법 문서화
모듈 사용법을 readme 파일에 문서화하는 것을 고려하세요:
- 이 모듈을 사용하는 이유는 무엇인가요?
- 이 모듈을 어떻게 사용하나요?
- 이 모듈은 무엇을 하나요?
통합 웹사이트 및 문서에 링크하는 것은 항상 좋은 생각입니다.
StackBlitz 데모 또는 보일러플레이트 제공
모듈과 함께 최소한의 재현을 만들고 StackBlitz에 추가하는 것이 좋은 관행입니다.
이는 모듈의 잠재적 사용자가 모듈을 빠르고 쉽게 실험할 수 있는 방법을 제공할 뿐만 아니라, 문제가 발생했을 때 최소한의 재현을 만들어 보낼 수 있는 쉬운 방법을 제공합니다.
특정 Nuxt 버전으로 광고하지 않기
Nuxt, Nuxt Kit 및 기타 새로운 도구는 모두 전방 및 후방 호환성을 염두에 두고 만들어졌습니다.
생태계의 단편화를 피하기 위해 "Nuxt 3용 X" 대신 "Nuxt용 X"를 사용하고, Nuxt 버전 제약 조건을 설정하기 위해 meta.compatibility
를 사용하는 것이 좋습니다.
스타터 기본값 유지
모듈 스타터는 기본 도구 및 구성 세트를 제공합니다 (예: ESLint 구성). 모듈을 오픈 소스로 공개할 계획이라면, 이러한 기본값을 유지하면 모듈이 다른 커뮤니티 모듈과 일관된 코딩 스타일을 공유하여 다른 사람들이 기여하기 쉽게 만듭니다.
생태계
Nuxt 모듈 생태계는 매월 1,500만 개 이상의 NPM 다운로드를 나타내며 모든 종류의 도구와의 확장 기능 및 통합을 제공합니다. 이 생태계의 일부가 될 수 있습니다!
Nuxt 모듈 유형에 대한 Vue School 비디오를 시청하세요.
모듈 유형
공식 모듈은 @nuxt/
로 접두사가 붙은 모듈입니다 (예: @nuxt/content
). Nuxt 팀에 의해 만들어지고 적극적으로 유지 관리됩니다. 프레임워크와 마찬가지로, 커뮤니티의 기여는 더 나은 모듈을 만드는 데 도움이 되므로 환영합니다!
커뮤니티 모듈은 @nuxtjs/
로 접두사가 붙은 모듈입니다 (예: @nuxtjs/tailwindcss
). 커뮤니티 구성원이 만들고 유지 관리하는 검증된 모듈입니다. 마찬가지로, 누구나 기여할 수 있습니다.
서드 파티 및 기타 커뮤니티 모듈은 종종 nuxt-
로 접두사가 붙은 모듈입니다. 누구나 만들 수 있으며, 이 접두사를 사용하면 npm에서 이러한 모듈을 검색할 수 있습니다. 아이디어를 초안하고 시도하는 데 가장 좋은 출발점입니다!
비공개 또는 개인 모듈은 자신의 사용 사례나 회사에 맞게 만든 모듈입니다. Nuxt와 함께 작동하기 위해 특정 명명 규칙을 따를 필요가 없으며, 종종 npm 조직 (예: @my-company/nuxt-auth
) 아래에 범위가 지정됩니다.
커뮤니티 모듈 목록에 추가
모든 커뮤니티 모듈은 모듈 목록에 추가될 수 있습니다. 목록에 추가하려면 nuxt/modules 저장소에 이슈를 열어주세요. Nuxt 팀은 목록에 추가하기 전에 모범 사례를 적용하는 데 도움을 줄 수 있습니다.
nuxt-modules
및 @nuxtjs/
에 가입하기
모듈을 nuxt-modules로 이동하면 항상 도움을 줄 수 있는 다른 사람이 있으며, 이를 통해 완벽한 솔루션을 만들기 위해 힘을 합칠 수 있습니다.
이미 게시되고 작동하는 모듈이 있고, 이를 nuxt-modules
로 이전하고 싶다면, nuxt/modules에 이슈를 열어주세요.
nuxt-modules
에 가입하면 커뮤니티 모듈을 @nuxtjs/
범위로 이름을 변경하고 문서를 위한 하위 도메인 (예: my-module.nuxtjs.org
)을 제공할 수 있습니다.
※이 페이지는 Nuxt.js 공식 문서의 비공식 번역 페이지입니다.
공식 문서의 해당 페이지는 여기 있습니다:
https://nuxt.com/docs/3.x/guide/going-further/modules