ember.js - 在单 Spa 中将 ember 应用程序作为子应用程序加载时出现问题

标签 ember.js systemjs

我尝试使用 ember 作为具有单个 spa( https://github.com/CanopyTax/single-spa ) 的子应用程序之一,但是我无法使用 systemJS 正确加载 js 文件 asset/vendor.js、assets/ember-app.js。

重现问题的步骤:

1) 使用 ember 设置单个水疗中心示例

git clone <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d5b2bca195b2bca1bda0b7fbb6bab8" rel="noreferrer noopener nofollow">[email protected]</a>:CanopyTax/single-spa-examples.git
cd single-spa-examples
cd src
ember new ember-app
cd ember-app
npm install

2)为ember添加骨架单spa钩子(Hook)方法(不完整,但现在应该没问题)

//src/ember-app/public/assets/apa.app.js
export async function bootstrap() {
  return new Promise((resolve, reject) => {
    resolve();
  });
}

export async function mount() {
  return new Promise((resolve, reject) => {
    resolve();
  });
}

export async function unmount() {
  return new Promise((resolve, reject) => {
    resolve();
  });
}

function cleanupInspector() {
  return new Promise((resolve, reject) => {
    resolve();
  });
}

2a) 为 ember 应用添加占位符 div。

#in single-spa-example-master/index.html add
<div id="ember-app"></div>

2b) 在 ember 环境中添加 rootElement 属性

#in src/ember-app/config/environment.js
APP: {
      // Here you can pass flags/options to your application instance
      // when it is created
      rootElement: '#ember-app'
    }

3) 添加单个 spa 的构建脚本(add bin/build-emberjs)

#!/usr/bin/env bash
set -e

cd src/ember-app
npm install
ember build
cd ..
cd ..
rm -rf build/ember-app
cp -a src/ember-app/dist build/ember-app

./node_modules/jspm/jspm.js build \
    src/ember-app/public/assets/spa.app.js \
    - common/colored-border.js \
    build/ember.app.js \
    --format amd \
    --source-map-contents \
    --skip-rollup \
    "$@"

4) 将构建添加为构建代码的一部分

#!/usr/bin/env bash
set -e

rm -rf build
mkdir build

cp jspm_packages/system.src.js build/system.src.js
cp jspm_packages/system-polyfills.src.js build/system-polyfills.src.js

./bin/build-root
./bin/build-common-deps

./bin/build-home
./bin/build-navbar
./bin/build-angular1
./bin/build-react -p
./bin/build-angular2
./bin/build-vue
./bin/build-svelte
./bin/build-preact
./bin/build-vanillajs
./bin/build-inferno
./bin/build-emberjs

5) 将 ember 应用程序声明为子应用程序并运行该应用程序

//src/single-spa-examples.js
singleSpa.declareChildApplication('ember', ()=> {
    /**ISSUE: ember-app.js does not get loaded*/
    return SystemJS.import('/build/ember-app/assets/vendor.js').then(function() {
        return SystemJS.import('/build/ember-app/assets/ember-app.js');
    });

    /*
    return Promise.all([
        SystemJS.import('/build/ember-app/assets/vendor.js'),
        SystemJS.import('/build/ember-app/assets/ember-app.js')
    ])*/
}, hashPrefix('/ember'));

6)启动应用程序

npm install
npm start

7) 转到 ember 应用程序 http://localhost:8080/#/ember

问题:

1)vendor.js 文件加载,但 ember-app.js 文件未加载(可以在 chrome 网络选项卡中验证)

child-app-errors.js:12 Uncaught Error: 'ember' died in status LOADING_SOURCE_CODE: (SystemJS) Cannot read property 'Ember' of undefined
    TypeError: Cannot read property 'Ember' of undefined
        at eval (http://localhost:8080/build/ember-app/assets/vendor.js!transpiled:10200:38)
        at eval (http://localhost:8080/build/ember-app/assets/vendor.js!transpiled:10301:11)
        at execute (http://localhost:8080/build/ember-app/assets/vendor.js!transpiled:64708:9)
    Error loading http://localhost:8080/build/ember-app/assets/vendor.js
        at eval (http://localhost:8080/build/ember-app/assets/vendor.js!transpiled:10200:38)
        at eval (http://localhost:8080/build/ember-app/assets/vendor.js!transpiled:10301:11)
        at execute (http://localhost:8080/build/ember-app/assets/vendor.js!transpiled:64708:9)
    Error loading http://localhost:8080/build/ember-app/assets/vendor.js 

2)在第5步中,如果我用注释版本替换代码,则会出现以下错误(相信这是因为文件应该按特定顺序加载,因为“runningTests”是在vendor.js文件中定义的):

child-app-errors.js:12 Uncaught Error: 'ember' died in status LOADING_SOURCE_CODE: (SystemJS) runningTests is not defined
    ReferenceError: runningTests is not defined
        at eval (http://localhost:8080/build/ember-app/assets/ember-app.js:294:1)
        at eval (http://localhost:8080/build/ember-app/assets/ember-app.js:299:3)
        at eval (<anonymous>)
        at tryCatchReject (http://localhost:8080/build/system-polyfills.src.js:1188:30)
        at runContinuation1 (http://localhost:8080/build/system-polyfills.src.js:1147:4)
        at Fulfilled.when (http://localhost:8080/build/system-polyfills.src.js:935:4)
    Evaluating http://localhost:8080/build/ember-app/assets/ember-app.js
    Error loading http://localhost:8080/build/ember-app/assets/ember-app.js
        at eval (http://localhost:8080/build/ember-app/assets/ember-app.js:294:1)
        at eval (http://localhost:8080/build/ember-app/assets/ember-app.js:299:3)
        at eval (<anonymous>)
        at tryCatchReject (http://localhost:8080/build/system-polyfills.src.js:1188:30)
        at runContinuation1 (http://localhost:8080/build/system-polyfills.src.js:1147:4)
        at Fulfilled.when (http://localhost:8080/build/system-polyfills.src.js:935:4)
    Evaluating http://localhost:8080/build/ember-app/assets/ember-app.js
    Error loading http://localhost:8080/build/ember-app/assets/ember-app.js

最佳答案

感谢您清晰的描述和重现步骤!我能够执行所有步骤并得到与您报告的完全相同的错误。

您所看到的tldr是SystemJS不知道如何正确执行ember-app.js和vendor.js包。

更长的解释:当 SystemJS 下载这些包的代码时,它会在代码上运行正则表达式以查看其格式。vendor.js 文件结合了 amd、cjs 和 esm 模块语法,但 SystemJS 决定将包解释为 esm (es6) 模块语法。然后,它将代码转换为 System.register 格式,并强制代码在 javascript 严格模式下执行,并带有 "use strict" 。陈述。一旦进入严格模式,代码就会在不同的上下文( this )下运行,这就是 this.Ember 的原因。导致错误Cannot read property 'Ember' of undefined 。如果您想了解更多详细信息或者它没有意义,请告诉我。我花了一段时间才找到答案,但我相信我现在明白了,如果您愿意,我可以为您提供更多详细信息。

话虽如此,所有这些都深深 Root 于 SystemJS 的内部,并且与 single-spa 的工作方式相去甚远。

如果您只想看看在单 Spa 应用程序中运行 Ember 是什么样子,我会查看 https://github.com/CanopyTax/single-spa-examples/pull/37#pullrequestreview-53690825我在哪里解决了这个问题。另请参阅https://github.com/CanopyTax/single-spa-examples/issues/33#issuecomment-319359153以及相关讨论。

关于ember.js - 在单 Spa 中将 ember 应用程序作为子应用程序加载时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45438094/

相关文章:

javascript - 登录后的 Ember Simple Auth 转换

ember.js 上下文感知 Handlebars 助手

javascript - 自动对象到数组的转换

javascript - 在 ember.js 中从 Controller 加载数据

javascript - Node js : how to export a previously exported function to make it visible

ember.js - 如何直接调用Ember数据函数?

javascript - 将 redux-devtools 与 jspm/system.js/babel 结合使用

angular - 如何使用 Mocha 测试 Angular 2?

javascript - 何时在 TypeScript 中使用脚本标签包含 JS 库?

javascript - 系统 JS 不加载模块