在 single-spa 中加载 ember 应用程序作为子应用程序时出现问题
Issue in loading ember app as child application in single-spa
我正在尝试将 ember 用作具有单个 spa(https://github.com/CanopyTax/single-spa) 的子应用程序之一,但是我无法加载 js 文件 assets/vendor.js,assets/ember-app.js 正确使用 systemJS.
重现问题的步骤:
1) 使用 ember
设置单个 spa 示例
git clone git@github.com:CanopyTax/single-spa-examples.git
cd single-spa-examples
cd src
ember new ember-app
cd ember-app
npm install
2) 为 ember 添加框架单 spa 钩子方法(不完整,但现在应该没问题)
//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 环境中添加根元素 属性
#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 添加构建脚本(添加 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) 在 http://localhost:8080/#/ember
转到 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" 在 [=55 中定义=] 文件):
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 格式,并使用 "use strict"
语句强制代码在 javascript 严格模式下执行。一旦进入严格模式,代码将在不同的上下文 (this
) 下运行,这就是 this.Ember
导致错误 Cannot read property 'Ember' of undefined
的原因。让我知道您是否需要有关其中任何内容的更多详细信息,或者它是否没有意义。我花了一段时间才找到,但我相信我现在明白了,如果你愿意,我可以给你更详细的信息。
话虽如此,所有这些都深入到 SystemJS 的内部,并且与 single-spa 的工作原理完全不同。
如果您只想看看 运行 Ember 单水疗应用程序内部的样子,我会查看 https://github.com/CanopyTax/single-spa-examples/pull/37#pullrequestreview-53690825 for where I have worked around this issue. Also see https://github.com/CanopyTax/single-spa-examples/issues/33#issuecomment-319359153 和相关讨论。
我正在尝试将 ember 用作具有单个 spa(https://github.com/CanopyTax/single-spa) 的子应用程序之一,但是我无法加载 js 文件 assets/vendor.js,assets/ember-app.js 正确使用 systemJS.
重现问题的步骤:
1) 使用 ember
设置单个 spa 示例git clone git@github.com:CanopyTax/single-spa-examples.git
cd single-spa-examples
cd src
ember new ember-app
cd ember-app
npm install
2) 为 ember 添加框架单 spa 钩子方法(不完整,但现在应该没问题)
//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 环境中添加根元素 属性
#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 添加构建脚本(添加 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) 在 http://localhost:8080/#/ember
转到 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" 在 [=55 中定义=] 文件):
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 格式,并使用 "use strict"
语句强制代码在 javascript 严格模式下执行。一旦进入严格模式,代码将在不同的上下文 (this
) 下运行,这就是 this.Ember
导致错误 Cannot read property 'Ember' of undefined
的原因。让我知道您是否需要有关其中任何内容的更多详细信息,或者它是否没有意义。我花了一段时间才找到,但我相信我现在明白了,如果你愿意,我可以给你更详细的信息。
话虽如此,所有这些都深入到 SystemJS 的内部,并且与 single-spa 的工作原理完全不同。
如果您只想看看 运行 Ember 单水疗应用程序内部的样子,我会查看 https://github.com/CanopyTax/single-spa-examples/pull/37#pullrequestreview-53690825 for where I have worked around this issue. Also see https://github.com/CanopyTax/single-spa-examples/issues/33#issuecomment-319359153 和相关讨论。