id: ecosystem-ember title: single-spa-ember

sidebar_label: Ember

single-spa-ember 是一个它可以帮助Ember应用程序实现single-spa 应用需要的生命周期函数 (bootstrap、mount和unmount)的辅助库,以便与[ember.js]一起使用(https://www.emberjs.com/)。请查看[single spa ember github](https://github.com/single-spa/single-spa-ember)

为了方便bower和ember cli一起使用的场景。它在npm和bower上都以single-spa-ember的形式提供。

概述

构建ember应用程序作为single-spa应用程序工作时,需要实现五件事:

除活动函数以外,Single-spa-ember会帮助您实现所有功能。

注意,加载和活动函数是single spa root application的一部分,而引导、装载和卸载函数是single spa application的一部分。

API

加载Ember应用程序

loadEmberApp(appName,appUrl,vendorUrl)是一个为ember应用程序实现加载函数的方法。appName and appUrl都是必填的字符串,而vendorUrl是可选的字符串。

  1. // In the single-spa root application
  2. import {registerApplication} from 'single-spa';
  3. import {loadEmberApp} from 'single-spa-ember';
  4. const name = 'ember-app';
  5. const app = () => loadEmberApp(name, '/dist/ember-app/assets/ember-app.js', '/dist/ember-app/assets/vendor.js');
  6. const activeWhen = location => location.hash.startsWith('ember');
  7. registerApplication({ name, app, activeWhen });

singleSpaEmber

要使用Single-spa-ember的single-spa生命周期函数,要调用一个带有配置对象的导出函数,该对象是具有bootstrapmountunmount生命周期函数。具有以下选项:

  1. // In the ember application
  2. import singleSpaEmber from 'single-spa-ember/src/single-spa-ember';
  3. const emberLifecycles = singleSpaEmber({
  4. appName: 'ember-app', // required
  5. createOpts: { // See https://www.emberjs.com/api/ember/2.14.1/classes/Ember.Application
  6. rootElement: '#ember-app',
  7. },
  8. });
  9. export const bootstrap = emberLifecycles.bootstrap;
  10. export const mount = emberLifecycles.mount;
  11. export const unmount = emberLifecycles.unmount;

使用ember cli

在大多数情况下,使用ember cli的应用程序都可以与single-spa很好的工作。有一个不同的是,ember cli会控制整个html页面,但一个single-spa应用程序不是这样。所以,通常我们可以通过动态地将供应商和应用程序捆绑包加载到html页面中,而不是直接将它们烘焙到html页面中来实现相同的行为。以下是在使用single-spa设置ember cli应用程序时应执行的已知操作:

因为ember cli只支持来自bower的依赖项,所以需要执行以下操作:

  • bower init
  • bower install single-spa-ember --save

将以下选项添加到ember-cli-build.js文件中:

  1. /* eslint-env node */
  2. 'use strict';
  3. const EmberApp = require('ember-cli/lib/broccoli/ember-app');
  4. module.exports = function(defaults) {
  5. let app = new EmberApp(defaults, {
  6. autoRun: false, // Set autoRun to false, because we only want the ember app to render to the DOM when single-spa tells it to.
  7. storeConfigInMeta: false, // We're making a single-spa application, which doesn't exclusively own the HTML file. So we don't want to have to have a `<meta>` tag for the ember environment to be initialized.
  8. fingerprint: {
  9. customHash: null, // This is optional, just will make it easier for you to have the same url every time you do an ember build.
  10. },
  11. // Add options here
  12. });
  13. // Tell ember how to use the single-spa-ember library
  14. app.import('bower_components/single-spa-ember/amd/single-spa-ember.js', {
  15. using: [
  16. {transformation: 'amd', as: 'single-spa-ember'},
  17. ],
  18. });
  19. return app.toTree();
  20. };

在single-spa根应用程序中(独立于由ember cli生成的任何内容):

  1. // root-application.js
  2. import * as singleSpa from 'single-spa';
  3. import {loadEmberApp} from 'single-spa-ember';
  4. singleSpa.registerApplication('ember-app', loadingFunction, activityFunction);
  5. function activityFunction(location) {
  6. // Only render the ember app when the url hash starts with ember
  7. return location.hash.startsWith('ember');
  8. }
  9. // single-spa-ember helps us load the script tags and give the ember app module to single-spa.
  10. function loadingFunction() {
  11. const appName = 'ember-app';
  12. const appUrl = '/dist/ember-app/assets/ember-app.js';
  13. const vendorUrl = '/dist/ember-app/assets/vendor.js'; // Optional if you have one vendor bundle used for many different ember apps
  14. return loadEmberApp(appName, appUrl, vendorUrl);
  15. }

在app.js文件中(ember cli生成)

  1. // app.js (the ember application)
  2. import Ember from 'ember';
  3. import Resolver from './resolver';
  4. import loadInitializers from 'ember-load-initializers';
  5. import config from './config/environment';
  6. import singleSpaEmber from 'single-spa-ember';
  7. // This part is generated by the ember cli
  8. const App = Ember.Application.extend({
  9. modulePrefix: config.modulePrefix,
  10. podModulePrefix: config.podModulePrefix,
  11. Resolver
  12. });
  13. loadInitializers(App, config.modulePrefix);
  14. export default App;
  15. // This is the single-spa part
  16. const emberLifecycles = singleSpaEmber({
  17. App, // required
  18. appName: 'ember-app', // required
  19. createOpts: { // optional
  20. rootElement: '#ember-app',
  21. },
  22. })
  23. // Single-spa lifecycles.
  24. export const bootstrap = emberLifecycles.bootstrap;
  25. export const mount = emberLifecycles.mount;
  26. export const unmount = emberLifecycles.unmount;