为什么我的 angular 2 应用程序不会 bootstrap?
Why won't my angular 2 application bootstrap?
我正在尝试使用 express、angular 2、typescript、gulp 和 systemjs 为 bootstrap angular 2 个应用程序构建样板模板。出于某种原因,我的 index.html 文件无法识别我的 bootstrap.js
文件。我所有的 jade
和 typescript
都位于 src
。我正在使用 gulp 将打字稿从 src
转换为 dist
,并在 express 中提供来自 node_modules
和 jspm_packages
的静态资产。但是当终于到了调用 System.import
的时候,就像这样:
System.import('app').catch(console.error.bind(console))
,
我得到:
Error: SyntaxError: Unexpected token <
Evaluating http://localhost:3000/app/bootstrap.js
Error loading http://localhost:3000/app/bootstrap.js
错误似乎是在 angular2-polyfills.min.js
中引起的。
这是我的基本 express 后端,可让您了解我的资产和文件是如何提供的(我怀疑我有一个临时的脑残并且我的路径已关闭):
const app = express();
app.use('/jspm_packages', express.static('jspm_packages'));
app.use('/node_modules', express.static('node_modules'));
app.get('*', function(req, res) {
const file = fs.readFileSync('src/index.jade').toString();
const html = jade.render(file);
return res.send(html);
});
app.listen(process.env.PORT || 3000);
我的 index.html
文件位于 dist
中,该目录包含所有转译文件 javascript。这是我的 System.config:
上的 packages
属性
packages: {
"dist": {
"main": "bootstrap",
"format": "system",
"defaultExtension": "js"
}
},
我的印象是 dist
标识了相对于 BASE_URL
的文件夹(在我的例子中就是 /
),而 main
属性 标识文件名。所以我认为通过调用 System.import('app')
,它会在 dist
内的 app
文件夹中查找 bootstrap.js
文件到 bootstrap 我的 angular 2 应用程序,但情况似乎并非如此。当我打开 chrome 控制台时,bootstrap.js
没有出现在我的源代码中,所以我猜某处存在路径错误,但我已经尝试了所有变体,但似乎无法理解上班。
非常感谢任何帮助,谢谢。
更新:
这是我的index.html
:https://jsfiddle.net/r02r3jk3/
这是提供内容的文件夹结构和服务器端代码:https://jsfiddle.net/cejk0jw3/
当我检查网络选项卡以获取对 angular2/platform
中 browser.js
文件请求的响应时,我得到以下信息:
请求URL是http://localhost:3000/jspm_packages/npm/angular2@2.0.0-beta.9/platform/browser.js
响应的内容类型为 Content-Type:text/html; charset=utf-8
,但响应是我的 index.html 文件 :(
而不是 System.import('app')
中的 app
它应该是 dist
这样的: System.import('dist')
并且您的包定义应该是:
packages: {
"dist": {
"main": "app/bootstrap",
"format": "system",
"defaultExtension": "js"
}
}
更新
因为您的 index.html
位于 app
与 dist
相同的文件夹中。那么你的包定义中不需要 dist
。
您的定义应该是:
packages: {
"app": {
"main": "bootstrap",
"format": "system",
"defaultExtension": "js"
}
}
并像这样导入:
System.import('app')
更新
我试图复制您的设置,以下是我发现的问题:
在您的后端代码中:
您没有提供 dist
中的文件。该行已被注释掉。这样,由于您的 app.get('*', ...)
,对 app/*
的任何请求都将转发给 index.html
您可以取消对原始行的注释:
app.use('/dist', express.static('dist'));
或
app.use('/app',express.static('dist/app'))
取决于你做的是哪一个,packages
对象会有所不同。
我会选择后者,app.use('/app',express.static('dist/app'))
。从请求中隐藏 dist
对我来说更有意义。
此外,检查 SystemJS module formats
包定义为:
packages: {
"app": {
"main": "bootstrap",
//"format": "system", // this was causing the main issue
format:"register",
"defaultExtension": "js"
}
},
最后:
System.import('app')
更新
最后一个问题是关于行 "angular2": "npm:angular2@2.0.0-beta.9"
:
由server/index.js
中的以下两行引起:
app.use(express.static('jspm_packages'));
app.use(express.static('node_modules'));
问题是 jspm_packages
和 node_modules
中的所有内容将直接从服务器提供。因此,如果您尝试访问:http://localhost:3000/angular2
,它将从 node_modules
.
提供服务
如果您尝试访问:http://localhost:3000/npm/angular2@2.0.0-beta.9
,它将从 jspm_packages
提供服务。所以,当你有这些行时:
paths: {
...
"npm:*": "jspm_packages/npm/*"
},
map:{
`"angular2": "npm:angular2@2.0.0-beta.9"`
}
对 angular2
的每个请求都将转换为:jspm_packages/npm/angular2@2.0.0-beta.9
。但它应该只是 /npm/angular2@2.0.0-beta.9
.
当您删除 "angular2": "npm:angular2@2.0.0-beta.9"
时它起作用了,因为 angular2
现在将从 node_modules
.
内部提供
所以解决方案是将您的 server/index.js
更改为:
app.use('jspm_packages',express.static('jspm_packages'));
app.use('node_modules',express.static('node_modules'));
此外,index.html
中的脚本标签现在应该是:
<script src="jspm_packages/npm/angular2@2.0.0-beta.9/bundles/angular2-polyfills.min.js"></script>
<script src="jspm_packages/system.js"></script>
事实上,这取决于在构建应用程序时如何转换 TypeScript 文件:
- 如果您为每个 TypeScript 获取一个 JS 文件,则会在相应文件中创建一个匿名模块 ("System.register([ 'import1' ], ...")。在这种情况下,模块由其名称和路径标识。
- 如果您只为所有 TypeScript 文件获取一个 JS 文件(使用 outFile 选项),则在使用 System.register 函数时明确定义模块名称 (("System.register('module name', [ 'import1' ], ...").
你的情况好像属于第一种情况,你可以试试这个:
System.import('path/to/boot');
请注意,如果您的 index.html 文件位于 dist 文件夹下,您需要在该级别为您的 JS 编译文件创建一个子文件夹。此子文件夹需要在 "packages" 条目中配置到您的 SystemJS 中。
有关详细信息,请参阅此问题:
- How do I actually deploy an Angular 2 + Typescript + systemjs app?
我正在尝试使用 express、angular 2、typescript、gulp 和 systemjs 为 bootstrap angular 2 个应用程序构建样板模板。出于某种原因,我的 index.html 文件无法识别我的 bootstrap.js
文件。我所有的 jade
和 typescript
都位于 src
。我正在使用 gulp 将打字稿从 src
转换为 dist
,并在 express 中提供来自 node_modules
和 jspm_packages
的静态资产。但是当终于到了调用 System.import
的时候,就像这样:
System.import('app').catch(console.error.bind(console))
,
我得到:
Error: SyntaxError: Unexpected token <
Evaluating http://localhost:3000/app/bootstrap.js
Error loading http://localhost:3000/app/bootstrap.js
错误似乎是在 angular2-polyfills.min.js
中引起的。
这是我的基本 express 后端,可让您了解我的资产和文件是如何提供的(我怀疑我有一个临时的脑残并且我的路径已关闭):
const app = express();
app.use('/jspm_packages', express.static('jspm_packages'));
app.use('/node_modules', express.static('node_modules'));
app.get('*', function(req, res) {
const file = fs.readFileSync('src/index.jade').toString();
const html = jade.render(file);
return res.send(html);
});
app.listen(process.env.PORT || 3000);
我的 index.html
文件位于 dist
中,该目录包含所有转译文件 javascript。这是我的 System.config:
packages
属性
packages: {
"dist": {
"main": "bootstrap",
"format": "system",
"defaultExtension": "js"
}
},
我的印象是 dist
标识了相对于 BASE_URL
的文件夹(在我的例子中就是 /
),而 main
属性 标识文件名。所以我认为通过调用 System.import('app')
,它会在 dist
内的 app
文件夹中查找 bootstrap.js
文件到 bootstrap 我的 angular 2 应用程序,但情况似乎并非如此。当我打开 chrome 控制台时,bootstrap.js
没有出现在我的源代码中,所以我猜某处存在路径错误,但我已经尝试了所有变体,但似乎无法理解上班。
非常感谢任何帮助,谢谢。
更新:
这是我的index.html
:https://jsfiddle.net/r02r3jk3/
这是提供内容的文件夹结构和服务器端代码:https://jsfiddle.net/cejk0jw3/
当我检查网络选项卡以获取对 angular2/platform
中 browser.js
文件请求的响应时,我得到以下信息:
请求URL是http://localhost:3000/jspm_packages/npm/angular2@2.0.0-beta.9/platform/browser.js
响应的内容类型为 Content-Type:text/html; charset=utf-8
,但响应是我的 index.html 文件 :(
而不是 System.import('app')
中的 app
它应该是 dist
这样的: System.import('dist')
并且您的包定义应该是:
packages: {
"dist": {
"main": "app/bootstrap",
"format": "system",
"defaultExtension": "js"
}
}
更新
因为您的 index.html
位于 app
与 dist
相同的文件夹中。那么你的包定义中不需要 dist
。
您的定义应该是:
packages: {
"app": {
"main": "bootstrap",
"format": "system",
"defaultExtension": "js"
}
}
并像这样导入:
System.import('app')
更新
我试图复制您的设置,以下是我发现的问题:
在您的后端代码中:
您没有提供 dist
中的文件。该行已被注释掉。这样,由于您的 app.get('*', ...)
app/*
的任何请求都将转发给 index.html
您可以取消对原始行的注释:
app.use('/dist', express.static('dist'));
或
app.use('/app',express.static('dist/app'))
取决于你做的是哪一个,packages
对象会有所不同。
我会选择后者,app.use('/app',express.static('dist/app'))
。从请求中隐藏 dist
对我来说更有意义。
此外,检查 SystemJS module formats
包定义为:
packages: {
"app": {
"main": "bootstrap",
//"format": "system", // this was causing the main issue
format:"register",
"defaultExtension": "js"
}
},
最后:
System.import('app')
更新
最后一个问题是关于行 "angular2": "npm:angular2@2.0.0-beta.9"
:
由server/index.js
中的以下两行引起:
app.use(express.static('jspm_packages'));
app.use(express.static('node_modules'));
问题是 jspm_packages
和 node_modules
中的所有内容将直接从服务器提供。因此,如果您尝试访问:http://localhost:3000/angular2
,它将从 node_modules
.
提供服务
如果您尝试访问:http://localhost:3000/npm/angular2@2.0.0-beta.9
,它将从 jspm_packages
提供服务。所以,当你有这些行时:
paths: {
...
"npm:*": "jspm_packages/npm/*"
},
map:{
`"angular2": "npm:angular2@2.0.0-beta.9"`
}
对 angular2
的每个请求都将转换为:jspm_packages/npm/angular2@2.0.0-beta.9
。但它应该只是 /npm/angular2@2.0.0-beta.9
.
当您删除 "angular2": "npm:angular2@2.0.0-beta.9"
时它起作用了,因为 angular2
现在将从 node_modules
.
所以解决方案是将您的 server/index.js
更改为:
app.use('jspm_packages',express.static('jspm_packages'));
app.use('node_modules',express.static('node_modules'));
此外,index.html
中的脚本标签现在应该是:
<script src="jspm_packages/npm/angular2@2.0.0-beta.9/bundles/angular2-polyfills.min.js"></script>
<script src="jspm_packages/system.js"></script>
事实上,这取决于在构建应用程序时如何转换 TypeScript 文件:
- 如果您为每个 TypeScript 获取一个 JS 文件,则会在相应文件中创建一个匿名模块 ("System.register([ 'import1' ], ...")。在这种情况下,模块由其名称和路径标识。
- 如果您只为所有 TypeScript 文件获取一个 JS 文件(使用 outFile 选项),则在使用 System.register 函数时明确定义模块名称 (("System.register('module name', [ 'import1' ], ...").
你的情况好像属于第一种情况,你可以试试这个:
System.import('path/to/boot');
请注意,如果您的 index.html 文件位于 dist 文件夹下,您需要在该级别为您的 JS 编译文件创建一个子文件夹。此子文件夹需要在 "packages" 条目中配置到您的 SystemJS 中。
有关详细信息,请参阅此问题:
- How do I actually deploy an Angular 2 + Typescript + systemjs app?