Adaptation of external npm package to native browser functions
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.
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.