学习 Angular 教程






4.90/5 (36投票s)
这是 Angular 教程的第一部分。在第一部分中,我们将介绍 Node、TypeScript、模块加载器、打包工具和 VS Code。
目录
- 引言
- 本系列文章如何教你 Angular?
- 为什么我们需要 Angular?
- 实验 1:练习 NodeJS
- 实验 2:练习 TypeScript
- 实验 3:练习 VS Code
- 实验 4:使用 SystemJs 理解模块加载器
- 实验 5:使用 WebPack 理解模块打包器
- 历史
其余文章的链接
- 在第一部分中,我们探讨了 Node、TypeScript、模块加载器/打包器和 VS Code。
- 在第二篇文章中,我们创建了一个简单的基本 Angular 应用程序,包含一个屏幕,并探讨了组件和模块等重要概念。
- 在第三篇文章中,我们研究了如何实现 SPA 和验证。
- 在第四篇文章中,我们理解了如何进行 HTTP 调用以及如何使用 Input 和 Output 创建自定义 Angular 组件。
- 在第五部分中,我们涵盖了两个实验——一个是如何在 Angular 中使用 Jquery,另一个是延迟路由。
- 在第六部分中,我们再次涵盖了两个实验——管道和使用提供者的依赖注入。
引言
为什么我们应该学习 Angular?下面的 Stack Overflow 图表说明了一切。它很受欢迎,很热门,有很多工作机会。本文通过 15 个出色的实验,逐步教你 Angular。所以如果你在这里学习 Angular,那么你来对地方了,也找到了正确的文章。
在这第一篇文章中,我们将涵盖五个实验。这五个实验将涵盖 Angular 的先决条件。本文涵盖了 Node、TypeScript、VSCode、模块加载器和模块打包器。
★ AngularJS 与 Angular。Angular 有两个版本——旧版名为 AngularJS,新版仅名为 Angular。因此,当有人说 AngularJS 时,指的是 Angular 1.X;当有人说“仅 Angular”时,指的是 Angular 2/4。
本系列文章如何教你 Angular?
学习 Angular 或任何新技术最好的方法是创建一个项目。因此,在这个循序渐进的系列中,我们将创建一个简单的客户数据录入屏幕项目。
该项目将具有以下功能
- 应用程序应能够接受三个字段——客户姓名、客户代码和客户金额值。
- 客户姓名和客户代码是必填字段,应进行验证。
- 应用程序将有一个“添加”按钮,帮助我们将当前客户数据发布到服务器。一旦数据添加到服务器,它应该显示在网格上。
- 应用程序将有一个导航结构,顶部有徽标和公司名称,左侧有导航链接,屏幕底部有版权信息。
以上是本文的路线图。它有三个阶段
理论阶段:在此阶段,我们将了解什么是 Angular 以及为什么我们需要它。
先决条件阶段:在此阶段,我们将看到四个重要事项——Node、Typescript、VSCode、模块加载器(SystemJS)和模块打包器(Webpack)。
主要学习阶段:这是 Angular 真正开始的地方。在此阶段,我们将有八个实验,在涵盖这些实验的同时,我们将创建之前讨论的客户数据录入屏幕项目。
所以不要再等了。一步一步地开始实验。
★ 我应该从 Angular 1、2 还是 4 开始。Angular 1.X 和 2.X 非常不同。所以即使你已经用过 Angular 1.X,你也要从 Angular 2.X 重新开始。Angular 2.X 和 Angular 4.X 向后兼容,所以如果你正在学习 Angular 2,你就在学习 Angular 4 及更高版本。所以对于 Angular 新手,直接从 Angular 4 开始。本文教授的是 Angular 4。
为什么我们需要 Angular?
“Angular 是一个开源 JavaScript 框架,它简化了 JavaScript 对象和 HTML UI 元素之间的绑定代码。”
让我们尝试用简单的示例代码来理解上述定义。
下面是一个简单的“Customer
”函数,带有“CustomerName
”属性。我们还创建了一个名为“Cust
”的对象,它是“Customer
”类类型。
function Customer()
{
this.CustomerName = "AngularInterview";
}
var Cust = new Customer();
现在假设在上面的 customer
对象中,我们想将其绑定到一个名为“TxtCustomerName
”的 HTML 文本框。换句话说,当我们在 HTML 文本框中更改某些内容时,customer
对象应该更新;当 customer
对象内部发生更改时,UI 也应该更新。
<input type=text id="TxtCustomerName" onchange="UitoObject()"/>
因此,为了实现 UI 到对象之间的这种通信,开发人员会编写如下所示的函数。“UitoObject
”函数从 UI 获取数据并将其设置到对象,而另一个函数“ObjecttoUI
”从对象获取数据并将其设置到 UI。
function UitoObject()
{
Cust.CustomerName = $("#TxtCustomerName").val();
}
function ObjecttoUi()
{
$("#TxtCustomerName").val(Cust.CustomerName);
}
所以如果我们通过视觉分析上面的代码,它看起来像下面所示。你的两个函数无非是绑定代码逻辑,它在 UI 和对象之间来回传输数据。
现在,同样的上述代码可以在 Angular 中写成如下所示。所以现在,你在文本框中输入的任何内容都会更新“Customer
”对象,当“Customer
”对象更新时,它也会更新 UI。
<input type=text [(ngModel)]="Customer.CustomerName"/>
简而言之,如果你现在从视觉上分析上面的代码,你最终会得到如下图所示的内容。你有 HTML 中的 VIEW
,你的 MODEL
对象是 JavaScript 函数,以及 Angular 中的绑定代码。
现在,绑定代码有不同的术语。
- 一些开发者称之为“
ViewModel
”,因为它连接了“Model
”和“View
”。 - 一些人称之为“
Presenter
”,因为这种逻辑无非是表现逻辑。 - 一些人将其称为“
Controller
”,因为它控制视图和模型如何通信。
为了避免这种术语混淆,Angular 团队将这段代码称为“Whatever
”。它是绑定 UI 和模型的“Whatever
”代码。这就是为什么你会听到很多开发者说 Angular 实现了“MVW”架构。
所以总结一下,Angular 的整个目标是绑定、绑定、绑定。
实验 1:练习 NodeJS
所以在学习 Angular 之前,你应该了解的第一个 JavaScript 开源框架是 NodeJS。在这个实验中,我添加的所有内容也在这个 YouTube 视频中进行了演示,所以请随意观看演示实验。
理论:什么是 NodeJS?
NodeJS 是一个开源 JavaScript 框架,它完成两件事
- 它帮助你在浏览器之外运行 JavaScript。NodeJS 使用 Chrome JavaScript 引擎在浏览器之外执行 JavaScript,这样我们就可以使用 JavaScript 创建桌面和基于服务器的应用程序。
- 它也充当一个中央存储库,我们可以通过 NPM(Node 包管理器)从中获取任何 JavaScript 框架。
★ 学习但不要过度学习。NodeJS 本身就是一个大话题。对于 Angular,我们只需要知道如何使用 NPM 命令。所以我们只会将自己限制在如何使用 NPM。我们不会进行全面的节点编程。记住 JavaScript 是广阔的。不要进行不必要的学习,因为你会失去焦点。
步骤 1:安装 NodeJs
要安装 NodeJS,请访问https://node.org.cn/并下载最新版本并安装。
![]() | 安装 Node 后,你会在程序文件中看到 NodeJs 命令提示符,如下图所示。 然后我们可以打开 NodeJS 命令提示符,并在其中执行 NPM 命令。 如果你完全不熟悉 NodeJS,请观看此 NodeJS 视频,它更详细地解释了 NodeJS。 |
步骤 2:练习 NPM Install 命令
所以我们来练习 NPM 的第一个命令“ 例如,如果你想安装 jquery,你将打开 node 命令提示符并输入“ | ![]() |
你是不是想知道 Jquery 安装在哪里了?它安装在你运行 NPM 命令的同一个文件夹中。 在该文件夹中,它创建了一个“node_modules”文件夹,并在其中创建了一个“jquery”文件夹,其中所有 Jquery 都已通过“ | ![]() |
步骤 3:理解 package.json 文件
当你处理大型项目时,你将需要大量的 JavaScript 框架。因此,在一个项目中,你可能需要 jquery、angular、lodash 等等。一遍又一遍地执行“npm install
”无疑是在浪费你宝贵的时间。
因此,为了一次性加载所有 JavaScript 框架引用,“npm
”团队提供了 package.json。在这个 package.json 文件中,你可以一次性将所有 JavaScript 引用添加到条目中,并一次性加载它们。
要创建 package.json 文件,请打开 node 命令提示符并键入“npm init
”。在“npm init
”命令之后,它会要求输入包名、版本号、项目描述等。填写完所有问题后,它将在当前文件夹中创建一个 package.json 文件。下面是“npm init
”命令的样子
一旦 npm init
命令成功执行,它会在当前文件夹中创建一个“package.json”文件。如果你打开“package.json”文件,它具有以下结构。
不要被所有信息压垮,只关注“dependencies
”节点。这个节点列出了所有 JavaScript 依赖项及其版本号。所以在我们的 package.json 文件中,我们列出了所有依赖项。
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "MyClass.js",
"dependencies": {
"angular": "^1.6.5",
"jquery": "^3.2.1",
"knockout": "^3.4.2",
"lodash": "~4.17.4"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
在创建“package.json”文件的任何地方,你只需输入“npm install ”命令,如下图所示。如果你还记得在 package.json 文件中,我们列出了三个 JavaScript 框架依赖项。它们将一个接一个地安装。你可以在图片中看到它显示“添加了 3 个包”。 | ![]() |
★ 学习但不要过度学习。Package.json 有很多配置。不要把你的精力花在现在理解所有这些上。随着我们进行后面的实验,我将逐步讲解重要的部分。所以请继续阅读章节。
理解 package.json 中的版本控制系统
大多数软件版本遵循语义化版本控制。在语义化版本控制中,版本分为三个数字,如下图所示。
第一个数字称为“主版本”,第二个“次版本”,第三个“修订版本”。 主版本:主版本中的任何增量都表明软件功能存在重大更改。旧代码很可能无法与这些更改一起使用,必须进行适当的测试。 次版本:此版本在添加新功能时递增,但旧代码仍然有效。 修订版:此版本在进行错误修复时递增。因此,没有添加新功能,没有破坏性更改,并且与旧代码向后兼容。 | ![]() |
NPM 遵循语义版本控制,但它还有一些特殊的字符,如“^”、“~”、“>”等。它们规定了 NPM 如何获取最新版本,以及主版本和次版本的行为。 对于这些格式,有三种主要格式。让我们分别理解它们。 精确版本 (1.6.5), 主要/次要版本 (^1.6.5) 或 次要版本 (~1.6.5)。 | ![]() |
精确版本 (1.6.5):这将获取精确版本 1.6.5 的最新版本,不多也不少。如果该版本不可用,它将抛出异常。 主要/次要版本 (^1.6.5):插入符号将获取最低 1.6.5 版本,如果有任何更高的次要/修订版本,它将获取该版本。它绝不会获取更高的主版本。因此,如果 1.6.5 有 1.6.7,它将获取该版本;如果它有 1.7.7,它将获取该版本;但如果它有 2.0,它将不会获取该版本。 最小或更低 (~1.6.5):波浪号将获取更高的修订版本。例如,如果 1.6.5 有 1.6.7,它将获取该版本,但如果它有 1.7.5,它将不会被安装;如果它有 2.0,它将不会被安装。 | ![]() |
什么是 package-lock.json 文件?
正如前面章节所讨论的,package.json 具有“^”和“~”版本控制机制。现在假设你的 package.json 中提到了 "jquery": "^3.1.0
",并且 Jquery 有一个新版本“3.2.1
”。因此,实际上它将安装或者换句话说“锁定”到“3.2.1
”。
所以在 package.json 中,你会有“^3.1.0
”,但实际上你会使用“3.2.1
”。实际版本的这个条目存在于“package-lock.json”中。所以 package lock 文件有你的代码中使用的精确版本。
下面是这两个文件的图片快照。
重要的 NPM 命令
NPM 有一个庞大的命令列表。但这里有一些非常重要的命令,你现在和将来都会用到。如前所述,学习但不要过度学习。
命令 | 解释 |
npm install -g typescript | -g 命令将全局安装包。换句话说,在你的计算机上,当你使用这个包时,它会使用全局安装。这应该只用于像 grunt、typescript、npm 等命令行包。 |
npm install --save jquery | 这将安装包,并在 package.json 文件中添加一个条目。有时,我们在项目中使用了一个包,却忘记更新 package.json,这时这个命令就非常方便了。 |
| 第一个命令会显示 GitHub 上的最新 Jquery 版本,第二个命令会按升序显示所有版本。 |
npm install -g npm | 这个命令会更新 npm 本身。“-g ”如前所述,有助于全局安装 npm 。 |
实验 2:练习 TypeScript
★Angular 是用 TypeScript 语言创建的。因此,如果你使用 Angular 进行开发,TypeScript 是前进的方向。
介绍:为什么我们需要 Typescript?
现在 JavaScript 是一种很棒但又奇怪的语言。在 JavaScript 中,如果你想实现继承,你需要使用原型,它不是一种强类型语言,没有多态等等。因此,当开发者来自 C# 和 Java 背景时,他们很难适应这种奇怪的语言。来自 C# 和 Java 背景的人大量使用 OOP 特性。
因此,为了弥补这个空白,答案是“TypeScript”。
“TypeScript 是一种在 JavaScript 之上的糖衣面向对象编程语言。”
![]() | 因此,在 TypeScript 中,我们可以使用“ 在内部,TypeScript 将编译(更准确的词应该是“转译”)成纯 JavaScript 代码,包括函数、闭包和 IIFE。 |
请务必观看这个 1 小时的TypeScript 培训视频,它将更详细地解释 TypeScript。
步骤 1:安装 TypeScript
所以要安装 TypeScript,我们需要使用“ “-g”命令表示你可以在任何文件夹中执行 TypeScript 命令。 | ![]() |
步骤 2:将一个简单的 TypeScript 编译成 JavaScript
我们来理解如何将 TypeScript 编译成 JavaScript。所以我们创建一个简单的“Customer.ts”文件,代码如下
class Customer{
}
现在打开 NodeJS 命令提示符并输入命令“ 如果你还记得,“ | ![]() |
下面是 TypeScript 命令行工具的 JavaScript 输出
var Customer = (function () {
function Customer() {
}
return Customer;
}());
许多人将 TypeScript 到 JavaScript 的转换称为“编译”。我个人觉得我们应该称这个过程为“转译”。
编译是将 C#、Java、C++ 等高级语言转换为机器语言或某些人类无法阅读的中间语言,而转译是将一种高级语言转换为另一种高级语言。
在这个过程中,TypeScript 和 JavaScript 都是高级语言。所以我们把这个过程称为转译,把 TypeScript 称为“转译器”而不是编译器。
步骤 3:使用 tsconfig.json 文件
TypeScript 的转译过程有很多高级设置。下面是编译时可以传递给 tsc 命令的一些选项
选项 | 描述 |
tsc Customer.ts –removecomments | 转译时,注释将被删除。 |
tsc Customer.ts --target ES5 | 这将使用 ES5 规范进行编译。 |
tsc Customer.ts --outdir "c:\users\shiv" | 这将在特定输出目录进行编译。 |
tsc foo.ts bar.ts –outFile “Single.js” | 这会将多个 TS 文件编译成单个 JS 文件。 |
tsc Customer.ts -w | 此命令将在后台持续运行 TypeScript,并不断查找更改的文件。如果文件已更改,它将编译该文件。 |
但现在让我们实际思考一下,如果我想以 ES5 规范转译到没有注释的特定目录,命令行将变成如下所示
tsc Customer.ts --outdir "c:\users\shiv" --target ES5 --removecomments
这就是 tsconfig.json 文件派上用场的地方。你可以将所有这些配置放入“tsconfig.json”文件中,然后只需执行“tsc
”。
{
"compilerOptions": {
"target": "es5",
"removeComments": false,
"outDir": "/Shiv"
}
}
★学习但不要过度学习。Tsconfig.json 有成千上万个属性。现在不要把你的精力花在理解所有这些上。继续进行实验。当出现任何新的 TypeScript 配置时,我们都会研究它。
实验 3:练习 VS Code
什么是 VS Code?
理论上,你可以用一个简单的记事本完成 Angular 的开发。但是那样,就等于回到了亚当和夏娃的时代,重新发明轮子。所以我们需要一些工具来帮助我们轻松编写 HTML、编译 TypeScript 等等。
这就是需要 VS Code 的原因。VS Code 是微软提供的一款免费编辑器,它将帮助我们完成 HTML、JavaScript、TypeScript 等所有自动化工作。
所以,请访问https://vscode.js.cn/download,并根据你的操作系统安装相应的版本。例如,我使用的是 Windows 操作系统,所以我将安装 Windows 版本。
下载安装程序后,它是一个简单的安装 EXE 文件。运行它,然后只需点击“下一步”、“下一步”和“完成”。
你也可以观看这个 VS Code 教程,它将帮助你理解。
第一点:所有操作都在一个文件夹中进行
在 VS Code 中,你将所有源代码放在一个文件夹中。因此,第一步是创建一个文件夹,然后通过点击“文件”➔“打开”并选择如下图所示的文件夹,将 VS Code 指向该文件夹
第二点:创建文件和文件夹
如果你想创建文件或子文件夹,可以点击图中所示的图标。 第一个图标创建文件,第二个图标创建文件夹。 | ![]() |
第三点:资源管理器和打开的编辑器
VS Code 的资源管理器部分有两个部分,一个显示打开的编辑器,另一个显示你的文件夹。你可以在图像中看到打开的编辑器。你可以点击那些交叉符号来关闭打开的文件。
第四点:在资源管理器中显示
如果你想浏览到当前文件夹,可以右键点击该文件夹并点击“在资源管理器中显示”。
第五点:集成终端
TypeScript、Node 这些框架大多通过命令行运行。因此,如果能在 VS Code 中集成命令行,那将非常棒。VS Code 有一个名为集成终端的功能,你可以通过点击“视图”➔“集成终端”来打开集成终端。
一旦进入集成终端,你就可以执行“npm install
”、“tsc
”等命令。下面是集成终端的样子
第六点:运行多个终端
我们总是需要做的一件事是运行多个命令,为此我们需要一个加载多个终端的工具。
在 VS Code 中,我们可以通过点击加号加载多个终端,如下图所示。这样,在一个终端中,你可以运行网络服务器,在另一个终端中,你可以运行代码审查工具。
第七点:更改为舒缓的颜色主题
默认情况下,VS Code 显示黑色主题,这对于你的眼睛健康非常好。但有时为了代码更清晰,你可能想换成一些更明亮的主题。你可以通过点击“文件”➔“首选项”➔“颜色主题”来完成,你将看到如下图所示的主题
第八点:VS Code 设置
VS Code 有很多设置,比如你可以隐藏不需要的文件,只关注你想要的文件,更改图标设置,更改字体大小等等。要应用设置,你需要转到“文件”➔“首选项”➔“设置”,你将看到如下图所示的界面。
其中有两部分,一部分是首选项示例代码片段,第二部分是你想在哪个级别应用这些代码片段。你可以在两个级别应用代码片段,一个是在项目工作区级别,另一个是在用户/计算机级别。
如果你在工作区级别应用,它只适用于该项目;如果你在用户级别应用,它将适用于该计算机中的所有项目。
例如,在用户设置中,我们粘贴了文件排除设置。在此设置中,我们指定了不希望在工作区中看到“.JS”和“.Map”文件。
{
"workbench.sideBar.location": "left",
"window.zoomLevel": 2,
"window.menuBarVisibility": "default",
"files.exclude": {
"**/*.js": true,
"**/*.js.map": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true
},
"workbench.colorTheme": "Visual Studio Light"
}
一旦应用该设置,你将看不到“JS”和“Map”文件。
实验 4:使用 SystemJs 理解模块加载器
你可以观看下面的视频,它将实际演示模块加载器和 SystemJS 的概念。
主题名称 | YouTube 视频源 |
System JS | https://www.youtube.com/watch?v=nQGhdoIMKaM |
Common JS 概念 | https://www.youtube.com/watch?v=jN4IM5tp1SE |
步骤 1:TypeScript 模块和 Import / Export 关键字
模块化开发是开发的重要支柱之一。一个好的软件总是包含自包含的模块。
因此,你希望创建单独的物理 TypeScript 或 JavaScript 文件,其中包含自包含的代码。然后,你希望有一种引用机制,通过这种机制可以在这些物理文件之间引用模块。
在 TypeScript 中,我们通过使用“import ”和“export ”关键字来实现这一点。因此,需要暴露的模块应该有“ | ![]() |
例如,假设我们有两个 TypeScript 文件“Customer.ts”和“Dal.ts”。假设“Customer.ts”正在使用“Dal.ts”。 因此,“Dal.ts”将使用 export 来暴露其模块,而“Customer.ts”将使用 import 来获取导出的模块。 | ![]() |
因此,在“Dal.ts”中,你想要导出的类应该标记为“exported”,如下图所示。如果你不将其标记为 exported,它就不能被导入。
export class Dal{
Add(){
alert("Dal add called");
}
}
现在在“Customer.ts”中,我们使用“import
”从“Dal.ts”调用导出的类。
import {Dal} from "./Dal "
export class Customer{
Add(){
var dal = new Dal();
dal.Add();
}
}
简而言之,你使用 export 和 import 在 Typescript 中进行模块化开发。但是现在,这些如何“转译”成 JavaScript 代码,我们将在下一节中看到。归根结底,所有这些模块都被转译成 JavaScript,所以让我们了解其内部工作原理。
步骤 2:JavaScript 中的模块格式 CommonJS, AMD, ES6
让我们首先定义“模块”格式这个词。我们在上一节中讨论了模块。模块格式定义了模块如何导出和导入的 JavaScript 语法。
在 JavaScript 世界中,有两种定义模块格式的方式——非官方方式和官方方式。在 ES6 之前,没有官方方式,所以一些非官方流行的定义模块格式的方式是 CommonJs、AMD、UMD 等。官方方式只有一种 ES6。
例如,下面是 commonJS 的格式。在 commonJS 中,导出的模块在“exports
”变量中定义,要导入,我们需要使用“require
”关键字。
你可以在下面看到 JS 输出,其中 dal 使用“exports
”变量导出。
Object.defineProperty(exports, "__esModule", { value: true });
var Dal = (function () {
function Dal() {
}
Dal.prototype.Add = function () {
alert("Dal add called");
};
return Dal;
}());
exports.Dal = Dal;
以下是“Customer.js”的代码,它使用“require
”来加载“Dal.js”。
Object.defineProperty(exports, "__esModule", { value: true });
var Dal_js_1 = require("./Dal.js");
var Customer = (function () {
function Customer() {
}
Customer.prototype.Add = function () {
var dal = new Dal_js_1.Dal();
dal.Add();
};
return Customer;
}());
exports.Customer = Customer;
所以现在,这是一种 commonJS 格式,同样我们也有其他格式。例如,下面是“amd
”模块格式。
在此,我们将在“export
”变量中导出类,并使用“define
”进行导入。下面是“define
”的代码。我们没有粘贴“export
”的代码,因为它与 commonJS 相同。
define(["require", "exports", "./Dal.js",
"./Validation.js"], function (require, exports, Dal_js_1, Validation_js_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Customer = (function () {
function Customer() {
}
Customer.prototype.Add = function () {
var val = new Validation_js_1.Validation();
var dal = new Dal_js_1.Dal();
dal.Add();
};
return Customer;
}());
exports.Customer = Customer;
});
在“ES6”模块格式中,要暴露类,我们需要使用“export
”关键字;要使用它,我们需要使用“import
”关键字。
import { Dal } from "./Dal.js";
import { Validation } from "./Validation.js";
var Customer = (function () {
function Customer() {
}
Customer.prototype.Add = function () {
var val = new Validation();
var dal = new Dal();
dal.Add();
};
return Customer;
}());
export { Customer };
var Dal = (function () {
function Dal() {
}
Dal.prototype.Add = function () {
alert("Dal add called");
};
return Dal;
}());
export { Dal };
简而言之,“amd
”、“commonJS
”和“ES6
”定义了模块之间如何通信。总结一下,ES6 使用“import
/ export
”,amd 使用“define
/export
”,commonJs 使用“require
/export
”。
所有这些模块格式都可以通过简单地更改 TypeScript 配置文件中的选项来生成。 所以在“tsconfig.json”中,我们可以在“ | ![]() |
步骤 3:在 HTML UI 中调用 JavaScript 模块加载器
现在,当我们尝试加载使用 AMD、CommonJS 或 ES6 等模块格式的 JavaScript 函数时,这并不那么容易。例如,在下面 HTML UI 代码中,我们加载了“Dal.js”和“Customer.js”。这个例子已经在前面的实验中演示过,并且启用了“CommonJS
”。
此外,我们正确设置了顺序,首先添加了“Dal.js”的引用,然后是“Customer.js”,因为“Customer.js”依赖于“Dal.js”。
但是当我们尝试创建“Customer
”对象并尝试调用“Add
”时,它不起作用。
<script src="Dal.js"></script>
<script src="Customer.js"></script>
<script>
var cust = new Customer();
cust.Add();
</script>
我们最终会遇到以下错误,指出“exports
”不被理解。这很合理,因为浏览器不识别“exports
”和“require
”等关键字,因为它们不是标准 JavaScript。
第二个问题是,即使这段代码有效,对于大量的引用,我仍然会有排序问题。假设我们有 15 个模块使用模块格式相互引用。我们将花费一半的时间在 HTML 文件中安排这些顺序。如果我们可以直接指向“Customer.js”,然后自动使用“exports
”和“imports
”识别引用并加载“Address.js”,那将非常棒。
这就是我们需要 JavaScript 模块加载器的地方。模块加载器的一些例子是 SystemJS、WebPack 等等。
所以如果我们使用模块加载器,我们只需要指向第一个 JS 文件,然后自动使用“ | ![]() |
让我们使用“SystemJS
”演示一个模块。所以首先进入 Node 命令提示符并安装“systemjs
”。
npm install systemjs
因此,在 HTML UI 中,我们需要告诉“system.js”哪个是第一个要加载的 JS 文件。你可以在下面的代码中看到,我们正在说“SystemJS.import
”加载“Customer.js”作为第一个文件。
<script src="system.js"></script>
<script>
SystemJS.import('./Customer.js')
.then(function(module){
var cust = new module.Customer();
cust.Add();
}).catch(function (err)
{ console.error(err); });;
</script>
一旦文件在 then
函数中加载,我们就会得到模块。然后我们可以引用模块变量并创建“Customer
”函数的对象。
如果你查看 Chrome 浏览器的网络选项卡,你可以看到首先“system.js”加载“Customer.js”,然后也加载其引用“Dal.js”。
实验 5:使用 WebPack 理解模块打包器
介绍:运行时 vs 编译时 – Webpack 模块打包器
在之前的实验 4 中,systemJS
在运行时处理所有事情。因此,在浏览器中,它首先加载“Customer.js”,然后加载“Address.js”,依此类推。如果你有很多依赖项,你最终会发出很多请求。
旁边是一张来自企业项目的简单图片,我们有 342 个 JavaScript 文件请求来加载网站。 这可是一个大数字,这么多的请求会大大降低你的应用程序性能。 | ![]() |
如果我们能在编译时就创建一个单一的包,那将大大提高性能。
这就是 webpack (https://webpack.js.cn/) 的用武之地。Webpack 是一个模块打包器。 它获取第一个 JS 文件,使用 CommonJS / AMD / UMD 等模块定义,然后找出引用并在编译时生成一个单一的 JS 文件。你可以将这个单一的打包 JS 文件放入你的网页中。 | ![]() |
那么,让我们试着理解 Webpack 的基本工作原理。
步骤 1:安装 WebPack
所以第一步是安装 webpack。打开 node 命令提示符并输入下面的 NPM
命令。请注意我们使用了全局标志“-g
”。
npm install -g webpack
步骤 2:生成单个打包文件
我们使用与“实验 4”中相同的代码。在实验 4 中,如果你看,“Customer.js”调用了“Address.js”。所以第一个 JavaScript 文件是“Customer.js”。我们只需要在 webpack 命令中给出第一个 JS 文件名和最终的打包文件名。你还可以看到有一个“—output-library”标志参数。Webpack 将向我们暴露“CustomerLibrary
”组件,我们可以从中在 UI 中访问“Customer
”类。
webpack "Customer.js" "Bundle.js" --output-library='CustomerLibrary'
步骤 3:在网页中调用 JavaScript 类
现在我们已经有了一个单独的 bundle,我们只需在网页中加载 JS 文件,并通过“CustomerLibrary
”访问类。请记住,这个“CustomerLibrary
”来自命令行,请再次查看步骤 2 获取详细信息。
<script src="Bundle.js"></script>
<script>
var x = new CustomerLibrary.Customer();
x.Add();
</script>
如果你现在查看网络选项卡,你会看到现在只有一个文件“Bundle.js”,而不是多个文件。
★SystemJS 和 WebPack。当我们学习 Angular 时,我们首先会使用 SystemJS,然后在其中一个实验中,我们将看到 Webpack 如何帮助我们。
现在我们已经完成了所有先决条件,是时候开始深入研究 Angular 了。所以从实验 6 开始,真正的 Angular 就开始了。
下一篇文章有什么内容?
现在我们已经完成了所有先决条件,是时候开始深入研究 Angular 了。所以从实验 6 开始,真正的 Angular 就开始了。要阅读“学习 Angular”教程的下一个实验,请从这里开始。
如需进一步阅读,请观看下面的面试准备视频和逐步视频系列。
- Angular 面试问答
- ASP.NET MVC 面试题及答案
- C# 面试问答
- 分步学习 Azure
- SQL Server 分步教程
- RxJS 面试问答
- 1 小时学习 Angular(Angular 9)
- 8 小时分步学习 Angular
历史
- 2017年9月21日:初始版本