엔트리포인트
WXT는 확장 프로그램을 번들링할 때 entrypoints/
디렉토리 내부의 파일을 입력으로 사용합니다. 이 파일들은 HTML, JS, CSS 또는 Vite에서 지원하는 파일 타입의 변형(Pug, TS, JSX, SCSS 등)일 수 있습니다.
다음은 엔트리포인트의 예제입니다:
📂 entrypoints/
📂 popup/
📄 index.html
📄 main.ts
📄 style.css
📄 background.ts
📄 content.ts
리스팅된 vs 언리스팅된
웹 확장 프로그램에는 두 가지 타입의 진입점이 있습니다:
- 리스팅된:
manifest.json
에서 참조됨 - 언리스팅된:
manifest.json
에서 참조되지 않음
WXT 문서의 나머지 부분에서는 리스팅된 진입점을 이름으로 참조합니다. 예를 들어:
- 팝업
- 옵션
- 백그라운드
- 콘텐츠 스크립트
- 기타
"언리스팅된" 진입점의 몇 가지 예시:
- 확장 프로그램이 설치될 때 표시되는 환영 페이지
- 콘텐츠 스크립트가 페이지의 메인 월드에 주입하는 JS 파일
TIP
진입점이 리스팅되었는지 언리스팅되었는지 여부와 상관없이, 모든 진입점은 확장 프로그램에 번들링되어 런타임에 사용 가능합니다.
엔트리포인트 추가하기
엔트리포인트는 단일 파일 또는 내부에 index
파일이 있는 디렉토리로 정의할 수 있습니다.
📂 entrypoints/
📄 background.ts
📂 entrypoints/
📂 background/
📄 index.ts
엔트리포인트의 이름은 엔트리포인트의 유형(목록에 포함된 것과 포함되지 않은 것)을 결정합니다. 이 예제에서 "background"는 "Background" 엔트리포인트의 이름입니다.
목록에 포함된 엔트리포인트와 해당 파일명 패턴의 전체 목록은 엔트리포인트 유형 섹션을 참조하세요.
Manifest 옵션 정의하기
대부분의 엔트리포인트는 manifest.json
에 추가해야 하는 옵션이 있습니다. 하지만 WXT를 사용하면 별도의 파일에 옵션을 정의하는 대신, _엔트리포인트 파일 내부에서 이 옵션들을 정의_합니다.
예를 들어, 콘텐츠 스크립트의 matches
를 정의하는 방법은 다음과 같습니다:
// entrypoints/content.ts
export default defineContentScript({
matches: ['*://*.wxt.dev/*'],
main() {
// ...
},
});
HTML 엔트리포인트의 경우, 옵션은 <meta>
태그로 설정됩니다. 예를 들어, MV2 팝업에 page_action
을 사용하려면 다음과 같이 작성합니다:
<!doctype html>
<html lang="en">
<head>
<meta name="manifest.type" content="page_action" />
</head>
</html>
각 엔트리포인트 내부에서 설정 가능한 옵션 목록과 정의 방법은 엔트리포인트 타입 섹션을 참고하세요.
확장 프로그램을 빌드할 때, WXT는 엔트리포인트에 정의된 옵션을 확인하고 그에 따라 manifest를 생성합니다.
Entrypoint Types
백그라운드
MV2에서는 백그라운드 스크립트가 백그라운드 페이지에 추가됩니다. MV3에서는 백그라운드가 서비스 워커로 변경됩니다.
Filename | Output Path | |
---|---|---|
entrypoints/background.[jt]s | /background.js | |
entrypoints/background/index.[jt]s | /background.js |
export default defineBackground(() => {
// 백그라운드가 로드될 때 실행됨
});
export default defineBackground({
// 매니페스트 옵션 설정
persistent: undefined | true | false,
type: undefined | 'module',
// 특정 빌드에서 백그라운드를 제거해야 할 경우 include/exclude 설정
include: undefined | string[],
exclude: undefined | string[],
main() {
// 백그라운드가 로드될 때 실행됨, 비동기로 사용 불가
},
});
북마크
Filename | Output Path | |
---|---|---|
entrypoints/bookmarks.html | /bookmarks.html | |
entrypoints/bookmarks/index.html | /bookmarks.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>
콘텐츠 스크립트
콘텐츠 스크립트에서 UI 생성 및 CSS 포함에 대한 자세한 내용은 콘텐츠 스크립트 UI를 참고하세요.
Filename | Output 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 |
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
Devtools 예제를 따라 다양한 패널과 창을 추가할 수 있습니다.
Filename | Output Path | |
---|---|---|
entrypoints/devtools.html | /devtools.html | |
entrypoints/devtools/index.html | /devtools.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
Filename | Output Path | |
---|---|---|
entrypoints/history.html | /history.html | |
entrypoints/history/index.html | /history.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
Filename | Output Path | |
---|---|---|
entrypoints/newtab.html | /newtab.html | |
entrypoints/newtab/index.html | /newtab.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>
옵션
Filename | Output Path | |
---|---|---|
entrypoints/options.html | /options.html | |
entrypoints/options/index.html | /options.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>
팝업
Filename | Output Path | |
---|---|---|
entrypoints/popup.html | /popup.html | |
entrypoints/popup/index.html | /popup.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>
샌드박스
Chromium 전용
Firefox는 샌드박스 페이지를 지원하지 않습니다.
Filename | Output 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 |
<!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에서는 side_panel
API를 사용하고, Firefox는 sidebar_action
API를 사용합니다.
Filename | Output 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` |
<!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를 추가하려면 콘텐츠 스크립트 문서를 참고하세요.
Filename | Output 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 |
body {
/* ... */
}
비공개 페이지
Filename | Output Path | |
---|---|---|
entrypoints/<name>.html | /<name>.html | |
entrypoints/<name>/index.html | /<name>.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
에서 접근 가능합니다:
const url = browser.runtime.getURL('/<name>.html');
console.log(url); // "chrome-extension://<id>/<name>.html"
비공개 스크립트
Filename | Output Path | |
---|---|---|
entrypoints/<name>.[jt]sx? | /<name>.js | |
entrypoints/<name>/index.[jt]sx? | /<name>.js |
export default defineUnlistedScript(() => {
// 스크립트가 로드될 때 실행됨
});
export default defineUnlistedScript({
// 특정 빌드에서 스크립트를 제외하려면 include/exclude 설정
include: undefined | string[],
exclude: undefined | string[],
main() {
// 스크립트가 로드될 때 실행됨
},
});
스크립트는 /<name>.js
에서 접근 가능합니다:
const url = browser.runtime.getURL('/<name>.js');
console.log(url); // "chrome-extension://<id>/<name>.js"
필요한 곳에서 스크립트를 로드하고 실행하는 것은 여러분의 책임입니다. 필요한 경우, 스크립트나 관련 스타일시트를 web_accessible_resources
에 추가하는 것을 잊지 마세요.