如何正确销毁并重新初始化Ember应用?多应用加载报错求助
Hey there, I’ve run into this exact issue when building microfrontends with single-spa and Ember—let’s break down what’s going wrong and how to fix it!
That Cannot redefine property: Inflector error happens because Ember’s Inflector (the core utility for pluralization/singularization) gets stored in a shared scope—either the global window object or your module loader’s cache—when your first Ember app loads. When you unmount that app and try to load another Ember app, the second one attempts to redefine Inflector, but the existing property is marked as non-configurable. JavaScript blocks this, hence the TypeError.
Let’s walk through actionable steps to resolve this and properly manage Ember app destruction/initialization:
Use single-spa-ember’s Isolation Features
single-spa-ember has built-in configurations to minimize cross-app conflicts. When registering your Ember app, use thecustomEmberEnvoption to avoid polluting a shared global Ember environment:singleSpa.registerApplication( 'ember-app-one', () => import('single-spa-ember/parcel').then(parcel => parcel.default({ appName: 'ember-app-one', createEmberApp: () => import('./ember-app-one/app'), // Override the default env to keep this app isolated customEmberEnv: { FEATURES: {}, APP: { name: 'ember-app-one' } } }) ), location => location.pathname.startsWith('/ember-app-one') );Repeat this for your second app with a unique
appNameandcustomEmberEnvto ensure each app runs in its own isolated context.Thoroughly Clean Up During Unmount
Destroying the Ember app instance isn’t enough—you need to clear leftover globals and module cache entries. Add this cleanup logic to your app’s unmount hook:async function unmountEmberApp(props) { // First, properly destroy the Ember app instance await props.emberAppInstance.destroy(); // Remove Inflector from the module cache (adjust the path for your Ember version if needed) const inflectorModulePath = require.resolve('@ember-data/inflector'); if (require.cache[inflectorModulePath]) { delete require.cache[inflectorModulePath]; } // Make the global Inflector property configurable before deleting it if (window.Inflector) { Object.defineProperty(window, 'Inflector', { configurable: true, writable: true }); delete window.Inflector; } }You can attach this hook directly in your single-spa parcel config by adding an
unmountproperty.Set Unique Module Prefixes for Each Ember App
In each Ember app’sconfig/environment.js, define a uniquemodulePrefixto avoid module naming collisions:// config/environment.js for ember-app-one module.exports = function(environment) { const ENV = { modulePrefix: 'ember-app-one', // ... rest of your config }; return ENV; };Do the same for your second app (e.g.,
modulePrefix: 'ember-app-two'). This ensures Ember’s module system doesn’t mix up components, services, or utilities between your apps.
The core idea here is isolation and thorough cleanup. By isolating each Ember app’s environment and clearing out all residual data during unmount, you’ll avoid the Inflector redefinition error and ensure smooth transitions between apps.
内容的提问来源于stack exchange,提问作者Deewendra Shrestha

