ng.*_*bie 51 javascript systemjs angular
我是Angular和Angular2的初学者.我对工作流程的结构感到困惑.我一直在查看Angular2站点中的示例项目.
如果我错了,请纠正我,但我所知道的是所有的打字稿都是由打字稿编译器转换成javascript的.然后编译的javascript实际上是在浏览器中运行的.
现在,如果我使用ES6导入语句将javascript文件导入typescript,如下所示:
import { NgModule } from '@angular/core';
Run Code Online (Sandbox Code Playgroud)
为什么我再次需要使用SystemJS来加载它们:
map: {
// our app is within the app folder
app: 'app',
// angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
Run Code Online (Sandbox Code Playgroud)
我的意思是,这不是反效果吗?查看ts文件的已转换的javascript,它显示所有import语句都转换为require()语句. 首先,require()在ES5 js文件中是如何工作的,如果是这样的话,那么SystemJS是怎么做的.
这让我很困惑.任何帮助将不胜感激.
Max*_*kyi 105
当tsc编译打字稿成JavaScript,你结束了在本地系统上一堆js文件.他们不知何故需要加载到浏览器中.由于浏览器尚不支持本机ES6模块加载,因此您有两个选项,要么index.html以正确的依赖顺序将它们全部放入您的文件中,要么您可以使用加载程序为您完成所有操作.您为所有模块指定了根,然后所有文件由该加载器以正确的依赖顺序加载和执行.有许多加载器:requirejs,webpack,systemjs等.在你的特殊情况下,它是systemjs.
查看ts文件的已转换的javascript,它显示所有import语句都转换为require()语句.
是的,这是一种SystemJs加载包的方法.它使用require()和exports语法,因为这是CommonJS加载包的语法,您在以下内容中指定了此类型tsconfig.json:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
Run Code Online (Sandbox Code Playgroud)
如果你要放module:'es6',你会发现在你编译的javascript文件中保存了导入和导出语句.但是,如前所述,您仍然无法使用此语法,因为浏览器本身不支持它.如果你要放module:'amd',你会看到使用不同的语法define().我想systemjs加载器在angular2初学者教程中是首选,因为它实际上可以加载所有支持的模块类型tsc.但是,如果要将模块作为es6模块加载,则必须将模块加载到模块module: 'system'中tsconfig.json.它是一个模块系统,旨在遵循es6 modules标准并使用,直到es6 modules在浏览器中得到完全支持.
设置如何工作
在您的index.html添加中添加以下脚本:
<script>
System.import('app').catch(function (err) {
console.error(err);
});
</script>
Run Code Online (Sandbox Code Playgroud)
在index.html加载时执行.该import('app')方法指示systemjs加载app模块,该模块映射到app项目目录结构中的文件夹,如下所示systemjs.config.js:
map: {
// our app is within the app folder
app: 'app',
Run Code Online (Sandbox Code Playgroud)
SystemJs main.js在该文件夹中查找文件.当app/main.js找到并加载到浏览器中时,在其代码require中找到调用:
var app_module_1 = require('./app.module');
Run Code Online (Sandbox Code Playgroud)
然后systemjs app.module.js从本地系统获取文件.这又有其自身的依赖性,如:
var core_1 = require('@angular/core');
Run Code Online (Sandbox Code Playgroud)
循环重复 - 加载,搜索依赖关系,加载它们并执行.这是所有dependecies在浏览器中解析,加载和执行的方式systemjs.
为什么需要映射到核心@angular库
在systemjs.config.ts文件中有映射到核心@angular模块:
map: {
...
// angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
Run Code Online (Sandbox Code Playgroud)
这里要理解的第一件事是这些是映射,而不是依赖.这意味着如果您的文件@angular/core都没有导入,则不会将其加载到浏览器.但是,您可能会看到此特定模块是在app/app.module.ts以下位置导入的:
import { NgModule } from '@angular/core';
Run Code Online (Sandbox Code Playgroud)
现在,为什么映射在那里.假设systemjs将您加载app/app.module.js到浏览器中.它解析其内容并找到以下内容:
var core_1 = require('@angular/core');
Run Code Online (Sandbox Code Playgroud)
现在systemjs明白它需要解决和加载@angular/core.它首先mappings按照文档中的规定进行检查:
map选项与path类似,但在规范化过程中很早就起作用了.它允许您将模块别名映射到位置或包.
我称之为命名模块的解决方案.因此,它找到了映射和替换@angular/core,node_modules/@angular/core这就是放置真实文件的位置.
我想systemjs尝试模仿中使用的方法node.js,你可以不指定相对路径识别模块['/', '../', or './'],只需像这样require('bar.js')和node.js:
然后Node.js从当前模块的父目录开始,并添加/ node_modules,并尝试从该位置加载模块.
如果您愿意,可以避免使用命名映射并使用相对路径导入,如下所示:
import {NgModule} from '../node_modules/@angular/core';
Run Code Online (Sandbox Code Playgroud)
但是,这应该@angular.core在项目和lib文件的所有引用中完成,包括@angular,至少可以说这不是一个好的解决方案.
| 归档时间: |
|
| 查看次数: |
19666 次 |
| 最近记录: |