Adaptation of external npm package to native browser functions

Author
Damian
Terlecki
6 minutes read
JS

Maintaining legacy applications written in JS, sooner or later, you will notice during installation that some packages are marked as deprecated. Sometimes the reason for this is authors discontinuing development in favor of newly supported native functions:

WARN deprecated stable@0.1.8: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility

Often, replacing such functions with native ones significantly reduces the size of the delivered application and provides better support in the event of potential errors. Such adaptation is possible thanks to the configuration of overridden dependencies in the package.json file through the overrides field:

{
  "overrides": {
    "baz": {
      "bar": {
        "foo": "1.0.0"
      }
    }
  }
}

This operation is safe as long as the new version is compatible with the dependent packages. Keep this in mind when updating dependent packages (for example, they may suddenly require a version that is not compatible with the package adaptation). From the above, there is an apparent con of this operation, i.e. the potential increase in the difficulty of maintaining the application.

Using the react-static package (now in maintenance mode) as an example, I'll show you how to replace the indirect dependency on the axios with the native fetch implementation from the browser or NodeJS:

Adaptation of the npm package

The react-static@7.6.2 requires the axios@^0.21.1 package in the dependency tree. However, only the axios.get() function is used in the entire codebase, and only in two places – as a React hook providing page data and for page prefetch.

Axios is a package that offers much more functionality than the native fetch. At the same time, it supports more browsers. On the other hand, the fetch function is now also found in the newer browsers. Moreover, it does not impose an additional size on the application.

axios@0.27.2 package size (webpack-bundle-analyzer)

By default, after installing the packages needed for react-static, you will find the axios package in the node_modules/axios directory relative to your project. In order to replace with your own adaptation, I recommend starting with copying the content to the root of the project. Then, in the package definition, remove unnecessary dependencies and add information about changes to the original:

{
  "name": "axios",
  "version": "0.0.0",
  "description": "Promise based HTTP client for the browser and node.js. MODIFIED: Customized as a wrapper for fetch GET.",
  "main": "index.js",
  "author": "Matt Zabriskie",
  "license": "MIT"
}

The package input file is index.js (module.exports = require ('./ lib / axios');), indicated by the main field. Referenced lib/axios.js source contains the module export. We adapt it by providing an implementation only for the get() function that refers to the native fetch function. To keep the default behavior intact, add the Accept headers and transform the response to JSON:

'use strict';

var axios = {
    get: (path) => {
        return fetch(path, {
            method: "GET",
            headers: {
                'Accept': 'application/json, text/plain, */*'
            }
        })
            .then(response => response.json())
            .then(data => ({data}));
    }
}

module.exports = axios;

At the very end, replace the package reference in the package.json file under the resolutions field (or under the dependencies field, if you use it directly). A global override with the local adaptation contained in the src/axios directory (invoke the npm install ./src/axios command for the automated update of the dependency field) will look like this:

{
  "resolutions": {
    "axios": "link:src/axios"
  }
}

If you add dependencies manually, all you need to do is call npm install to update package-lock.json. Lastly, try to prepare some test cases to cover all use cases of your adaptation.