Skip to content

엔트리포인트 ​

WXT는 확장 프로그램을 번들링할 때 entrypoints/ 디렉토리 내부의 파일을 입력으로 사용합니다. 이 파일들은 HTML, JS, CSS 또는 Vite에서 지원하는 파일 타입의 변형(Pug, TS, JSX, SCSS 등)일 수 있습니다.

다음은 엔트리포인트의 예제입니다:

html
📂 entrypoints/
   📂 popup/
      📄 index.html
      📄 main.ts
      📄 style.css
   📄 background.ts
   📄 content.ts

리스팅된 vs 언리스팅된 ​

웹 확장 프로그램에는 두 가지 타입의 진입점이 있습니다:

  • 리스팅된: manifest.json에서 참조됨
  • 언리스팅된: manifest.json에서 참조되지 않음

WXT 문서의 나머지 부분에서는 리스팅된 진입점을 이름으로 참조합니다. 예를 들어:

  • 팝업
  • 옵션
  • 백그라운드
  • 콘텐츠 스크립트
  • 기타

"언리스팅된" 진입점의 몇 가지 예시:

  • 확장 프로그램이 설치될 때 표시되는 환영 페이지
  • 콘텐츠 스크립트가 페이지의 메인 월드에 주입하는 JS 파일

TIP

진입점이 리스팅되었는지 언리스팅되었는지 여부와 상관없이, 모든 진입점은 확장 프로그램에 번들링되어 런타임에 사용 가능합니다.

엔트리포인트 추가하기 ​

엔트리포인트는 단일 파일 또는 내부에 index 파일이 있는 디렉토리로 정의할 수 있습니다.

html
📂 entrypoints/
   📄 background.ts
html
📂 entrypoints/
   📂 background/
      📄 index.ts

엔트리포인트의 이름은 엔트리포인트의 유형(목록에 포함된 것과 포함되지 않은 것)을 결정합니다. 이 예제에서 "background"는 "Background" 엔트리포인트의 이름입니다.

목록에 포함된 엔트리포인트와 해당 파일명 패턴의 전체 목록은 엔트리포인트 유형 섹션을 참조하세요.

Manifest 옵션 정의하기 ​

대부분의 엔트리포인트는 manifest.json에 추가해야 하는 옵션이 있습니다. 하지만 WXT를 사용하면 별도의 파일에 옵션을 정의하는 대신, _엔트리포인트 파일 내부에서 이 옵션들을 정의_합니다.

예를 들어, 콘텐츠 스크립트의 matches를 정의하는 방법은 다음과 같습니다:

ts
// entrypoints/content.ts
export default defineContentScript({
  matches: ['*://*.wxt.dev/*'],
  main() {
    // ...
  },
});

HTML 엔트리포인트의 경우, 옵션은 <meta> 태그로 설정됩니다. 예를 들어, MV2 팝업에 page_action을 사용하려면 다음과 같이 작성합니다:

html
<!doctype html>
<html lang="en">
  <head>
    <meta name="manifest.type" content="page_action" />
  </head>
</html>

각 엔트리포인트 내부에서 설정 가능한 옵션 목록과 정의 방법은 엔트리포인트 타입 섹션을 참고하세요.

확장 프로그램을 빌드할 때, WXT는 엔트리포인트에 정의된 옵션을 확인하고 그에 따라 manifest를 생성합니다.

Entrypoint Types ​

백그라운드 ​

Chrome Docs • Firefox Docs

MV2에서는 백그라운드 스크립트가 백그라운드 페이지에 추가됩니다. MV3에서는 백그라운드가 서비스 워커로 변경됩니다.

FilenameOutput Path
entrypoints/background.[jt]s/background.js
entrypoints/background/index.[jt]s/background.js
ts
export default defineBackground(() => {
  // 백그라운드가 로드될 때 실행됨
});
ts
export default defineBackground({
  // 매니페스트 옵션 설정
  persistent: undefined | true | false,
  type: undefined | 'module',

  // 특정 빌드에서 백그라운드를 제거해야 할 경우 include/exclude 설정
  include: undefined | string[],
  exclude: undefined | string[],

  main() {
    // 백그라운드가 로드될 때 실행됨, 비동기로 사용 불가
  },
});

북마크 ​

Chrome Docs • Firefox Docs

FilenameOutput Path
entrypoints/bookmarks.html/bookmarks.html
entrypoints/bookmarks/index.html/bookmarks.html
html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Title</title>
    <!-- 특정 빌드에서 페이지를 제외하거나 포함하려면 include/exclude를 설정하세요 -->
    <meta name="manifest.include" content="['chrome', ...]" />
    <meta name="manifest.exclude" content="['chrome', ...]" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

콘텐츠 스크립트 ​

Chrome Docs • Firefox Docs

콘텐츠 스크립트에서 UI 생성 및 CSS 포함에 대한 자세한 내용은 콘텐츠 스크립트 UI를 참고하세요.

FilenameOutput Path
entrypoints/content.[jt]sx?/content-scripts/content.js
entrypoints/content/index.[jt]sx?/content-scripts/content.js
entrypoints/<name>.content.[jt]sx?/content-scripts/<name>.js
entrypoints/<name>.content/index.[jt]sx?/content-scripts/<name>.js
ts
export default defineContentScript({
  // 매니페스트 옵션 설정
  matches: string[],
  excludeMatches: undefined | [],
  includeGlobs: undefined | [],
  excludeGlobs: undefined | [],
  allFrames: undefined | true | false,
  runAt: undefined | 'document_start' | 'document_end' | 'document_idle',
  matchAboutBlank: undefined | true | false,
  matchOriginAsFallback: undefined | true | false,
  world: undefined | 'ISOLATED' | 'MAIN',

  // 특정 빌드에서 백그라운드를 제거할 경우 include/exclude 설정
  include: undefined | string[],
  exclude: undefined | string[],

  // 페이지에 CSS를 주입하는 방식 설정
  cssInjectionMode: undefined | "manifest" | "manual" | "ui",

  // 콘텐츠 스크립트가 등록되는 방식/시점 설정
  registration: undefined | "manifest" | "runtime",

  main(ctx: ContentScriptContext) {
    // 콘텐츠 스크립트가 로드될 때 실행되며, 비동기로 동작할 수 있음
  },
});

Devtools ​

Chrome Docs • Firefox Docs

Devtools 예제를 따라 다양한 패널과 창을 추가할 수 있습니다.

FilenameOutput Path
entrypoints/devtools.html/devtools.html
entrypoints/devtools/index.html/devtools.html
html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- 특정 빌드에서 페이지를 제외하거나 포함하려면 include/exclude를 설정하세요 -->
    <meta name="manifest.include" content="['chrome', ...]" />
    <meta name="manifest.exclude" content="['chrome', ...]" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

History ​

Chrome Docs • Firefox Docs

FilenameOutput Path
entrypoints/history.html/history.html
entrypoints/history/index.html/history.html
html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Title</title>
    <!-- 특정 빌드에서 페이지를 제외하거나 포함하려면 include/exclude를 설정하세요 -->
    <meta name="manifest.include" content="['chrome', ...]" />
    <meta name="manifest.exclude" content="['chrome', ...]" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

Newtab ​

Chrome Docs • Firefox Docs

FilenameOutput Path
entrypoints/newtab.html/newtab.html
entrypoints/newtab/index.html/newtab.html
html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Title</title>
    <!-- 특정 빌드에서 페이지를 제외하거나 포함하려면 include/exclude를 설정하세요 -->
    <meta name="manifest.include" content="['chrome', ...]" />
    <meta name="manifest.exclude" content="['chrome', ...]" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

옵션 ​

Chrome 문서 • Firefox 문서

FilenameOutput Path
entrypoints/options.html/options.html
entrypoints/options/index.html/options.html
html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>옵션 제목</title>

    <!-- 매니페스트 옵션 커스터마이징 -->
    <meta name="manifest.open_in_tab" content="true|false" />
    <meta name="manifest.chrome_style" content="true|false" />
    <meta name="manifest.browser_style" content="true|false" />

    <!-- 특정 빌드에서 페이지를 제외하거나 포함할지 설정 -->
    <meta name="manifest.include" content="['chrome', ...]" />
    <meta name="manifest.exclude" content="['chrome', ...]" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

팝업 ​

Chrome Docs • Firefox Docs

FilenameOutput Path
entrypoints/popup.html/popup.html
entrypoints/popup/index.html/popup.html
html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <!-- manifest에서 `action.default_title` 설정 -->
    <title>기본 팝업 제목</title>

    <!-- manifest 옵션 커스터마이징 -->
    <meta
      name="manifest.default_icon"
      content="{
        16: '/icon-16.png',
        24: '/icon-24.png',
        ...
      }"
    />
    <meta name="manifest.type" content="page_action|browser_action" />
    <meta name="manifest.browser_style" content="true|false" />

    <!-- 특정 빌드에서 페이지를 제외하거나 포함하려면 include/exclude 설정 -->
    <meta name="manifest.include" content="['chrome', ...]" />
    <meta name="manifest.exclude" content="['chrome', ...]" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

샌드박스 ​

Chrome Docs

Chromium 전용

Firefox는 샌드박스 페이지를 지원하지 않습니다.

FilenameOutput Path
entrypoints/sandbox.html/sandbox.html
entrypoints/sandbox/index.html/sandbox.html
entrypoints/<name>.sandbox.html/<name>.html
entrypoints/<name>.sandbox/index.html/<name>.html
html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Title</title>

    <!-- 특정 빌드에서 페이지를 제외하거나 포함하려면 include/exclude를 설정하세요 -->
    <meta name="manifest.include" content="['chrome', ...]" />
    <meta name="manifest.exclude" content="['chrome', ...]" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

사이드 패널 ​

Chrome Docs • Firefox Docs

Chrome에서는 side_panel API를 사용하고, Firefox는 sidebar_action API를 사용합니다.

FilenameOutput Path
entrypoints/sidepanel.html/sidepanel.html
entrypoints/sidepanel/index.html/sidepanel.html
entrypoints/<name>.sidepanel.html/<name>.html`
entrypoints/<name>.sidepanel/index.html/<name>.html`
html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>기본 사이드 패널 제목</title>

    <!-- 매니페스트 옵션 커스터마이징 -->
    <meta
      name="manifest.default_icon"
      content="{
        16: '/icon-16.png',
        24: '/icon-24.png',
        ...
      }"
    />
    <meta name="manifest.open_at_install" content="true|false" />
    <meta name="manifest.browser_style" content="true|false" />

    <!-- 특정 빌드에서 페이지를 제외하거나 포함하려면 include/exclude 설정 -->
    <meta name="manifest.include" content="['chrome', ...]" />
    <meta name="manifest.exclude" content="['chrome', ...]" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

비공개 CSS ​

원하는 CSS 전처리기를 설정하려면 Vite 가이드를 참고하세요: https://vitejs.dev/guide/features.html#css-pre-processors

CSS 진입점은 항상 비공개로 처리됩니다. 콘텐츠 스크립트에 CSS를 추가하려면 콘텐츠 스크립트 문서를 참고하세요.

FilenameOutput Path
entrypoints/<name>.(css|scss|sass|less|styl|stylus)/<name>.css
entrypoints/<name>/index.(css|scss|sass|less|styl|stylus)/<name>.css
entrypoints/content.(css|scss|sass|less|styl|stylus)/content-scripts/content.css
entrypoints/content/index.(css|scss|sass|less|styl|stylus)/content-scripts/content.css
entrypoints/<name>.content.(css|scss|sass|less|styl|stylus)/content-scripts/<name>.css
entrypoints/<name>.content/index.(css|scss|sass|less|styl|stylus)/content-scripts/<name>.css
css
body {
  /* ... */
}

비공개 페이지 ​

FilenameOutput Path
entrypoints/<name>.html/<name>.html
entrypoints/<name>/index.html/<name>.html
html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Title</title>

    <!-- 특정 빌드에서 페이지를 제외하거나 포함하려면 include/exclude 설정 -->
    <meta name="manifest.include" content="['chrome', ...]" />
    <meta name="manifest.exclude" content="['chrome', ...]" />
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

페이지는 /<name>.html에서 접근 가능합니다:

ts
const url = browser.runtime.getURL('/<name>.html');

console.log(url); // "chrome-extension://<id>/<name>.html"

비공개 스크립트 ​

FilenameOutput Path
entrypoints/<name>.[jt]sx?/<name>.js
entrypoints/<name>/index.[jt]sx?/<name>.js
ts
export default defineUnlistedScript(() => {
  // 스크립트가 로드될 때 실행됨
});
ts
export default defineUnlistedScript({
  // 특정 빌드에서 스크립트를 제외하려면 include/exclude 설정
  include: undefined | string[],
  exclude: undefined | string[],

  main() {
    // 스크립트가 로드될 때 실행됨
  },
});

스크립트는 /<name>.js에서 접근 가능합니다:

ts
const url = browser.runtime.getURL('/<name>.js');

console.log(url); // "chrome-extension://<id>/<name>.js"

필요한 곳에서 스크립트를 로드하고 실행하는 것은 여러분의 책임입니다. 필요한 경우, 스크립트나 관련 스타일시트를 web_accessible_resources에 추가하는 것을 잊지 마세요.