Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeError: adapter is not a function error when using axios and webpack in Chrome extension

I'm building a chrome extension which will need to make an API call when certain messages are received from the content script. I'm having difficulty making the HTTP request and I believe that my webpack configuration is to blame.

I've tried using node-fetch and axios and neither is working for me.

My webpack.common.js file looks like this:


const path = require("path");

module.exports = {
  target: "node",
  entry: {
    popup: path.join(__dirname, "src/popup/index.tsx"),
    background: path.join(__dirname, "src/background.ts"),
    contentScript: path.join(__dirname, "src/contentScript.ts"),
  },
  output: {
    path: path.join(__dirname, "dist"),
    filename: "[name].js",
  },
  module: {
    rules: [
      {
        exclude: /node_modules/,
        test: /\.tsx?$/,
        use: "ts-loader",
      },
      {
        exclude: /node_modules/,
        test: /\.scss$/,
        use: [
          {
            loader: "style-loader", // Creates style nodes from JS strings
          },
          {
            loader: "css-loader", // Translates CSS into CommonJS
          },
          {
            loader: "sass-loader", // Compiles Sass to CSS
          },
        ],
      },
    ],
  },
  resolve: {
    extensions: [".ts", ".tsx", ".js"],
  },
};

When the script attempts a call with axios from the chrome extension, I receive this error:


dispatchRequest.js:52 Uncaught (in promise) TypeError: adapter is not a function
    at dispatchRequest (dispatchRequest.js:52)

like image 806
Dave Cook Avatar asked Feb 21 '21 18:02

Dave Cook


2 Answers

I'm like 10 months late, but this can be useful for anyone having this same problem. Migrating from Axios to fetch could be a good option, but it's a lot of work if you have built a custom API on top of Axios with all its utilities (interceptors, cancellation, etc.), so there's a simple fix:

Axios accepts an adapter field in its configuration, so you can pass a fetch adapter like axios-fetch-adapter and probably, you'll need to add regenerator-runtime too, so in your background.js file:

import "regenerator-runtime/runtime.js";
like image 196
piedra Avatar answered Oct 21 '22 04:10

piedra


I faced a similar problem. I think it happens when using axios on the Service Worker of chrome extension.

When accessing other origins and getting responses (i.e. CROS) on the Service Worker of the chrome extension, I was able to request them by doing the following

First of all, you can't use axios on the Service Worker. axios tries to use xhr and http when getting adapter, but you can't use both on Service Worker. So, use fetch, which should be in cros mode.

To use fetch in cros mode, put the target URL in host_permissions. I've seen examples of URLs in permissions on other sites, but if you don't use host_permissions, you will get an error.

The actual code should look like the following. (Some excerpts)

Manifest.json

  "background": {
    "service_worker": "background.js"
  },
  "host_permissions": ["https://sample.com/*"]

background.js

const res = await fetch(baseUrl + word, {        
method: "GET",        
mode: "cors",      
});      
const txt = await res.text();

I have written a more detailed history of the project below, which I hope you will take a look at while translating.

https://takumi-oda.com/blog/2021/09/30/post-2006/

like image 44
Chaitaku Avatar answered Oct 21 '22 06:10

Chaitaku