Etc

Copy right 자동 생성용 플러그인 만들기 (Webpack)

사내에서 프로젝트 진행시, 프로젝트 내 필요한 파일 추가시 copy right를 추가해야 해야하는 룰이 있다. 그런데 매번 작업자가 파일 생성시 copy right를 의식하지 않으면 누락이 되는 일이 발생하곤 했다. 이를 자동화하는 방법은 없을까 하다가, 최근 Tanstack router를 사용하면서
새로운 Route 파일 생성시 플러그인에 의해 routeTree.gen.ts 파일이 업데이트 되는 것에 영감을 받아 copy right 주석 생성용 플러그인을 만들어보게 되었다. (Tanstack router에 대한 자세한 내용은 다루지 않도록 하겠다.)

웹팩 플러그인 생성

우선 웹팩 문서를 참고 후, 플러그인 생성에 필요한 구성은 다음과 같다.

  • 사용하고자 하는 메인 함수 or 메인 클래스 생성
  • apply 메서드 추가
  • 특정 이벤트훅 추가
  • 필요한 나머지 메서드 추가

1. 메인 클래스 생성

class FileCreationWatcherPlugin {}

export default FileCreationWatcherPlugin;
  • 사용하고자 하는 플러그인을 클래스로 선언한다.

2. apply 메서드 추가


class FileCreationWatcherPlugin {
  apply(compiler) {
    ...
  }

}

export default FileCreationWatcherPlugin;
  • compiler를 인자로 받는 apply 메소드 추가
  • 해당 메소드는, 웹팩 컴파일러에에 의해 호출

3. 특정 이벤트훅 추가

class FileCreationWatcherPlugin {
  apply(compiler) {
    compiler.hooks.afterEnvironment.tap("FileCreationWatcherPlugin", () => {
      const dir = path.join(compiler.context);
      this.watchNewFiles(dir);
    });
  }
}

export default FileCreationWatcherPlugin;
  • 내 경우 컴파일러 환경 설정이 완료된 시점에 동작하는 라이프사이클 훅인 afterEnvironment 사용
  • 디렉토리를 감시하고자 하는 watchNewFiles 메서드에, 프로젝트 경로인 compiler.context 를 전달

4. 필요한 나머지 메서드 추가

import fs from "fs";
import path from "path";
import chokidar from "chokidar";

class FileCreationWatcherPlugin {
  constructor() {
    this.HEADER_COMMENT = `/** 이것은 주석입니다.
    * 
    */\n\n`;
  }

  apply(compiler) {
    compiler.hooks.afterEnvironment.tap("FileCreationWatcherPlugin", () => {
      const dir = path.join(compiler.context);
      this.watchNewFiles(dir);
    });
  }

  watchNewFiles(dir) {
    const watcher = chokidar.watch(dir, {
      ignored: [/(^|[\/\\])\../, "**/node_modules/**"],
      persistent: true,
      ignoreInitial: true,
    });

    watcher.oen("add", (filePath) => {
      const ext = path.extname(filePath);
      if (ext === ".ts" || ext === ".tsx") {
        this.addHeaderToFile(filePath);
      }
    });
  }

  addHeaderToFile(filePath) {
    const content = fs.readFileSync(filePath, "utf-8");
    if (!content.startsWith(this.HEADER_COMMENT)) {
      fs.writeFileSync(filePath, this.HEADER_COMMENT + content);
    }
  }
}

export default FileCreationWatcherPlugin;
  • watchNewFiles
    • chokidar 라이브러리를 통해 file watching
    • 파일이 추가가 될때마다 파일의 확장자가 .ts or .tsx 일 경우, addHeaderToFile 메서드가 호출될 수 있도록 리스너 추가
  • addHeaderToFile
    • 해당 파일이 HEADER_COMMENT string 값으로 시작하지 않을 경우, HEADER_COMMENT 추가

 

next.config.mjs 에 추가

import FileCreationWatcherPlugin from "./src/utils/FileCreationWatcherPlugin/index.js";

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  webpack: (config, { dev }) => {
    if (dev) {
      config.plugins.push(new FileCreationWatcherPlugin());
    }

    return { ...config };
  },
};

export default nextConfig;
  • Nextjs config 에서 기존 웹팩 설정에 필요한 플러그인 추가(문서 참고)
  • 개발 환경에서만 필요하므로, dev 환경일때만 동작하도록 조건문 추가

 

결과

image

 

Reference

'Etc' 카테고리의 다른 글

Page Object Models - Playwright  (0) 2023.10.16
소스맵 정리  (0) 2023.09.28
TTF, OTF 폰트별 특징  (0) 2023.07.28
리액트와 함께하는 테스트 격리(번역)  (0) 2023.04.17
TIL | Reflow, Repaint  (0) 2022.08.28