Skip to content

WXT 모듈

WXT는 빌드 프로세스의 다양한 단계에서 코드를 실행하여 수정할 수 있는 "모듈 시스템"을 제공합니다.

모듈 추가하기

프로젝트에 모듈을 추가하는 방법은 두 가지가 있습니다.

  1. NPM: @wxt-dev/auto-icons와 같은 NPM 패키지를 설치하고 설정 파일에 추가합니다.

    ts
    // wxt.config.ts
    export default defineConfig({
      modules: ['@wxt-dev/auto-icons'],
    });

    NPM에서 "wxt module"을 검색하면 공개된 WXT 모듈을 찾는 데 도움이 됩니다.

  2. 로컬: 프로젝트의 modules/ 디렉토리에 파일을 추가합니다.

    <srcDir>/
      modules/
        my-module.ts

    직접 모듈을 작성하는 방법에 대해 더 알아보려면 모듈 작성하기 문서를 참고하세요.

모듈 옵션

WXT 모듈은 동작을 변경하기 위해 커스텀 옵션 설정을 요구하거나 허용할 수 있습니다. 옵션은 두 가지 유형으로 나뉩니다:

  1. 빌드 타임: 빌드 과정에서 사용되는 설정, 예를 들어 기능 플래그
  2. 런타임: 런타임에 접근되는 설정, 예를 들어 콜백 함수

빌드 타임 옵션은 wxt.config.ts 파일에 위치하며, 런타임 옵션은 app.config.ts 파일에 위치합니다. 각 모듈의 문서를 참조하여 어떤 옵션이 필요한지, 그리고 어디에 위치해야 하는지 확인하세요.

TypeScript를 사용하는 경우, 모듈은 WXT의 타입을 확장하므로 옵션이 누락되거나 잘못된 경우 타입 에러가 발생합니다.

실행 순서

모듈은 훅이 실행되는 순서와 동일하게 로드됩니다. 자세한 내용은 훅 문서를 참고하세요.

모듈 작성하기

기본적인 WXT 모듈은 다음과 같이 작성합니다:

ts
import { defineWxtModule } from 'wxt/modules';

export default defineWxtModule({
  setup(wxt) {
    // 모듈 코드 작성...
  },
});

각 모듈의 setup 함수는 wxt.config.ts 파일이 로드된 후 실행됩니다. wxt 객체는 모듈 작성에 필요한 모든 것을 제공합니다:

  • wxt.hook(...)을 사용해 빌드 라이프사이클에 훅을 걸고 변경 사항을 적용
  • wxt.config로 프로젝트의 wxt.config.ts 파일에서 해석된 설정 가져오기
  • wxt.logger로 콘솔에 메시지 기록
  • 그리고 더 많은 기능!

사용 가능한 모든 속성과 함수 목록은 API 참조를 확인하세요.

또한 사용 가능한 모든 훅에 대해 꼭 읽어보세요. 이는 모듈 작성에 필수적입니다.

레시피

모듈은 복잡하며 WXT의 코드와 작동 방식을 깊이 이해해야 합니다. 가장 좋은 학습 방법은 예제를 통해 배우는 것입니다.

Update resolved config

ts
import { defineWxtModule } from 'wxt/modules';

export default defineWxtModule({
  setup(wxt) {
    wxt.hook('config:resolved', () => {
      wxt.config.outDir = 'dist';
    });
  },
});

빌드 타임 설정 추가

ts
import { defineWxtModule } from 'wxt/modules';
import 'wxt';

export interface MyModuleOptions {
  // 여기에 빌드 타임 옵션을 추가하세요...
}
declare module 'wxt' {
  export interface InlineConfig {
    // wxt.config.ts 파일의 "myModule" 키에 대한 타입을 추가하세요
    myModule: MyModuleOptions;
  }
}

export default defineWxtModule<AnalyticModuleOptions>({
  configKey: 'myModule',

  // 빌드 타임 설정은 setup 함수의 두 번째 인자로 사용 가능
  setup(wxt, options) {
    console.log(options);
  },
});

런타임 설정 추가하기

ts
import { defineWxtModule } from 'wxt/modules';
import 'wxt/sandbox';

export interface MyModuleRuntimeOptions {
  // 여기에 런타임 옵션을 추가하세요...
}
declare module 'wxt/sandbox' {
  export interface WxtAppConfig {
    myModule: MyModuleOptions;
  }
}

런타임 옵션은 아래와 같이 호출할 때 반환됩니다.

ts
const config = useAppConfig();
console.log(config.myModule);

이 기능은 런타임 모듈 생성하기에서 매우 유용합니다.

출력 파일 생성

ts
import { defineWxtModule } from 'wxt/modules';

export default defineWxtModule({
  setup(wxt) {
    // 출력 디렉토리 기준
    const generatedFilePath = 'some-file.txt';

    wxt.hook('build:publicAssets', (_, assets) => {
      assets.push({
        relativeDest: generatedFilePath,
        contents: 'some generated text',
      });
    });

    wxt.hook('build:manifestGenerated', (_, manifest) => {
      manifest.web_accessible_resources ??= [];
      manifest.web_accessible_resources.push({
        matches: ['*://*'],
        resources: [generatedFilePath],
      });
    });
  },
});

이 파일은 런타임에 다음과 같이 로드할 수 있습니다:

ts
const res = await fetch(browser.runtime.getURL('/some-text.txt'));

커스텀 엔트리포인트 추가하기

entrypoints/ 디렉토리 아래의 기존 파일들을 발견한 후, entrypoints:found 훅을 사용해 커스텀 엔트리포인트를 추가할 수 있습니다.

INFO

entrypoints:found 훅은 엔트리포인트 목록에 대한 검증이 수행되기 전에 트리거됩니다. 따라서 커스텀 엔트리포인트도 중복 이름 검사를 거치며, 디버깅 중에 로그로 기록됩니다.

ts
import { defineWxtModule } from 'wxt/modules';

export default defineWxtModule({
  setup(wxt) {
    wxt.hook('entrypoints:found', (_, entrypointInfos) => {
      // 새로운 엔트리포인트 추가
      entrypointInfos.push({
        name: 'my-custom-script',
        inputPath: 'path/to/custom-script.js',
        type: 'content-script',
      });
    });
  },
});

런타임 모듈 생성하기

.wxt 디렉토리에 파일을 생성하고, 별칭을 추가하여 가져오도록 설정한 뒤, 내보낸 변수에 대해 자동 가져오기를 추가합니다.

ts
import { defineWxtModule } from 'wxt/modules';
import { resolve } from 'node:path';

export default defineWxtModule({
  imports: [
    // 자동 가져오기 추가
    { from: '#analytics', name: 'analytics' },
    { from: '#analytics', name: 'reportEvent' },
    { from: '#analytics', name: 'reportPageView' },
  ],

  setup(wxt) {
    const analyticsModulePath = resolve(
      wxt.config.wxtDir,
      'analytics/index.ts',
    );
    const analyticsModuleCode = `
      import { createAnalytics } from 'some-module';

      export const analytics = createAnalytics(useAppConfig().analytics);
      export const { reportEvent, reportPageView } = analytics;
    `;

    addAlias(wxt, '#analytics', analyticsModulePath);

    wxt.hook('prepare:types', async (_, entries) => {
      entries.push({
        path: analyticsModulePath,
        text: analyticsModuleCode,
      });
    });
  },
});

선언 파일 생성하기

ts
import { defineWxtModule } from 'wxt/modules';
import { resolve } from 'node:path';

export default defineWxtModule({
  setup(wxt) {
    const typesPath = resolve(wxt.config.wxtDir, 'my-module/types.d.ts');
    const typesCode = `
      // 전역 타입 선언, 타입 확장 수행
    `;

    wxt.hook('prepare:types', async (_, entries) => {
      entries.push({
        path: 'my-module/types.d.ts',
        text: `
          // 전역 타입 선언, 타입 확장 등 수행
        `,
        // 중요 - 이 줄이 없으면 선언 파일이 TS 프로젝트에 포함되지 않음:
        tsReference: true,
      });
    });
  },
});

예제 모듈

다른 사람들이 작성하고 공개한 모듈 코드도 살펴보는 것이 좋습니다. 다음은 몇 가지 예제입니다: