├── .DS_Store ├── .gitignore ├── Basic ├── 01_know_node.md ├── 02_start_node.md ├── 03_node_modules.md ├── README.md └── _image │ ├── 2019-03-04-22-50-13.jpg │ ├── 2019-03-12-21-45-06.png │ ├── 2019-03-12-21-46-23.png │ ├── 2019-03-14-22-55-53.png │ ├── 2019-03-15-21-19-40.png │ ├── 2019-03-15-21-25-58.png │ ├── 2019-03-15-21-34-50.png │ ├── 2019-03-20-21-18-39.png │ ├── 2019-03-20-22-37-43.png │ └── 2019-03-20-23-16-29.png ├── Practice └── README.md ├── README.md ├── SUMMARY.md ├── Web └── README.md └── _image ├── qrcode-self.jpeg └── weixin-qrcode.png /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengloo53/node-fullstack-course/9da61ac77245e05035c65b46505f91211590caf9/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | .markeditor 64 | .Archive 65 | 66 | drafts 67 | configs 68 | 69 | #gitbook 70 | .gitbook -------------------------------------------------------------------------------- /Basic/01_know_node.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 走进 Node 的世界 3 | --- 4 | 5 | 这一课的内容,带你走进 Node 的世界,相对而言,它是一门比较年轻的技术,而非编程语言。与 Java 和 PHP 的概念不一样,Node 使用的的编程语言是 JavaScript ,这么一说,更让人糊涂了,那 Node 到底是什么样的一个存在?且听我慢慢道来。 6 | 7 | ## Node 的定义 8 | 9 | 看一下维基百科上的定义。 10 | 11 | > Node.js 是一个能够在服务器端运行 JavaScript 的开放源代码、跨平台 JavaScript 运行环境。Node.js 由 Node.js 基金会持有和维护,并与 Linux 基金会有合作关系。Node.js 采用 Google 开发的 V8 运行代码,使用事件驱动、非阻塞和 异步输入输出模型等技术来提高性能,可优化应用程序的传输量和规模。 12 | 13 | 根据上述的定义,我们提出如下概念: 14 | 15 | * Node 是 JavaScript 的服务器运行环境(runtime) 16 | * Node 采用 Google 开发的 V8 引擎运行代码 17 | * Node 采用事件驱动,非阻塞和异步 I/O 模型 18 | 19 | 一句话总结一下,Node 是采用**事件驱动**,**非阻塞异步 I/O** 模型,运行在 V8 引擎下, JavaScript 语言在服务器端的运行环境。关于事件驱动,非阻塞异步 I/O 等概念,会在后续的课程中详细介绍到。 20 | 21 | ## Node 的诞生 22 | 23 | Node 诞生于 2009 年,他的作者 Ryan Dahl 起初想要创建一个高性能的 Web 服务器并提供一套库。想要创建高性能的 Web 服务器,至少要具备两个条件:**事件驱动**,**非阻塞异步 I/O**。 24 | 25 | 于是,他的目标就是要写一这样的 Web 服务器,而他并不想重新再创造一门编程语言,那么使用什么编程语言呢,这是一个问题。他本身是 C/C++ 程序员,然而他认为 C++ 的门槛太高了,很多开发者可能并不想去做实际的业务开发,而基于 **事件驱动**,**非阻塞异步 I/O** 这两点的考虑,衡量了 Ruby,Haskell 等语言后,他最终选择了 JavaScript 作为它的语言。 26 | 27 | 在此之前,JavaScript 只是一门在浏览器环境下运行的语言,它的学习门槛非常低,而在服务器端几乎没有市场,可以说「这是一片净土」,为它倒入一套「非阻塞异步 I/O 库」要容易得多了。另外一个重要的原因,JavaScript 在浏览器环境下,就已经广泛的使用了「事件驱动」,像页面按钮的监听点击动作,页面加载完成事件等等,都是「事件驱动」方面的应用。 28 | 29 | 正是因为 JavaScript 这三个方面的优势: 1. 学习门槛低 2. 无太多阻力构建非阻塞异步 I/O 模型 3. 事件驱动的天然优势 30 | 31 | 让 JavaScript 成为了 Node 的实现语言。而在浏览器大战中,Google 的 Chrome 浏览器 JavaScript V8 引擎一战成名,于是 Node 采用高性能的 V8 作为运行环境,也就顺理成章了。 32 | 33 | 说到这里,相信你已经大概了解 Node 定义中的那段话,接下来的问题是,它能做什么呢? 34 | 35 | ## Node 的用途 36 | 37 | 其实,我比较反感去回答,某个语言能做什么?我认为这是一个特别没有意思的问题,比如,有点人可能会说,我要做爬虫,所以我要学 Python,我要学开发网站,所以我要学 PHP 和 Java。这其中,其实没有任何的因果关系,有关系的只是你掌握的程度。 38 | 39 | 就如 Ryan Dahl 想要一个高性能的 Web 服务器,他的选择是创造了 Node,使用了 JavaScript 语言。在此之前,你如果要问 JavaScript 能做什么?得到的答案应该是:让网页动起来。**而如今,你几乎可以使用 JavaScript 做任何事情**。 40 | 41 | 好了,我们换个问法,Node 适合做什么?前面介绍了,它是一个高性能的 Web 服务器, 采用的是事件驱动,异步I/O模型,那么它的优势就在 Web,高性能 I/O 上面,于是它擅长做如下应用: 42 | 43 | * Web 服务 API( REST ) 44 | * 服务端 Web 应用,高并发请求 45 | * 即时通信应用 46 | * 静态文件服务器( I/O 类) 47 | * ...... 48 | 49 | 擅长的应用可能多了去了,那么,它不擅长什么? 50 | 51 | 发展之初的时候,由于单线程的弱点,我可能会说,它不适合在多 CPU 架构服务器上运行(因为他是单线程的),不适合做大规模计算类的应用(因为单线程,一旦 CPU 被计算阻塞,异步也就白扯了),但是,如今这些曾经的问题,都已经不是问题了,Node 引入了 child\_process 子进程模块,解决单线程问题。 52 | 53 | 所以,Node 的用途是非常广泛的,想做爬虫,使用 Node 也是可以实现的,想做 Web ,Node 更是可以胜任。 54 | 55 | 在我看来,其他编程语言也都一样,他们只是一个工具,为我们服务的工具,问题是我们能不能用好这个工具,而不是工具本身的问题,当然,也不可否认工具是否合适的问题。**在有了 Node 之后,如今的 JavaScript 几乎可以做任何事情**。 56 | 57 | ## 闲聊:JavaScript 的那些规范 58 | 59 | 你已经知道了,Node 只是 JavaScript 在服务器端的运行环境,所以,在使用 Node 开发过程中,我们使用的是 JavaScript 这门语言,鉴于它的特殊性,以及历史渊源,我觉得还是有必要聊一聊,关于 JavaScript 的一些规范。 60 | 61 | JavaScript 语言的缔造者「网景」公司,希望 JavaScript 语言能够成为国际标准,最开始交给标准化组织 ECMA 去制作规范,由于与 Java 商标等因素,ECMA 组织发布的这套规范,不叫 JavaScript ,而是叫 ECMAScript,这就是 ECMAScript 的由来,也是最初的 JavaScript 语言的官方规范。 62 | 63 | ECMAScript 5.1 到 6.0 版本的时候,ECMA 标准化组织想让发布标准变成一个常规流程,于是规定每年 6 月份的时候发布一次正式版本,不再沿用旧版本号来记录,直接以当年年份作为名称,例如:ECMAScript 2018,简称 ES2018,就是在 2018 年 6 月发布的最新一版。以这种规则发布的第一个版本是在 2015 年 6 月,它是 5.1 到 6.0 的第一个版本,称作 ES2015 ,也称作 ES6,由于这一次的变化非常大,所以,ES6 泛指下一代 JavaScript 标准。 64 | 65 | 我们都知道,在 Node 诞生之前,JavaScript 一直主要应用于浏览器端,它在服务器端的作为,几乎可以忽略不计。所以 ES6 标准之前,JavaScript 的规范都受限于浏览器端的环境,所以,它的官方规范是相当薄弱的,都不能称作为一个完整的语言。 66 | 67 | 而 CommonJS 就在这种背景下,由 JavaScript 开发者社区共同制定出来了,它定义了 JavaScript 语言的模块系统,Buffer,I/O处理,Web 服务器接口等等规范,填补了 JavaScript 在服务器端的空缺,Node 正是借助了 CommonJS 的一些规范,迅速在服务器端打开市场。 68 | 69 | 随着时间推移,各大浏览器对 ES6 的支持以及 Node 的发展,ES6 正式成为下一代 JavaScript 语言的国际标准。 70 | 71 | > 查看浏览器对 ES6 的支持程度 访问:[http://ruanyf.github.io/es-checker/](http://ruanyf.github.io/es-checker/) 72 | 73 |  74 | 75 | > 查看你当前 Node 环境对 ES6 的支持程度 76 | > 77 | > * `npm i -g es-checker` 安装检测模块 78 | > * `es-checker` 运行模块 79 | 80 |  81 | 82 | 参考资源:[ECMAScript 6 入门 - 阮一峰](http://es6.ruanyifeng.com/) 83 | 84 | -------------------------------------------------------------------------------- /Basic/02_start_node.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 开始 Node 的开发之旅 3 | --- 4 | 5 | 从这一节课程开始,就正式进入开发实战中。工欲善其事,必先利其器,要开始学习 Node 开发了,Node 的环境一定要准备好。这一节课程的主要内容是 Node 环境的安装,以及编写属于 Node 的「Hello, World」。 6 | 7 | ## Node 环境 8 | 9 | Node 是全平台支持的,官方提供了下载地址,分为长期版本以及当前版本,初学者建议安装长期版本,截止到写该篇文章为止,Node 的长期版本号为:10.15.1,我们打开官方下载页面:[Download \| Node.js](https://nodejs.org/en/download/) 10 | 11 |  12 | 13 | Windows 平台和 Mac 平台直接下载对应的软件包,然后双击安装即可。 14 | 15 | 这里主要介绍一下 Linux 平台的安装,如果你使用的是 Ubuntu 系统的话,有可能会发现,通过 `sudo apt install node` 命令是无法安装的,那是因为 apt 库里没有该软件包。如果是这种情况,我们就需要自己下载软件包进行安装。下载 Linux 编译好的软件包,即上面的 `Linux Binaries` 的版本,注意别下成源码了,源码编译太慢了(别问我怎么知道了)。 16 | 17 | 命令行界面,我们使用 wget 下载,命令如下: 18 | 19 | ```bash 20 | wget https://nodejs.org/dist/v10.15.1/node-v10.15.1-linux-x64.tar.xz 21 | ``` 22 | 23 | 以上是 10.15.1 长期版本的下载链接,如果版本有更新,请到官网找到最新的下载链接。下载到当前目录后解压,命令如下; 24 | 25 | ```bash 26 | tar -xvf node-v10.15.1-linux-x64.tar.xz 27 | ``` 28 | 29 | 解压出来一个目录,进入 bin 目录,你会发现直接就能用了。这就是 Linux 的魅力,基本都是绿色软件。我们转移一下软件目录,我一般的习惯是剪贴到 /usr/local/ 目录下,命令如下: 30 | 31 | ```bash 32 | mv node-v10.15.1-linux-x64/* /usr/local/node 33 | ``` 34 | 35 | 最后,编写 ~/.zshrc 文件,添加 PATH ,这样你就可以在任何目录下访问 `node` 以及 `npm` 命令了。`vim ~/.zshrc` 编辑文件,在任何地方添加一行: 36 | 37 | ```bash 38 | export PATH=$PATH:/usr/local/node/bin 39 | ``` 40 | 41 | > 另外,Mac 用户还可以通过 bower 来安装 Node ,通过命令 `bower install node` 即可。 42 | 43 | Node 环境安装完成之后,在命令行处输入 `node -v`,显示版本号,即表示安装成功。于此同时,你也拥有了,目前最大的前端包管理器,它就是 [npm](https://www.npmjs.com/) 。 44 | 45 | 它的强大之处,就在「有事没事,上去搜一下,只有你想不到的,没有它没有的」。开发过程中,很多时候,你觉得很麻烦的地方,没准别人早就做好模块,等着供你使用了。 46 | 47 | 学习以下命令,基本就满足开发需要了。 48 | 49 | * `npm -l` 查看命令帮助 50 | * `npm install --save xxx` 安装到项目目录中 51 | * `npm install -g xxx` 全局安装,之前安装的 `supervisor` 以及 `express-generator` 就是这类 52 | * `npm ls xxx` 查看当前目录是否安装该依赖 53 | * `npm search xxx` 搜索依赖包 54 | 55 | > 以上 install 可缩写成 i 56 | 57 | ## supervisor 58 | 59 | 什么是 supervisor?它是一个进程管理工具,当线上的 Web 应用崩溃的时候,它可以帮助你重新启动应用,让应用一直保持线上状态。听起来,开发阶段貌似没有啥用呀,其实不然,开发阶段更需要它。 60 | 61 | 开发的时候,当修改后台代码后,我们需要重启服务,以便及时看到最新的效果,如果没有它,我们需要修改一段代码,就要手动重启一下服务,效率就低下了。 62 | 63 | 安装方法很简单,在命令行中,输入 `npm i -g supervisor` 即可。安装完成之后,我们就可以使用 `supervisor` 命令来替代 `node` 命令启动项目了,当项目中代码变化时,`supervisor` 会自动帮我们重启项目。 64 | 65 | ## Hello, Node 66 | 67 | Node 安装完成之后,我们在命令行处输入 `node`,会出现命令行交互界面,我们输入 `console.log('Hello, World!')` 回车,将会在控制台,打印出 Hello, World! 的字样。如下图所示: 68 | 69 |  70 | 71 | 如果我说,这就是 Node 的「Hello, World」程序,你一定会质问,这算什么呀?在浏览器命令行里,输入同样的代码,也会出现相同的结果,这明明是 JavaScript 语言的「Hello, World」,跟 Node 有半毛钱关系呀。 72 | 73 |  74 | 75 | 没错,如果拿这个冒充 Node 的「Hello, World」,一定会让人瞧不起的。现在就来看看,属于 Node 的 「Hello, World」,上面提到过,Node 的诞生,最初是为了成为一个高性能的 Web 服务器,所以,它的优势当然在 Web 上。且看下面一段代码: 76 | 77 | ```javascript 78 | const http = require('http'); 79 | http.createServer(function(req,res){ 80 | res.setHeader('content-type', 'text/plain'); 81 | res.end('Hello, World!'); 82 | }).listen('3000'); 83 | console.log('Server is started @3000'); 84 | ``` 85 | 86 | 先不着急明白代码的含义,先在编辑器上敲出如上代码,然后保存到本地,命名为 helloworld.js ,然后到终端中,使用 `supervisor helloworld.js` 命令运行代码,终端显示如下: 87 | 88 |  89 | 90 | 如果上述环境安装都没有问题的话,你的服务已经在本地 3000 端口跑起来了,打开浏览器,输入网址:[http://localhost:3000](http://localhost:3000) 你将会看到,属于 Node 的 「Hello, World」程序。 91 | 92 | 我们修改一下代码,将打印的文本替换成 「Hello, Node!」,在终端处,你会看到服务自动重启,如下图: 93 | 94 |  95 | 96 | 这就是 supervisor 的作用。 97 | 98 | ## 小结 99 | 100 | 这一节课程,我们正式走入的 Node 开发之旅。 101 | 102 | * 首先,我们在 Node 官网上,找到了 Node 环境的安装方法,并且详细介绍了 Linux 环境下的安装步骤; 103 | * 然后,通过 NPM 包管理器,安装了我们的第一个工具:supervisor,它能够帮助我们不断的重启服务,当我们修改了代码之后; 104 | * 最后,我们写出了属于 Node 的 「Hello, world」程序,正式进入 Node 开发。 105 | 106 | -------------------------------------------------------------------------------- /Basic/03_node_modules.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 模块机制与规范 3 | --- 4 | 5 | 上一节课程,我们写出了 Node 的「Hello, World」程序,但是我们还不知道它具体是什么原理。这篇课程,就从「Hello,World」的这段代码着手,带你了解 Node 的模块机制及规范。 6 | 7 | 一段简单的代码,如果真的要深入去挖掘,你会发现,其实并没有你想象的那么简单,我们再来看看这段代码。 8 | 9 | ```javascript 10 | const http = require('http'); 11 | http.createServer(function(req,res){ 12 | res.setHeader('content-type', 'text/plain'); 13 | res.end('Hello, World!'); 14 | }).listen('3000'); 15 | console.log('Server is started @3000'); 16 | ``` 17 | 18 | 假如我是一个初学者,我有很多的问题想要问: 19 | 20 | 1. require 是什么? 21 | 2. http 是什么? 22 | 3. createServer 方法定义的是什么? 23 | 4. createServer 方法里竟然传入了一个 function,这是什么操作? 24 | 5. req, res 各自是什么? 25 | 6. console 又是什么? 26 | 27 | 你看,短短 6 句代码,随随便便就能问出这么多问题,而且都还不算深入的,这些问题真要深入去研究,几乎都可以当作一个课题,因为它涉及到了 HTTP 模块 API、CommonJS 规范、事件驱动、函数式编程等等概念。这里我们先不着急去回答这些问题,我们依然从 Node 的基础概念入手。 28 | 29 | ## 模块的起源 30 | 31 | 在 JavaScript 语言还只是在浏览器端应用的时候,几乎没有模块概念的,这一块的缺失,使得 JavaScript 这门语言很难承担大型项目的责任,为什么这么说呢? 32 | 33 | 在大型项目中,我们通常需要将各个功能模块拆开,形成一个一个组件,或者更小的功能模块,一来为了代码的复用,二来可以降低各个功能模块间的耦合性,从而减少二次维护成本。所以,一门语言具备合理的模块机制,在大型项目开发中就显得至关重要。 34 | 35 | 在第一节谈到 JavaScript 的那些规范的时候,提到过,JavaScript 很多关于后台开发的规范,都源自于 CommonJS,Node 也正是借助了 CommonJS ,从而迅速在服务器端占领市场。那么 CommonJS 的模块机制到底定义些什么内容呢? 36 | 37 | ## 模块的规范 38 | 39 | ### 什么是模块? 40 | 41 | > 每一个文件都是一个模块,其中定义的变量、函数以及类都是**私有的**,所以模块内部定义的变量,只在该模块作用域下,不会污染全局作用域 42 | 43 | 示例:我们创建一个 `template.js` 文件,写上如下代码: 44 | 45 | ```javascript 46 | var http = 'hello, world, I am from template!'; 47 | var changeToHeader = () => { 48 | return '