Skip to content

Commit 4aba86f

Browse files
Add a way to build without axios (#1038)
* replace axios with feaxios * make sure env is properly set for all builds and tests * add github test and changelog * update readme * update yarn lock
1 parent 64bb331 commit 4aba86f

32 files changed

+671
-113
lines changed

.github/workflows/tests.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,8 @@ jobs:
4141
- name: Browser Tests
4242
run: yarn test:browser
4343

44+
- name: Browser No Axios Tests
45+
run: yarn test:browser:no-axios
46+
4447
- name: Linter Tests
4548
run: yarn _prettier && (git diff-index --quiet HEAD; git diff)

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@ test/unit/out/
1515

1616
target
1717
.soroban
18+
19+
config/tsconfig.tmp.json

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ export interface BalanceResponse {
2525
}
2626
```
2727

28+
- New build target for creating a browser bundle without Axios dependency. Set USE_AXIOS=false environment variable to build stellar-sdk-no-axios.js and stellar-sdk-no-axios.min.js in the dist/ directory. Use yarn build:browser:no-axios to generate these files.
29+
- Similarly, a new import path for the node package without the Axios dependency can be used. Import the SDK using `@stellar/stellar-sdk/no-axios`. For Node.js environments that don't support the package.json `exports` configuration, use `@stellar/stellar-sdk/lib/no-axios/index`.
30+
## [Version Number] - YYYY-MM-DD
31+
- Updated the Node.js target in the Babel configuration from 16 to 18 for production builds.
2832

2933
## [v12.3.0](https://github.com/stellar/js-stellar-sdk/compare/v12.2.0...v12.3.0)
3034

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,13 @@ If you don't want to use or install Bower, you can copy the packaged JS files fr
8585
| Always make sure that you are using the latest version number. They can be found on the [releases page](https://github.com/stellar/js-stellar-sdk/releases) in GitHub. |
8686
|----|
8787

88+
### Custom Installation
89+
90+
You can configure whether or not to build the browser bundle with the axios dependency. In order to turn off the axios dependency, set the USE_AXIOS environment variable to false.
91+
92+
#### Build without Axios
93+
USE_AXIOS=false npm run build:browser
94+
8895
## Usage
8996

9097
The usage documentation for this library lives in a handful of places:

babel.config.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
const buildConfig = require('./config/build.config');
2+
const fs = require('fs');
3+
const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
4+
const version = packageJson.version;
5+
6+
module.exports = function(api) {
7+
api.cache(true);
8+
9+
const presets = [
10+
"@babel/preset-env",
11+
"@babel/typescript"
12+
];
13+
14+
const plugins = [];
15+
16+
if (process.env.NODE_ENV === 'development') {
17+
plugins.push('istanbul');
18+
}
19+
20+
// Add the define plugin
21+
plugins.push([
22+
'babel-plugin-transform-define',
23+
{
24+
__USE_AXIOS__: buildConfig.useAxios,
25+
__USE_EVENTSOURCE__: buildConfig.useEventSource,
26+
__PACKAGE_VERSION__: version,
27+
}
28+
]);
29+
30+
const config = {
31+
comments: process.env.NODE_ENV !== 'production',
32+
presets,
33+
plugins,
34+
targets: process.env.NODE_ENV === 'production'
35+
? { node: 18, browsers: ["> 2%", "ie 11", "not op_mini all"] }
36+
: { browsers: ["> 2%"] }
37+
};
38+
39+
return config;
40+
};

babel.config.json

Lines changed: 0 additions & 26 deletions
This file was deleted.

config/build.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
useAxios: process.env.USE_AXIOS !== 'false',
3+
useEventSource: process.env.USE_EVENTSOURCE !== 'false',
4+
};

config/karma.conf.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
const webpackConfig = require('./webpack.config.browser.js');
2+
const buildConfig = require('./build.config');
23

34
delete webpackConfig.output;
45
delete webpackConfig.entry; // karma fills these in
56
webpackConfig.plugins.shift(); // drop eslinter plugin
67

8+
function getStellarSdkFileName() {
9+
let name = 'stellar-sdk';
10+
if (!buildConfig.useAxios) name += '-no-axios';
11+
if (!buildConfig.useEventSource) name += '-no-eventsource';
12+
return name + '.js';
13+
}
14+
715
module.exports = function (config) {
816
config.set({
917
frameworks: ['mocha', 'sinon-chai'],
1018
browsers: ['FirefoxHeadless', 'ChromeHeadless'],
1119

1220
files: [
13-
'../dist/stellar-sdk.js', // webpack should build this first
21+
'../dist/' + getStellarSdkFileName(),
1422
'../test/test-browser.js',
1523
'../test/unit/**/*.js'
1624
],

config/set-output-dir.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
4+
const OUTPUT_DIR = process.env.OUTPUT_DIR || 'lib';
5+
const tsconfigPath = path.resolve(__dirname, 'tsconfig.json');
6+
const tempTsconfigPath = path.resolve(__dirname, 'tsconfig.tmp.json');
7+
8+
const tsconfig = require(tsconfigPath);
9+
tsconfig.compilerOptions.outDir = path.resolve(__dirname, '..', OUTPUT_DIR);
10+
tsconfig.compilerOptions.declarationDir = path.resolve(__dirname, '..', OUTPUT_DIR);
11+
12+
fs.writeFileSync(tempTsconfigPath, JSON.stringify(tsconfig, null, 2), 'utf8');
13+
14+
console.log(`Set TypeScript outDir to ${OUTPUT_DIR} in temporary tsconfig file.`);

config/webpack.config.browser.js

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
var path = require('path');
22
var webpack = require('webpack');
3+
var fs = require('fs');
34

45
var ESLintPlugin = require('eslint-webpack-plugin');
56
var TerserPlugin = require('terser-webpack-plugin');
67
var NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
8+
var buildConfig = require('./build.config');
9+
10+
// Read the version from package.json
11+
const packageJson = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../package.json'), 'utf8'));
12+
const version = packageJson.version;
713

814
const config = {
915
target: 'web',
@@ -16,17 +22,34 @@ const config = {
1622
fallback: {
1723
crypto: require.resolve('crypto-browserify'),
1824
stream: require.resolve('stream-browserify'),
19-
buffer: require.resolve('buffer')
25+
buffer: require.resolve('buffer'),
2026
},
21-
extensions: ['.ts', '.js']
27+
extensions: ['.ts', '.js'],
2228
},
2329
output: {
24-
clean: true,
30+
clean: process.env.no_clean ? false: true,
2531
library: {
2632
name: 'StellarSdk',
2733
type: 'umd',
2834
umdNamedDefine: true
2935
},
36+
filename: (pathData) => {
37+
let name = pathData.chunk.name;
38+
let suffix = '';
39+
40+
if (name.endsWith('.min')) {
41+
name = name.slice(0, -4); // Remove .min
42+
suffix = '.min.js';
43+
} else {
44+
suffix = '.js';
45+
}
46+
47+
if (!buildConfig.useAxios && !buildConfig.useEventSource) name += '-minimal';
48+
else if (!buildConfig.useAxios) name += '-no-axios';
49+
else if (!buildConfig.useEventSource) name += '-no-eventsource';
50+
51+
return name + suffix;
52+
},
3053
path: path.resolve(__dirname, '../dist')
3154
},
3255
mode: process.env.NODE_ENV ?? 'development',
@@ -42,7 +65,11 @@ const config = {
4265
cacheDirectory: true
4366
}
4467
}
45-
}
68+
},
69+
{
70+
test: /node_modules\/https-proxy-agent\//,
71+
use: 'null-loader',
72+
},
4673
]
4774
},
4875
optimization: {
@@ -70,6 +97,11 @@ const config = {
7097
}),
7198
new webpack.ProvidePlugin({
7299
Buffer: ['buffer', 'Buffer']
100+
}),
101+
new webpack.DefinePlugin({
102+
__USE_AXIOS__: JSON.stringify(buildConfig.useAxios),
103+
__USE_EVENTSOURCE__: JSON.stringify(buildConfig.useEventSource),
104+
__PACKAGE_VERSION__: version,
73105
})
74106
],
75107
watchOptions: {

package.json

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,63 @@
3636
"./rpc": {
3737
"types": "./lib/rpc/index.d.ts",
3838
"default": "./lib/rpc/index.js"
39+
},
40+
"./no-axios": {
41+
"browser": "./dist/stellar-sdk-no-axios.min.js",
42+
"types": "./lib/no-axios/index.d.ts",
43+
"default": "./lib/no-axios/index.js"
44+
},
45+
"./no-axios/contract": {
46+
"types": "./lib/no-axios/contract/index.d.ts",
47+
"default": "./lib/no-axios/contract/index.js"
48+
},
49+
"./no-axios/rpc": {
50+
"types": "./lib/no-axios/rpc/index.d.ts",
51+
"default": "./lib/no-axios/rpc/index.js"
52+
},
53+
"./no-eventsource": {
54+
"browser": "./dist/stellar-sdk-no-eventsource.min.js",
55+
"types": "./lib/no-eventsource/index.d.ts",
56+
"default": "./lib/no-eventsource/index.js"
57+
},
58+
"./no-eventsource/contract": {
59+
"types": "./lib/no-eventsource/contract/index.d.ts",
60+
"default": "./lib/no-eventsource/contract/index.js"
61+
},
62+
"./no-eventsource/rpc": {
63+
"types": "./lib/no-eventsource/rpc/index.d.ts",
64+
"default": "./lib/no-eventsource/rpc/index.js"
65+
},
66+
"./minimal": {
67+
"browser": "./dist/stellar-sdk-minimal.min.js",
68+
"types": "./lib/minimal/index.d.ts",
69+
"default": "./lib/minimal/index.js"
70+
},
71+
"./minimal/contract": {
72+
"types": "./lib/minimal/contract/index.d.ts",
73+
"default": "./lib/minimal/contract/index.js"
74+
},
75+
"./minimal/rpc": {
76+
"types": "./lib/minimal/rpc/index.d.ts",
77+
"default": "./lib/minimal/rpc/index.js"
3978
}
4079
},
4180
"scripts": {
4281
"build": "cross-env NODE_ENV=development yarn _build",
4382
"build:prod": "cross-env NODE_ENV=production yarn _build",
4483
"build:node": "yarn _babel && yarn build:ts",
45-
"build:ts": "tsc -p ./config/tsconfig.json",
84+
"build:node:no-axios": "cross-env OUTPUT_DIR=lib/no-axios USE_AXIOS=false yarn build:node",
85+
"build:node:no-eventsource": "cross-env OUTPUT_DIR=lib/no-eventsource USE_EVENTSOURCE=false yarn build:node",
86+
"build:node:minimal": "cross-env OUTPUT_DIR=lib/minimal USE_AXIOS=false USE_EVENTSOURCE=false yarn build:node",
87+
"build:node:all": "yarn build:node && yarn build:node:no-axios && yarn build:node:no-eventsource && yarn build:node:minimal",
88+
"clean:temp": "rm -f ./config/tsconfig.tmp.json",
89+
"build:ts": "node config/set-output-dir.js && tsc -p ./config/tsconfig.tmp.json && yarn clean:temp",
4690
"build:test": "tsc -p ./test/unit/tsconfig.json",
4791
"build:browser": "webpack -c config/webpack.config.browser.js",
92+
"build:browser:no-axios": "cross-env USE_AXIOS=false webpack -c config/webpack.config.browser.js",
93+
"build:browser:no-eventsource": "cross-env USE_EVENTSOURCE=false webpack -c config/webpack.config.browser.js",
94+
"build:browser:minimal": "cross-env USE_AXIOS=false USE_EVENTSOURCE=false webpack -c config/webpack.config.browser.js",
95+
"build:browser:all": "yarn build:browser && cross-env no_clean=true yarn build:browser:no-axios && cross-env no_clean=true yarn build:browser:no-eventsource && cross-env no_clean=true yarn build:browser:minimal",
4896
"build:docs": "cross-env NODE_ENV=docs yarn _babel",
4997
"clean": "rm -rf lib/ dist/ coverage/ .nyc_output/ jsdoc/ test/e2e/.soroban",
5098
"docs": "yarn build:docs && jsdoc -c ./config/.jsdoc.json --verbose",
@@ -53,11 +101,12 @@
53101
"test:node": "yarn _nyc mocha --recursive 'test/unit/**/*.js'",
54102
"test:integration": "yarn _nyc mocha --recursive 'test/integration/**/*.js'",
55103
"test:browser": "karma start config/karma.conf.js",
104+
"test:browser:no-axios": "cross-env USE_AXIOS=false yarn build:browser && cross-env USE_AXIOS=false karma start config/karma.conf.js",
56105
"fmt": "yarn _prettier && yarn eslint -c .eslintrc.js src/ --fix",
57106
"preversion": "yarn clean && yarn _prettier && yarn build:prod && yarn test",
58107
"prepare": "yarn build:prod",
59-
"_build": "yarn build:node && yarn build:test && yarn build:browser",
60-
"_babel": "babel --extensions '.ts' --out-dir lib/ src/",
108+
"_build": "yarn build:node:all && yarn build:test && yarn build:browser:all",
109+
"_babel": "babel --extensions '.ts' --out-dir ${OUTPUT_DIR:-lib} src/",
61110
"_nyc": "nyc --nycrc-path config/.nycrc",
62111
"_prettier": "prettier --ignore-path config/.prettierignore --write './test/**/*.js'"
63112
},
@@ -116,6 +165,7 @@
116165
"axios-mock-adapter": "^1.22.0",
117166
"babel-loader": "^9.1.3",
118167
"babel-plugin-istanbul": "^7.0.0",
168+
"babel-plugin-transform-define": "^2.1.4",
119169
"buffer": "^6.0.3",
120170
"chai": "^4.3.10",
121171
"chai-as-promised": "^7.1.1",
@@ -149,6 +199,7 @@
149199
"minami": "^1.1.1",
150200
"mocha": "^10.6.0",
151201
"node-polyfill-webpack-plugin": "^3.0.0",
202+
"null-loader": "^4.0.1",
152203
"nyc": "^17.0.0",
153204
"prettier": "^3.3.3",
154205
"randombytes": "^2.1.0",
@@ -166,6 +217,7 @@
166217
"axios": "^1.7.7",
167218
"bignumber.js": "^9.1.2",
168219
"eventsource": "^2.0.2",
220+
"feaxios": "^0.0.20",
169221
"randombytes": "^2.1.0",
170222
"toml": "^3.0.0",
171223
"urijs": "^1.19.1"

src/browser.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
/* tslint:disable:no-var-requires */
22
/* eslint import/no-import-module-exports: 0 */
3-
4-
import axios from "axios"; // idk why axios is weird
3+
import { httpClient } from "./http-client";
54

65
export * from "./index";
76
export * as StellarBase from "@stellar/stellar-base";
8-
export { axios };
7+
export { httpClient };
98

109
export default module.exports;

src/federation/server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/* eslint-disable require-await */
2-
import axios from "axios";
32
import { StrKey } from "@stellar/stellar-base";
43
import URI from "urijs";
54

@@ -8,6 +7,7 @@ import { BadResponseError } from "../errors";
87
import { Resolver } from "../stellartoml";
98

109
import { Api } from "./api";
10+
import { httpClient } from "../http-client";
1111

1212
// FEDERATION_RESPONSE_MAX_SIZE is the maximum size of response from a federation server
1313
export const FEDERATION_RESPONSE_MAX_SIZE = 100 * 1024;
@@ -218,7 +218,7 @@ export class FederationServer {
218218
private async _sendRequest(url: URI) {
219219
const timeout = this.timeout;
220220

221-
return axios
221+
return httpClient
222222
.get(url.toString(), {
223223
maxContentLength: FEDERATION_RESPONSE_MAX_SIZE,
224224
timeout,

0 commit comments

Comments
 (0)