0

나는 amd 방식으로 크롬 확장을 개발 중이다. js bundler로서 webpack을 사용하고 있습니다. 여러 항목을 추출한 webpack은 여러 항목을 구성했습니다. 내 목표는 content_script 컨텍스트에서 청크로드를 얻는 것입니다. 기본적으로 동작 webpack_require. 적절한 SRC와 새 스크립트 태그를 생성하고 DOM에 주입합니다 기능을 확인 은 :webpack chrome extension chunk loading content_script context

내 경우를 들어
__webpack_require__.e = function requireEnsure(chunkId, callback) { 
/******/  // "0" is the signal for "already loaded" 
/******/  if(installedChunks[chunkId] === 0) 
/******/   return callback.call(null, __webpack_require__); 
/******/ 
/******/  // an array means "currently loading". 
/******/  if(installedChunks[chunkId] !== undefined) { 
/******/   installedChunks[chunkId].push(callback); 
/******/  } else { 
/******/   // start chunk loading 
/******/   installedChunks[chunkId] = [callback]; 
/******/   var head = document.getElementsByTagName('head')[0]; 
/******/   var script = document.createElement('script'); 
/******/   script.type = 'text/javascript'; 
/******/   script.charset = 'utf-8'; 
/******/   script.async = true; 
/******/ 
/******/   script.src = __webpack_require__.p + "" + ({}[chunkId]||chunkId) + ".chunk.js"; 
/******/   head.appendChild(script); // INJECT INTO DOM 
/******/  } 
/******/ }; 

나는 (지금 작동 등) 별도의 요청으로 덩어리를로드 만의 컨텍스트에서 실행하고 싶습니다 현재 content_script code : eval 기능.

그렇게 떨어지게 효율적으로 활용하려면 다음 작업을

/******/ __webpack_require__.e = function requireEnsure(chunkId, callback) { 
/******/  // "0" is the signal for "already loaded" 
/******/  if(installedChunks[chunkId] === 0) 
/******/   return callback.call(null, __webpack_require__); 
/******/ 
/******/  // an array means "currently loading". 
/******/  if(installedChunks[chunkId] !== undefined) { 
/******/   installedChunks[chunkId].push(callback); 
/******/  } else { 
/******/   // start chunk loading 
/******/   installedChunks[chunkId] = [callback]; 
/******/   var head = document.getElementsByTagName('head')[0]; 
/******/   var src = __webpack_require__.p + "" + ({}[chunkId]||chunkId) + ".chunk.js"; 
/******/   var url = chrome.extension.getURL(src); 
/******/   var xhr = new XMLHttpRequest(), 
/******/   evalResponseText = function (xhr) { 
/******/    eval(xhr.responseText + '//# sourceURL=' + url); // execute chunk's code in context of content_script 
/******/    // context.completeLoad(moduleName); 
/******/   }; 
/******/   xhr.open('GET', url, true); 
/******/   xhr.onreadystatechange = function (e) { 
/******/    if (xhr.readyState === 4 && xhr.status === 200) { 
/******/     evalResponseText.call(window, xhr); 
/******/    } 
/******/   }; 
/******/   xhr.send(null); // get chunk 
/******/    
/******/  } 

는 이미 컴파일 과정에 사용자 정의 플러그인 주입하여 해결했다. '합법적'(단순한) 방식으로 달성 할 수 있는지 의문입니다. 또는 사용자 정의 플러그인을 사용하지 않고 사용자 정의 로더로 해결할 수 있습니까?

Thx 아이디어가 많습니다.

답변

1

크롬 확장을 사용하여 새 콘텐츠 스크립트를 삽입하는 합법적 인 방법은 chrome.tabs.executeScript을 통해 백그라운드 페이지에서 수행하는 것입니다. 삽입 된 콘텐츠 스크립트는 다른 콘텐츠 스크립트의 실행 환경을 공유하며 소위 isolated world입니다.

  • 콘텐츠 스크립트

    function loadScript(fileName, callback) { 
        // fileName: file name relative to the extension root folder: 'js/blah.js' 
        // callback: receives an array, 
        //   in our case there'll be only one element as we inject in one frame, 
        //   each element is an injected script's last evaluated expression 
        //   that underwent internal JSON.stringify + JSON.parse 
        //   thus losing anything except simple stringifiable data 
        chrome.runtime.sendMessage({ 
         action: 'loadContentScript', 
         fileName: fileName, 
        }, callback); 
    } 
    

    사용법 :

    loadScript('js/lib/something.js', function(r) { 
        console.log('something was dropped:', r); 
        // call something in something 
        ............. 
    } 
    
  • 배경 스크립트 :

    chrome.runtime.onMessage(function(msg, sender, sendResponse)) { 
        if (msg.action == 'loadContentScript') { 
         chrome.tabs.executeScript(sender.tab.id, { 
          file: msg.fileName, 
          frameId: sender.frameId, 
          runAt: 'document_start', // just in case, force an immediate execution 
         }, sendResponse); 
        } 
        return true; // keeps the message channel open while async executeScript runs 
    }); 
    
  • 의 manifest.json :

    ,

    chrome.tabs.executeScript은 (<all_urls> 또는 사용) https://example.com/에 삽입 할 수 :

    "permissions": ["activeTab"], 
    

    :

    "permissions": ["tabs", "https://example.com/*"], 
    

    다르게, 바람직 경우에는 내선은 승인 된 사용자 제스처에 의해 활성화 user gestures 목록 :

    • 브라우저 동작 즉 도구 모음 아이콘 클릭
    • 페이지 작업, 즉 도구 모음 아이콘에서 확장하여 제안을 수락 명령의 API
    • 에서 확장의 키보드 바로 가기를 실행 확장
    • 의 상황에 맞는 메뉴 항목을 실행 현대 크롬
    • 클릭을 실행 검색 주소창
+0

답장을위한 Thx!실제로 처음 질문은 webpack을 참조했으며, chunk loading 코드 생성 메커니즘을 수정/변경하는 가장 좋은 방법은 무엇입니까?) 그러나 내 코드에서 eval() 호출을 피하는 방법은 나에게 답을 줄 수 있습니다. ** chrome.executeScript **로 제안을 이미 시도했지만 혼란스러운 오류 메시지가 표시됩니다. 내가 뭘 하려는지 오버 라이드 requirejs.load 전역 함수 sendMessage 및 executeScript 배경 페이지를 호출하는 데 사용하는 것입니다. Chrome은 모듈을 찾을 수는 있지만 어떤 이유로 실행할 수 없습니다. – SchmerZ

+0

글쎄, webpack 크롬 확장의 고유 한 제한을 피할 수 없다, 그래서 어떤 확장 기능 스크립트를 로딩 기능은 기본적 으로이 줄을 따라 제공 할 수 있습니다. 크롬이 확장을 위해 ES6 모듈을 구현할 때 밝은 미래에 어쩌면. – wOxxOm

+0

응답 객체를 실행하려는 경우 내부 문자열링에 의해 거세 된 것으로 평가 된 항목의 나머지 부분 만 남습니다 (내 코드의 주석 참조). 따라서 새로운 모듈을 직접 액세스하면됩니다 (예를 들어 글로벌'modules' 또는'exports' 객체에 등록되어야합니다). – wOxxOm