node_modules 등 소스에서 관리되지 않는 영역의 모듈을 변경할 경우는 postinstall 스크립트를 사용하여 처리할 수 있다. 특히 node_modules 내에 존재하는 모듈 파일은 어플리케이션 빌드가 install 스크립트를 실행하는 경우, 초기화 되므로 동적인 스크립트를 사용하여 변경할 필요가 있다.

스크립트 생성

변경할 대상의 모듈 파일은 다음과 같이 프로젝트 내에 위치하고, node 스크립트를 사용하여 특정 경로의 모듈 파일을 replace하는 스크립트를 작성한다.

Untitled

위와 같이 프로젝트 경로 scripts 디렉토리 내에 replace 할 모듈 파일을 위치하고 (위의 이미지에서는 scripts/vectorx/treelist.ts 에 위치), install.mjs 파일을 추가한다.

install.mjs 파일 (ESM 유형)을 구동하기 위해서는 별도의 스크립트가 필요한데 이를 구동하는 역할을 하는 run.js는 다음과 같이 작성한다.

import { register } from 'node:module'
import { pathToFileURL } from 'node:url'

if (process.argv.length < 3) {
  console.warn('cannout found target module')
  process.exit(1)
}

const executionPath = process.argv[2]

register('@std/esm', pathToFileURL('./'))
import(executionPath)

작성된 내용을 보면 esm 모듈 구동을 위한 “@std/esm” 로더를 등록하고 argument로 유입된 스크립트를 구동하는 처리를 수행한다.

install.mjs 파일은 실제 node modules의 위치를 찾아 대체 파일로 replace 하는 로직을 작성한다.

import { resolve } from 'node:path'
import { copyFileSync } from 'node:fs'
import { fileURLToPath } from 'node:url'

const __dirname = fileURLToPath(new URL('.', import.meta.url))
const replaceFileSourcePath = resolve(__dirname, './vectorx/treelist.ts')
const replaceFileTargetPath = resolve(__dirname, '../node_modules/@vectorx/nuxt-kendo-ui/src/composables/treelist.ts')

copyFileSync(replaceFileSourcePath, replaceFileTargetPath)

위의 코드는 디렉토리의 내의 생성된 모듈 파일을 대상 디렉토리의 파일로 복사하는 코드이며, 각 모듈의 위치는 프로젝트 상황에 따라 조정할 필요가 있다.

스크립트 등록

위의 스크립트를 install 후에 자동 실행해야 하므로 package.json 내에 postinstall 스크립트를 다음과 같이 등록한다. postinstall 스크립트는 yarn 패키지 매니저에서 제공하는 Lifecycle Scripts이며, install 명령어 수행 후에 자동으로 스크립트이다.