모듈로 사용할 helper.js 라는 파일이 있고 func1() 이라는 함수를 export 한다고 가정하자.
helper.js
function func1(msg)
{
console.log(msg);
}
export { func1 };
PageAction (popup)
브라우저 탭에 붙는 popup의 경우 기본적으로 manifest.json에 html 파일을 지정하도록 되어있으므로 간단함.
manifest.json
"browser_action": {
"default_popup": "popup.html"
}
popup.html
<!-- 이렇게 모듈 타입으로 호출 -->
<script type="module" src="popup.js"></script>
popup.js
// 이런식으로 사용
import { func1 } from './helper.js';
func1('from popup');
background script
manifest.json에서 일반적으로 background에 script: [ "background.js" ] 같은 형태로 js 파일을 지정하는데,
page를 지정하는 방식으로 html 파일을 지정할 수 있다.
나머진 해당 html 파일 안에서 <script> 태그 안에 type="module" 을 넣어주면 해결됨.
manifest.json
"background": {
"page": "background.html"
}
background.html
<script type="module" src="background.js"></script>
background.js
import { func1 } from './helper.js';
func1('from background');
content script
content script의 경우 html을 지정하는 방법도 없고,
삽입되는 html의 head에 <script type="module" src="./helper.js"> 형태로 태그를 만들어 넣는 방법은 scope가 완전히 분리되는 바람에 chrome.runtime 등을 사용하지 못하는 치명적인 단점이 있다.
그래서 나온 해결책이 dynamic import를 사용하는 방법.
우선 manifest.json 에서 import 할 js 들을 리스팅 해줘야 함.
귀찮으면 그냥 * 하거나 모듈들이 모여있는 디렉토리를 지정하거나. ex) "src/modules/*"
manifest.json
"web_accessible_resources": [
"main.js",
"helper.js"
]
content_script.js
// 실제 로딩될 main.js 파일을 dynamic import
(async()=>{
const src = chrome.extension.getURL('main.js');
const contentScript = await import(src);
contentScript.main();
})();
main.js
import { func1 } from './helper.js';
export function main()
{
// 메인 프로세스를 여기서 실행하면 됨...
// chrome.runtime이 사용가능한지 체크
console.log('typeof chrome.runtime = '+(typeof chrome.runtime));
// 물론 func1() 도 사용가능
func1('from dynamic imported main.js');
}