Vue CLI Plugin for single-spa
vue-cli-plugin-single-spa is an official plugin for Vue CLI that streamlines the process of integrating Vue applications into a single-spa microfrontend architecture. It automatically handles the necessary Webpack configuration and scaffolding to transform a standard Vue project into a single-spa microfrontend or parcel. The current stable version is 4.0.0, which notably shifted the default Webpack output module format to native ES modules. The project maintains a moderate release cadence, with consistent updates addressing Webpack compatibility, security, and feature enhancements. Its primary differentiator is its deep integration with the Vue CLI ecosystem, offering a simplified developer experience for creating single-spa compatible Vue applications without extensive manual Webpack configuration.
Common errors
-
ERROR Cannot use import statement outside a module
cause With vue-cli-plugin-single-spa v4.0.0+, the default Webpack output format is native ES modules, which may conflict with environments expecting UMD or SystemJS.fixAdd `pluginOptions['single-spa'].outputSystemJS: true` to your `vue.config.js` file to revert to UMD/SystemJS compatible output. -
Webpack build fails with module not found errors for 'single-spa' or other single-spa related packages.
cause Webpack might not be correctly configured to treat `single-spa` and its related libraries as external dependencies, leading to bundling issues.fixEnsure `single-spa` is correctly marked as a Webpack external. While the plugin handles this, custom Webpack configurations in `vue.config.js` might override it. Verify `webpack-chain` or `configureWebpack` modifications are not interfering. -
TypeError: 'this' is undefined or 'app.use' is not a function when loading the Vue microfrontend.
cause Vue's instance creation or lifecycle hooks are not correctly integrated with `single-spa-vue`'s `bootstrap`, `mount`, and `unmount` functions, or the Vue instance isn't properly created.fixVerify that your `main.js` (or entry file) exports the `bootstrap`, `mount`, and `unmount` functions returned by `singleSpaVue({})` and that `createApp` is correctly passed. Ensure `app.use()` calls for plugins like Vue Router or Vuex are inside the `handleInstance` callback.
Warnings
- breaking With v4.0.0, the default output module format now defaults to native ES modules (`"libraryTarget": "module"` in webpack). This may cause compatibility issues with older single-spa root configurations that expect UMD or SystemJS module formats.
- breaking Version 3.0.0 upgraded the underlying `standalone-single-spa-webpack-plugin` from v1 to v3. While most projects can safely upgrade, it's recommended to review the breaking changes for `standalone-single-spa-webpack-plugin` if you encounter unexpected build or runtime issues.
- gotcha Version 3.3.0 introduced critical fixes for Webpack 5 compatibility. Using versions prior to 3.3.0 with Webpack 5 may lead to build failures or unexpected behavior.
- gotcha This plugin relies on `webpack` as a peer dependency. Incompatibility between the plugin's expected Webpack version and your project's installed Webpack version can lead to build errors. Ensure your `webpack` version is compatible.
- gotcha As a CLI plugin that generates and modifies project configurations, it's crucial to ensure supply chain security. Always verify the source and integrity of downloaded packages to mitigate risks.
Install
-
npm install vue-cli-plugin-single-spa -
yarn add vue-cli-plugin-single-spa -
pnpm add vue-cli-plugin-single-spa
Imports
- N/A (CLI Command)
vue add single-spa
- singleSpaVue
import { singleSpaVue } from 'single-spa-vue'import singleSpaVue from 'single-spa-vue'
- defineApplication
import defineApplication from 'single-spa'
import { defineApplication } from 'single-spa'
Quickstart
{
// Step 1: Create a new Vue project (if you don't have one)
// vue create my-single-spa-app
// cd my-single-spa-app
// Step 2: Add the single-spa plugin
// Run this command in your project's root directory:
// vue add single-spa@latest
// The plugin will modify your main.ts (or main.js) to look similar to this:
// main.ts (or main.js)
import { h, createApp } from 'vue';
import singleSpaVue from 'single-spa-vue';
import App from './App.vue';
// import router from './router'; // Uncomment if you have vue-router installed
// import store from './store'; // Uncomment if you have Vuex installed
const vueLifecycles = singleSpaVue({
createApp,
appOptions: {
render() {
return h(App, {
props: {
// single-spa props are passed as "custom props" to the root component
name: this.name,
mountParcel: this.mountParcel,
singleSpa: this.singleSpa
}
});
},
// Uncomment the following if you use Vuex or Vue Router
// el: '#app', // Not typically needed for single-spa apps unless rendering standalone
},
handleInstance(app) {
// app.use(router); // Apply vue-router
// app.use(store); // Apply Vuex store
},
});
export const bootstrap = vueLifecycles.bootstrap;
export const mount = vueLifecycles.mount;
export const unmount = vueLifecycles.unmount;
}