Skip to content

Commit

Permalink
Add a way to build without axios (#1038)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
BlaineHeffron authored Sep 24, 2024
1 parent 64bb331 commit 4aba86f
Show file tree
Hide file tree
Showing 32 changed files with 671 additions and 113 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,8 @@ jobs:
- name: Browser Tests
run: yarn test:browser

- name: Browser No Axios Tests
run: yarn test:browser:no-axios

- name: Linter Tests
run: yarn _prettier && (git diff-index --quiet HEAD; git diff)
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ test/unit/out/

target
.soroban

config/tsconfig.tmp.json
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ export interface BalanceResponse {
}
```

- 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.
- 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`.
## [Version Number] - YYYY-MM-DD
- Updated the Node.js target in the Babel configuration from 16 to 18 for production builds.

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

Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ If you don't want to use or install Bower, you can copy the packaged JS files fr
| 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. |
|----|

### Custom Installation

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.

#### Build without Axios
USE_AXIOS=false npm run build:browser

## Usage

The usage documentation for this library lives in a handful of places:
Expand Down
40 changes: 40 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const buildConfig = require('./config/build.config');
const fs = require('fs');
const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
const version = packageJson.version;

module.exports = function(api) {
api.cache(true);

const presets = [
"@babel/preset-env",
"@babel/typescript"
];

const plugins = [];

if (process.env.NODE_ENV === 'development') {
plugins.push('istanbul');
}

// Add the define plugin
plugins.push([
'babel-plugin-transform-define',
{
__USE_AXIOS__: buildConfig.useAxios,
__USE_EVENTSOURCE__: buildConfig.useEventSource,
__PACKAGE_VERSION__: version,
}
]);

const config = {
comments: process.env.NODE_ENV !== 'production',
presets,
plugins,
targets: process.env.NODE_ENV === 'production'
? { node: 18, browsers: ["> 2%", "ie 11", "not op_mini all"] }
: { browsers: ["> 2%"] }
};

return config;
};
26 changes: 0 additions & 26 deletions babel.config.json

This file was deleted.

4 changes: 4 additions & 0 deletions config/build.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
useAxios: process.env.USE_AXIOS !== 'false',
useEventSource: process.env.USE_EVENTSOURCE !== 'false',
};
10 changes: 9 additions & 1 deletion config/karma.conf.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
const webpackConfig = require('./webpack.config.browser.js');
const buildConfig = require('./build.config');

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

function getStellarSdkFileName() {
let name = 'stellar-sdk';
if (!buildConfig.useAxios) name += '-no-axios';
if (!buildConfig.useEventSource) name += '-no-eventsource';
return name + '.js';
}

module.exports = function (config) {
config.set({
frameworks: ['mocha', 'sinon-chai'],
browsers: ['FirefoxHeadless', 'ChromeHeadless'],

files: [
'../dist/stellar-sdk.js', // webpack should build this first
'../dist/' + getStellarSdkFileName(),
'../test/test-browser.js',
'../test/unit/**/*.js'
],
Expand Down
14 changes: 14 additions & 0 deletions config/set-output-dir.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const fs = require('fs');
const path = require('path');

const OUTPUT_DIR = process.env.OUTPUT_DIR || 'lib';
const tsconfigPath = path.resolve(__dirname, 'tsconfig.json');
const tempTsconfigPath = path.resolve(__dirname, 'tsconfig.tmp.json');

const tsconfig = require(tsconfigPath);
tsconfig.compilerOptions.outDir = path.resolve(__dirname, '..', OUTPUT_DIR);
tsconfig.compilerOptions.declarationDir = path.resolve(__dirname, '..', OUTPUT_DIR);

fs.writeFileSync(tempTsconfigPath, JSON.stringify(tsconfig, null, 2), 'utf8');

console.log(`Set TypeScript outDir to ${OUTPUT_DIR} in temporary tsconfig file.`);
40 changes: 36 additions & 4 deletions config/webpack.config.browser.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
var path = require('path');
var webpack = require('webpack');
var fs = require('fs');

var ESLintPlugin = require('eslint-webpack-plugin');
var TerserPlugin = require('terser-webpack-plugin');
var NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
var buildConfig = require('./build.config');

// Read the version from package.json
const packageJson = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../package.json'), 'utf8'));
const version = packageJson.version;

const config = {
target: 'web',
Expand All @@ -16,17 +22,34 @@ const config = {
fallback: {
crypto: require.resolve('crypto-browserify'),
stream: require.resolve('stream-browserify'),
buffer: require.resolve('buffer')
buffer: require.resolve('buffer'),
},
extensions: ['.ts', '.js']
extensions: ['.ts', '.js'],
},
output: {
clean: true,
clean: process.env.no_clean ? false: true,
library: {
name: 'StellarSdk',
type: 'umd',
umdNamedDefine: true
},
filename: (pathData) => {
let name = pathData.chunk.name;
let suffix = '';

if (name.endsWith('.min')) {
name = name.slice(0, -4); // Remove .min
suffix = '.min.js';
} else {
suffix = '.js';
}

if (!buildConfig.useAxios && !buildConfig.useEventSource) name += '-minimal';
else if (!buildConfig.useAxios) name += '-no-axios';
else if (!buildConfig.useEventSource) name += '-no-eventsource';

return name + suffix;
},
path: path.resolve(__dirname, '../dist')
},
mode: process.env.NODE_ENV ?? 'development',
Expand All @@ -42,7 +65,11 @@ const config = {
cacheDirectory: true
}
}
}
},
{
test: /node_modules\/https-proxy-agent\//,
use: 'null-loader',
},
]
},
optimization: {
Expand Down Expand Up @@ -70,6 +97,11 @@ const config = {
}),
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer']
}),
new webpack.DefinePlugin({
__USE_AXIOS__: JSON.stringify(buildConfig.useAxios),
__USE_EVENTSOURCE__: JSON.stringify(buildConfig.useEventSource),
__PACKAGE_VERSION__: version,
})
],
watchOptions: {
Expand Down
58 changes: 55 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,63 @@
"./rpc": {
"types": "./lib/rpc/index.d.ts",
"default": "./lib/rpc/index.js"
},
"./no-axios": {
"browser": "./dist/stellar-sdk-no-axios.min.js",
"types": "./lib/no-axios/index.d.ts",
"default": "./lib/no-axios/index.js"
},
"./no-axios/contract": {
"types": "./lib/no-axios/contract/index.d.ts",
"default": "./lib/no-axios/contract/index.js"
},
"./no-axios/rpc": {
"types": "./lib/no-axios/rpc/index.d.ts",
"default": "./lib/no-axios/rpc/index.js"
},
"./no-eventsource": {
"browser": "./dist/stellar-sdk-no-eventsource.min.js",
"types": "./lib/no-eventsource/index.d.ts",
"default": "./lib/no-eventsource/index.js"
},
"./no-eventsource/contract": {
"types": "./lib/no-eventsource/contract/index.d.ts",
"default": "./lib/no-eventsource/contract/index.js"
},
"./no-eventsource/rpc": {
"types": "./lib/no-eventsource/rpc/index.d.ts",
"default": "./lib/no-eventsource/rpc/index.js"
},
"./minimal": {
"browser": "./dist/stellar-sdk-minimal.min.js",
"types": "./lib/minimal/index.d.ts",
"default": "./lib/minimal/index.js"
},
"./minimal/contract": {
"types": "./lib/minimal/contract/index.d.ts",
"default": "./lib/minimal/contract/index.js"
},
"./minimal/rpc": {
"types": "./lib/minimal/rpc/index.d.ts",
"default": "./lib/minimal/rpc/index.js"
}
},
"scripts": {
"build": "cross-env NODE_ENV=development yarn _build",
"build:prod": "cross-env NODE_ENV=production yarn _build",
"build:node": "yarn _babel && yarn build:ts",
"build:ts": "tsc -p ./config/tsconfig.json",
"build:node:no-axios": "cross-env OUTPUT_DIR=lib/no-axios USE_AXIOS=false yarn build:node",
"build:node:no-eventsource": "cross-env OUTPUT_DIR=lib/no-eventsource USE_EVENTSOURCE=false yarn build:node",
"build:node:minimal": "cross-env OUTPUT_DIR=lib/minimal USE_AXIOS=false USE_EVENTSOURCE=false yarn build:node",
"build:node:all": "yarn build:node && yarn build:node:no-axios && yarn build:node:no-eventsource && yarn build:node:minimal",
"clean:temp": "rm -f ./config/tsconfig.tmp.json",
"build:ts": "node config/set-output-dir.js && tsc -p ./config/tsconfig.tmp.json && yarn clean:temp",
"build:test": "tsc -p ./test/unit/tsconfig.json",
"build:browser": "webpack -c config/webpack.config.browser.js",
"build:browser:no-axios": "cross-env USE_AXIOS=false webpack -c config/webpack.config.browser.js",
"build:browser:no-eventsource": "cross-env USE_EVENTSOURCE=false webpack -c config/webpack.config.browser.js",
"build:browser:minimal": "cross-env USE_AXIOS=false USE_EVENTSOURCE=false webpack -c config/webpack.config.browser.js",
"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",
"build:docs": "cross-env NODE_ENV=docs yarn _babel",
"clean": "rm -rf lib/ dist/ coverage/ .nyc_output/ jsdoc/ test/e2e/.soroban",
"docs": "yarn build:docs && jsdoc -c ./config/.jsdoc.json --verbose",
Expand All @@ -53,11 +101,12 @@
"test:node": "yarn _nyc mocha --recursive 'test/unit/**/*.js'",
"test:integration": "yarn _nyc mocha --recursive 'test/integration/**/*.js'",
"test:browser": "karma start config/karma.conf.js",
"test:browser:no-axios": "cross-env USE_AXIOS=false yarn build:browser && cross-env USE_AXIOS=false karma start config/karma.conf.js",
"fmt": "yarn _prettier && yarn eslint -c .eslintrc.js src/ --fix",
"preversion": "yarn clean && yarn _prettier && yarn build:prod && yarn test",
"prepare": "yarn build:prod",
"_build": "yarn build:node && yarn build:test && yarn build:browser",
"_babel": "babel --extensions '.ts' --out-dir lib/ src/",
"_build": "yarn build:node:all && yarn build:test && yarn build:browser:all",
"_babel": "babel --extensions '.ts' --out-dir ${OUTPUT_DIR:-lib} src/",
"_nyc": "nyc --nycrc-path config/.nycrc",
"_prettier": "prettier --ignore-path config/.prettierignore --write './test/**/*.js'"
},
Expand Down Expand Up @@ -116,6 +165,7 @@
"axios-mock-adapter": "^1.22.0",
"babel-loader": "^9.1.3",
"babel-plugin-istanbul": "^7.0.0",
"babel-plugin-transform-define": "^2.1.4",
"buffer": "^6.0.3",
"chai": "^4.3.10",
"chai-as-promised": "^7.1.1",
Expand Down Expand Up @@ -149,6 +199,7 @@
"minami": "^1.1.1",
"mocha": "^10.6.0",
"node-polyfill-webpack-plugin": "^3.0.0",
"null-loader": "^4.0.1",
"nyc": "^17.0.0",
"prettier": "^3.3.3",
"randombytes": "^2.1.0",
Expand All @@ -166,6 +217,7 @@
"axios": "^1.7.7",
"bignumber.js": "^9.1.2",
"eventsource": "^2.0.2",
"feaxios": "^0.0.20",
"randombytes": "^2.1.0",
"toml": "^3.0.0",
"urijs": "^1.19.1"
Expand Down
5 changes: 2 additions & 3 deletions src/browser.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
/* tslint:disable:no-var-requires */
/* eslint import/no-import-module-exports: 0 */

import axios from "axios"; // idk why axios is weird
import { httpClient } from "./http-client";

export * from "./index";
export * as StellarBase from "@stellar/stellar-base";
export { axios };
export { httpClient };

export default module.exports;
4 changes: 2 additions & 2 deletions src/federation/server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/* eslint-disable require-await */
import axios from "axios";
import { StrKey } from "@stellar/stellar-base";
import URI from "urijs";

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

import { Api } from "./api";
import { httpClient } from "../http-client";

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

return axios
return httpClient
.get(url.toString(), {
maxContentLength: FEDERATION_RESPONSE_MAX_SIZE,
timeout,
Expand Down
Loading

0 comments on commit 4aba86f

Please sign in to comment.