Ice.js Request Configuration Plugin
build-plugin-ice-request is a core plugin for the Ice.js (now often `@ice/app`) framework, designed to standardize and enhance network request handling within Ice.js applications. It facilitates global configuration of HTTP requests, leveraging an Axios-compatible interface. This includes setting up base URLs, timeouts, and defining request and response interceptors for global error handling, authentication, and data transformation. The plugin integrates deeply into the Ice.js runtime, exposing `request` (imperative) and `useRequest` (React hook) APIs for components to interact with the configured request service. The current stable version is `2.0.1`, with updates and compatibility closely tied to the frequent release cycle of the `@ice/app` framework (e.g., v3.x series). Its primary differentiator is its seamless integration into the Ice.js build and runtime, providing a consistent and configurable request layer across the application.
Common errors
-
TypeError: (0 , ice__WEBPACK_IMPORTED_MODULE_1__.request) is not a function
cause The `build-plugin-ice-request` is not correctly configured or enabled in the build system, or `request` is imported from the wrong package.fixVerify that `build-plugin-ice-request` is listed in your `build.json` (or equivalent Ice.js plugin configuration) and that `runApp` includes a `request` configuration block. Ensure `import { request } from 'ice';` is used. -
Property 'request' does not exist on type 'AppConfig'
cause TypeScript type definition mismatch, indicating either an outdated `@types/ice` package or a custom `AppConfig` interface that doesn't include the `request` property.fixUpdate `@ice/app` and any related `@types` packages (e.g., `@types/ice`) to match your framework version. If using a custom type, ensure it extends or includes the `request` property. -
Network Error
-
AxiosError: Request failed with status code 404
-
Error: timeout of 5000ms exceeded
cause Incorrect `baseURL` or API endpoint configuration in `appConfig.request`, a problem with the backend service, or an excessively short timeout.fixReview the `baseURL` in `appConfig.request` and the relative paths used in `request()` calls. Use request interceptors (`onConfig` for requests) to log the full request URL for debugging. Check your network tab for actual request URLs and server responses. Adjust `timeout` if network conditions require more time.
Warnings
- gotcha The global request configuration, including `baseURL`, `timeout`, and `interceptors`, must be defined within the `request` property of the `appConfig` object, which is passed to `runApp`. Attempting to configure these settings directly as a plugin option in `defineConfig` will not affect runtime request behavior.
- gotcha The `request` and `useRequest` functions are exposed directly from the main `ice` (or `@ice/app`) package, not from `build-plugin-ice-request`. Directly importing them from the plugin package (`import { request } from 'build-plugin-ice-request'`) will result in runtime errors.
- breaking While `build-plugin-ice-request` has its own versioning, its runtime behavior and API compatibility are tightly coupled with the major versions of the underlying Ice.js framework (now `@ice/app`). Using an incompatible plugin version with your framework version can lead to unexpected runtime issues or type mismatches.
Install
-
npm install build-plugin-ice-request -
yarn add build-plugin-ice-request -
pnpm add build-plugin-ice-request
Imports
- request
import { request } from 'build-plugin-ice-request'import { request } from 'ice' - useRequest
import { useRequest } from 'build-plugin-ice-request'import { useRequest } from 'ice' - runApp
const { runApp } = require('ice')import { runApp } from 'ice' - defineConfig
import { defineConfig } from 'ice'import { defineConfig } from '@ice/app'
Quickstart
// build.json (or similar build configuration file)
// Make sure to add the plugin to your Ice.js build configuration.
// For older Ice.js versions, this is often in build.json:
/*
{
"plugins": [
"build-plugin-ice-request"
]
}
*/
// src/app.ts (or src/index.ts - global application entry point)
import { runApp, request, useRequest } from 'ice';
import React, { useEffect } from 'react';
// Configure the global request service within your Ice.js application
const appConfig = {
request: {
baseURL: '/api', // Example: All requests will be prefixed with /api
timeout: 5000, // Example: Request timeout of 5 seconds
interceptors: {
request: {
onConfig: (config) => {
console.log('Request interceptor (onConfig):', config.url);
// Example: Add an authorization token to all requests
const token = localStorage.getItem('authToken');
if (token) {
config.headers = { ...config.headers, Authorization: `Bearer ${token}` };
}
return config;
},
onError: (error) => {
console.error('Request interceptor (onError):', error.message);
return Promise.reject(error);
}
},
response: {
onConfig: (response) => {
console.log('Response interceptor (onConfig):', response.config.url, response.status);
return response;
},
onError: (error) => {
console.error('Response interceptor (onError):', error.response?.status, error.message);
// Example: Handle 401 Unauthorized errors globally
if (error.response?.status === 401) {
alert('Session expired. Please log in again.');
// window.location.href = '/login'; // Redirect to login page
}
return Promise.reject(error);
}
}
}
}
};
// Initialize the Ice.js application with the configured request service
runApp(appConfig);
// Example Component Usage (in a React component within your Ice.js app)
const DataDisplay = () => {
// Using the useRequest hook for automatic data fetching
const { loading, error, data, request: fetchData } = useRequest({
url: '/users',
method: 'GET',
manual: true // Set to true to manually trigger the request
});
useEffect(() => {
fetchData(); // Trigger the request on component mount
}, [fetchData]);
// Using the imperative request function
const postData = async () => {
try {
const result = await request('/posts', { method: 'POST', data: { title: 'New Post', content: '...' } });
console.log('Post successful:', result);
} catch (err) {
console.error('Post failed:', err);
}
};
if (loading) return <div>Loading user data...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
<h2>Users:</h2>
<pre>{JSON.stringify(data, null, 2)}</pre>
<button onClick={postData}>Create New Post</button>
</div>
);
};
export default DataDisplay; // Export for routing or direct use in an Ice.js app