これらのコードをひとつにまとめたものを作りたいですが、どういう風にすればよいかわかりません。

Chrome拡張機能で実装を考えているメモ機能のコードなのですが、  
いつもエラーの処理がわからなくなって様々な質問サイトで質問するので、答えてもらいやすくするためにひとつにまとめたいです。

=================================

manifest.json

```

    {
      "name": "test",
      "manifest_version": 2,
      "version": "1.0",
      "permissions": ["tabs", "storage"],
      "browser_action": {
        "default_title": "Mister test",
        "default_popup": "popup.html"
      },
      "background":{
        "scripts":[
          "background.js"
        ],
        "persistent": false
      },
      "content_scripts": [
        {
          "js": ["content_script.js"],
          "matches": ["http://*/*", "https://*/*"],
          "run_at": "document_end"
        }
      ]
    }
    
```

popup.js

```

    "ポップアップを立ち上げた際に、そのurlでメモを保存したかどうかをストレージから探しcontent_script.jsへその情報を渡す"
    chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs => {
      chrome.storage.local.get([tabs[0].url], item => {
        // ポップアップを立ち上げた際に、そのurlでメモを保存したかどうかを探す
        // あった場合: chrome.storageに保存してあるテキスト・位置でモーダルを表示
        if (item[tabs[0].url]) {
           chrome.tabs.sendMessage(tabs[0].id, {content: item[tabs[0].url].content, posX: item[tabs[0].url].posX, posY: item[tabs[0].url].posY});
        }
        // なかった場合: デフォルト位置に空白のテキストボックスでモーダルを表示
        else {
           chrome.tabs.sendMessage(tabs[0].id, {content: '', posX: 0, posY: 0});
        }
      });
    });
    
```

background.js

```

    chrome.runtime.onMessage.addListener((content, sender, sendResponse) => {
      chrome.tabs.query({'active': true, 'lastFocusedWindow': true}, tabs => {
        const url = tabs[0].url;//{'active': true, 'lastFocusedWindow': true}なタブ(1つしかない)
        let data = {};
        // URLに場所と内容を結びつける
        data[url] = {
          content: content,
          posX: 100,
          posY: 100
        };
        // 保存
         chrome.storage.local.set(data);
      });
      // ”保存したよ”って返信
       sendResponse('saved');
    });
    
```

content_script.js

```

    const save = (content) => {//save(textbox.value)
      chrome.runtime.sendMessage(content, res => {
          console.log(res);
      });
    };
    chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
      const modalfrm = document.getElementById('ex-memo');
      if (modalfrm != null) return;
      const modal = document.createElement('div');
      modal.id = 'ex-memo';
      // modal.style.width = '500px';
      // modal.style.height = '100px';
      modal.style.zIndex = '2147483647';
      modal.style.position = 'fixed';
      modal.style.left = `${message.posX}px`;
      modal.style.top = `${message.posY}px`;
      console.log("modal.style.left:" + modal.style.left);
      console.log("modal.style.top:" + modal.style.top);
      console.log("modal.style.width:" + modal.style.width);
      console.log("modal.style.height:" + modal.style.height);
      const textbox = document.createElement('textarea');
      textbox.style.width = '600px';
      textbox.style.height = '200px';
      textbox.style.backgroundColor = 'rgb(67, 67, 67)';
      textbox.style.color = 'rgb(51, 166, 184)';
      textbox.value= message.content;
      modal.appendChild(textbox);
      const saveButton = document.createElement('button');
      saveButton.onclick = () => save(textbox.value);
      saveButton.innerText = '保存';
      modal.appendChild(saveButton);
      document.body.appendChild(modal);
      console.log("function");
      modal.addEventListener('mousedown', mdown);
      modal.addEventListener('touchstart', mdown);
      // "マウスが押された際の関数"
      function mdown(e){
          console.log("mdown");
          this.classList.add("drag");
          //タッチドイベントとマウスのイベントの差異を吸収
          if(e.type === "mousedown") {
              var event = e;
          } else {
              var event = e.changedTouches[0];
          }
          //要素内の相対座標を取得
          posX = event.pageX - this.offsetLeft;
          posY = event.pageY - this.offsetTop;
          //ムーブイベントにコールバック
          document.body.addEventListener("mousemove", mmove);
          document.body.addEventListener("touchmove", mmove);
      }
      // "マウスカーソルが動いたときに発火"
      function mmove(e){
          console.log("mmove");
          //ドラッグしている要素を取得
        　var drag = document.getElementsByClassName("drag")[0];
          //同様にマウスとタッチの差異を吸収
          if(e.type === "mousemove") {
              var event = e;
          } else {
              var event = e.changedTouches[0];
          }
          //フリックしたときに画面を動かさないようにデフォルト動作を抑制
          e.preventDefault();
          //マウスが動いた場所に要素を動かす
          drag.style.top = event.pageY - posY + "px";
          drag.style.left = event.pageX - posX + "px";
          //マウスボタンが離されたとき、またはカーソルが外れたとき発火
          drag.addEventListener("mouseup", mup);
          document.body.addEventListener("mouseleave", mup);
          drag.addEventListener("touchend", mup);
          document.body.addEventListener("touchleave", mup);
    
            // "マウスボタンが上がったら発火"
      function mup(e){
        console.log("mup");
        var drag = document.getElementsByClassName("drag")[0];
        //ムーブベントハンドラの消去
        document.body.removeEventListener("mousemove", mmove);
        drag.removeEventListener("mouseup", mup);
        document.body.removeEventListener("touchmove", mmove);
        drag.removeEventListener("touchend", mup);
        //クラス名 .drag も消す
        drag.classList.remove("drag");
      }
    
      }
    });
    
```
CC BY-SA 4.0
2020-03-30T08:03:35.680
65233
2020-04-02T23:57:03.367
2020-04-02T23:26:58.087
38112
38112
question
javascript chrome-extension
まとめ方がわからないです
Chrome拡張機能を作って、Googleに提出するためにまとめたいということですか？もしそうであれば、1つのHTMLにまとめるのではなく、上記のファイル群にアイコンも含めてZIP形式で圧縮して提出します。
CC BY-SA 4.0
2020-04-02T20:23:28.420
65314
2020-04-02T20:23:28.420
38398
65233
answer
質問するときのためにひとつにまとめたいということであれば、むしろ逆に、まとめる必要は無いです。ファイルが分かれていることによってコードのだいたいの役割がファイル名を見るだけで分かるようになり、問題の把握が楽になります。

回答者の負担を減らすためということであれば、コードを短くすることを心がけると良さそうです。つまり、質問の本質とは関係無さそうなところを削ったトイプログラムを作るのです。同じ問題が再現できるなるべく小さなプログラムを作ってそれに基づいて質問すると、質問をより読みやすくなります。スタック・オーバーフローのヘルプセンターにも「[再現可能な短いサンプルコードの書き方](https://ja.stackoverflow.com/help/minimal-
reproducible-example)」というページがあるので参考になるでしょう。
CC BY-SA 4.0
2020-04-02T23:57:03.367
65315
2020-04-02T23:57:03.367
19110
65233
answer