docs/faq/index.md
This FAQ covers the most common questions and issues encountered when working with qiankun. If you can't find the answer you're looking for, please check our GitHub Issues or join our community discussions.
A: qiankun is a micro-frontend framework based on single-spa that enables you to build large-scale frontend applications by composing multiple smaller, independent applications. You should consider qiankun when:
A: qiankun provides several key advantages:
A: Yes! qiankun is designed to work with existing applications. You can:
A: CORS errors are common in development. Here are solutions:
For webpack dev server:
// webpack.config.js or vue.config.js
module.exports = {
devServer: {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization'
}
}
};
For Create React App (using CRACO):
// craco.config.js
module.exports = {
devServer: {
headers: {
'Access-Control-Allow-Origin': '*'
}
}
};
For production, configure your server:
# nginx.conf
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
}
A: Follow this troubleshooting checklist:
Example of correct micro app export:
// Micro app entry file
export async function bootstrap() {
console.log('micro app bootstrapped');
}
export async function mount(props) {
console.log('micro app mounted', props);
// Your app mounting logic
}
export async function unmount(props) {
console.log('micro app unmounted', props);
// Your app cleanup logic
}
A: Configure the public path in your micro applications:
For webpack:
// webpack.config.js
module.exports = {
output: {
publicPath: process.env.NODE_ENV === 'production'
? 'https://mycdn.com/micro-app/'
: 'http://localhost:8080/'
}
};
For runtime configuration:
// public-path.js in your micro app
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
A: Follow these architectural principles:
1. Domain-driven design:
Main App (Shell)
āāā User Management (HR Domain)
āāā Product Catalog (Commerce Domain)
āāā Analytics Dashboard (BI Domain)
āāā Settings (System Domain)
2. Shared vs. Independent:
3. Communication patterns:
// Event-driven communication
window.dispatchEvent(new CustomEvent('user-updated', {
detail: { userId: 123 }
}));
// Props-based communication
registerMicroApps([{
name: 'user-app',
entry: '//localhost:8080',
container: '#container',
activeRule: '/users',
props: {
userPermissions: currentUser.permissions,
onUserUpdate: handleUserUpdate
}
}]);
A: Several approaches work well:
1. External dependencies (recommended):
// webpack.config.js
module.exports = {
externals: {
'react': 'React',
'react-dom': 'ReactDOM',
'lodash': '_'
}
};
2. Module Federation:
// Main app webpack config
new ModuleFederationPlugin({
name: 'shell',
shared: {
react: { singleton: true },
'react-dom': { singleton: true }
}
});
3. CDN approach:
<!-- Load shared libraries from CDN -->
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
A: Yes, here are the recommended patterns:
1. Event-driven communication:
// Micro app A
const notifyOtherApps = (data) => {
window.dispatchEvent(new CustomEvent('app-a-event', { detail: data }));
};
// Micro app B
window.addEventListener('app-a-event', (event) => {
console.log('Received from app A:', event.detail);
});
2. Shared state management:
// Global store
window.__SHARED_STORE__ = {
user: null,
subscribe: [],
updateUser: (user) => {
window.__SHARED_STORE__.user = user;
window.__SHARED_STORE__.subscribers.forEach(callback => callback(user));
}
};
3. Props from main app:
// Main app coordinates communication
const handleDataChange = (data) => {
// Update props for all relevant micro apps
updateMicroAppProps('app-a', { sharedData: data });
updateMicroAppProps('app-b', { sharedData: data });
};
A: Use qiankun's built-in style isolation:
1. Strict style isolation (Shadow DOM):
import { start } from 'qiankun';
start({
sandbox: {
strictStyleIsolation: true
}
});
2. Experimental style isolation (CSS scoping):
start({
sandbox: {
experimentalStyleIsolation: true
}
});
3. Manual CSS scoping:
/* Prefix all your styles */
.my-micro-app .button {
background: blue;
}
.my-micro-app .container {
padding: 20px;
}
See our Style Isolation Guide for comprehensive solutions.
A: Absolutely! CSS-in-JS libraries work great with qiankun:
Styled Components:
import styled from 'styled-components';
const Button = styled.button`
background: blue;
color: white;
`;
Emotion:
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
const buttonStyle = css`
background: blue;
color: white;
`;
CSS-in-JS provides natural isolation since styles are scoped to components.
A: qiankun supports multiple routing strategies:
1. Route-based micro apps (recommended):
registerMicroApps([
{
name: 'user-management',
entry: '//localhost:8080',
container: '#container',
activeRule: '/users' // Loads when route starts with /users
},
{
name: 'product-catalog',
entry: '//localhost:8081',
container: '#container',
activeRule: ['/products', '/categories'] // Multiple routes
}
]);
2. Programmatic routing:
// Navigate between micro apps
import { navigateToUrl } from 'single-spa';
const navigateToUsers = () => {
navigateToUrl('/users');
};
3. Hash routing:
registerMicroApps([
{
name: 'hash-app',
entry: '//localhost:8080',
container: '#container',
activeRule: '#/app' // Hash-based routing
}
]);
A: Yes! Each micro application can have its own internal router:
React Router example:
// In your micro app
import { BrowserRouter, Routes, Route } from 'react-router-dom';
function App() {
const basename = window.__POWERED_BY_QIANKUN__ ? '/users' : '/';
return (
<BrowserRouter basename={basename}>
<Routes>
<Route path="/" element={<UserList />} />
<Route path="/profile" element={<UserProfile />} />
<Route path="/settings" element={<UserSettings />} />
</Routes>
</BrowserRouter>
);
}
A: Follow these optimization strategies:
1. Enable prefetching:
start({
prefetch: true // or 'all' or specific app names
});
2. Use code splitting:
// Dynamic imports in micro apps
const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
3. Optimize bundle sizes:
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all'
}
}
};
See our Performance Optimization Guide for detailed strategies.
A: Implement proper cleanup:
// Micro app lifecycle
export async function unmount() {
// Clear timers
clearInterval(myInterval);
// Remove event listeners
window.removeEventListener('resize', handleResize);
// Clean up subscriptions
subscription.unsubscribe();
// Clear caches
cache.clear();
}
A: Use these debugging strategies:
1. Enable source maps:
// webpack.config.js
module.exports = {
devtool: 'source-map'
};
2. Use browser dev tools:
3. qiankun debugging:
// Enable detailed logging
localStorage.setItem('qiankun:debug', true);
A: Yes, with some configuration:
For webpack dev server:
// webpack.config.js
module.exports = {
devServer: {
hot: true,
headers: {
'Access-Control-Allow-Origin': '*'
}
}
};
Note: Hot reload works within each micro app, but changes to the main app may require a full refresh.
A: Centralize authentication in the main application:
1. Token-based authentication:
// Main app handles auth
const userToken = await authenticate(credentials);
localStorage.setItem('token', userToken);
// Pass token to micro apps
registerMicroApps([{
name: 'secure-app',
entry: '//localhost:8080',
container: '#container',
activeRule: '/secure',
props: {
token: userToken,
user: currentUser
}
}]);
2. Shared authentication state:
// Global auth state
window.__AUTH_STATE__ = {
user: currentUser,
token: userToken,
isAuthenticated: true
};
A: Be aware of these security considerations:
1. Content Security Policy (CSP):
<meta http-equiv="Content-Security-Policy"
content="script-src 'self' https://trusted-cdn.com;">
2. CORS configuration:
3. Dependency security:
npm auditA: Yes, qiankun works on mobile with considerations:
1. Touch event optimization:
// Use passive listeners
element.addEventListener('touchstart', handler, { passive: true });
2. Viewport management:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
3. Performance optimization:
A: qiankun supports modern browsers:
For older browsers, consider polyfills:
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
A: Use independent deployment strategy:
1. Separate builds:
# Build each app independently
cd main-app && npm run build
cd micro-app-1 && npm run build
cd micro-app-2 && npm run build
2. CDN deployment:
// Configure different CDNs for each app
const microApps = [
{
name: 'app-1',
entry: 'https://cdn1.example.com/app-1/',
container: '#container',
activeRule: '/app-1'
},
{
name: 'app-2',
entry: 'https://cdn2.example.com/app-2/',
container: '#container',
activeRule: '/app-2'
}
];
A: Implement version management:
1. Semantic versioning:
// Package.json for each micro app
{
"name": "user-management-app",
"version": "1.2.3"
}
2. Runtime version checking:
const requiredVersion = '1.2.0';
const currentVersion = window.__MICRO_APP_VERSION__;
if (!semver.gte(currentVersion, requiredVersion)) {
console.warn('Micro app version compatibility issue');
}
A: SSR with micro-frontends is complex but possible:
1. Static rendering:
2. Considerations:
Alternative approaches:
A: qiankun works with various build tools:
Webpack: Use @qiankunjs/webpack-plugin
Vite: Use vite-plugin-qiankun
Rollup: Manual configuration
Parcel: Manual configuration
See our Ecosystem section for specific integrations.
A: Multiple support channels are available:
qiankunA: We welcome contributions:
See our Contributing Guide for details.
Can't find what you're looking for? Please open an issue or start a discussion - we're here to help!