├── .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 | ![](./_image/2019-03-12-21-46-23.png) 74 | 75 | > 查看你当前 Node 环境对 ES6 的支持程度 76 | > 77 | > * `npm i -g es-checker` 安装检测模块 78 | > * `es-checker` 运行模块 79 | 80 | ![](./_image/2019-03-12-21-45-06.png) 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 | ![](./_image/2019-03-04-22-50-13.jpg) 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 | ![](./_image/2019-03-14-22-55-53.png) 70 | 71 | 如果我说,这就是 Node 的「Hello, World」程序,你一定会质问,这算什么呀?在浏览器命令行里,输入同样的代码,也会出现相同的结果,这明明是 JavaScript 语言的「Hello, World」,跟 Node 有半毛钱关系呀。 72 | 73 | ![](./_image/2019-03-15-21-19-40.png) 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 | ![](./_image/2019-03-15-21-25-58.png) 89 | 90 | 如果上述环境安装都没有问题的话,你的服务已经在本地 3000 端口跑起来了,打开浏览器,输入网址:[http://localhost:3000](http://localhost:3000) 你将会看到,属于 Node 的 「Hello, World」程序。 91 | 92 | 我们修改一下代码,将打印的文本替换成 「Hello, Node!」,在终端处,你会看到服务自动重启,如下图: 93 | 94 | ![](./_image/2019-03-15-21-34-50.png) 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 '

' + http + '

'; 49 | } 50 | ``` 51 | 52 | 这里定义两个变量,它的作用域只在 template 模块中,不会影响其他地方定义的 http 和 changeToHeader 变量。 53 | 54 | ### global? 55 | 56 | > global 是顶层对象,其属性对所有模块共享,但由于作用域污染问题,不建议这么使用 57 | 58 | 从这里我们就知道了,为什么 console 都没有定义,就能直接使用了,因为在 Node 中,它是直接「挂靠」在 global 顶层对象下的「一等公民」,`console` 也等同于 `global.console`,在终端里,我们执行 `console.log(global.console)`,打印 console 对象看看,得到如下结果: 59 | 60 | ![](./_image/2019-03-20-21-18-39.png) 61 | 62 | 第一个变量,就是上述我们使用的 log 方法。 63 | 64 | ### 如何导出模块? 65 | 66 | > module 对象代表当前模块,它的 exports 属性(即 module.exports)是对外的接口,加载某个模块,其实是加载该模块的 module.exports 67 | 68 | 我们想要把 template 中的 changeToHeader 导出为对外的模块,于是在 template.js 中,最后加上一句代码即可。 69 | 70 | ```javascript 71 | module.exports = changeToHeader; 72 | ``` 73 | 74 | ### 如何加载模块? 75 | 76 | > 加载模块使用 require 方法,模块的加载是单次的,只会加载一次,之后就会被缓存 77 | 78 | 上面已经把 template 导出为对外模块了,我们在 helloworld.js 中引入模块,修改代码如下: 79 | 80 | ```javascript 81 | const http = require('http'); 82 | const template = require('./template.js'); 83 | http.createServer(function(req,res){ 84 | res.setHeader('content-type', 'text/html'); // 这里修改成了 html 85 | res.end(template('Hello, Node!')); // 这里使用 template 模块 86 | }).listen('3030'); 87 | console.log('Server is started @3030'); 88 | ``` 89 | 90 | 如果你的服务没有杀掉,这会应该自动重启了,浏览器打开 [http://localhost:3030](http://localhost:3030) ,将会看到如下结果: 91 | 92 | ![](./_image/2019-03-20-22-37-43.png) 93 | 94 | 我们刚刚完成了,模块的导出以及引用。 95 | 96 | ### module.exports 和 exports 区别? 97 | 98 | module.exports 属性表示当前模块对外输出的接口,上面已经讲到了,假如我想将多个方法或者变量对外开放,该如何操作?聪明如你,可能已经想到下面的方法: 99 | 100 | ```javascript 101 | var http = 'hello, world, I am from template!'; 102 | var changeToHeader = () => { 103 | return '

' + http + '

'; 104 | } 105 | console.log('loader from module template'); 106 | module.exports.changeToHeader = changeToHeader; 107 | module.exports.http = http; 108 | ``` 109 | 110 | exports 本身也是对象,在对象上加属性是 JavaScript 再常规不过的操作了,我们把 http 变量也暴露出去,在 helloworld.js 中引用一下,如下: 111 | 112 | ```javascript 113 | const http = require('http'); 114 | const template = require('./template.js'); 115 | http.createServer(function(req,res){ 116 | res.setHeader('content-type', 'text/html'); 117 | res.write(template.http); // 返回模块 template 的 http 变量 118 | res.end(template.changeToHeader()); // 返回 changeToHeader() 方法 119 | }).listen('3030'); 120 | console.log('Server is started @3030'); 121 | ``` 122 | 123 | 再刷新一下浏览器,出现结果: 124 | 125 | ![](./_image/2019-03-20-23-16-29.png) 126 | 127 | 跟我们想要的结果一致,但是,`module.exports.xxx = xxx` 这种写法太繁琐了吧。干脆不要了,直接写成这样: 128 | 129 | ```javascript 130 | exports.changeToHeader = changeToHeader; 131 | exports.http = http; 132 | ``` 133 | 134 | 诶,还真可以,但也许并非你想象的那样,那是因为 Node 为我们做了一些事情。Node 为每个模块提供一个 exports 变量,指向 module.exports ,也就是说,在每个模块,都自动帮我们定义了一个变量 exports , 而且 `exports = module.exports`,这里等号是赋值的意思。有了这个定义,才有了上面省略 module 的写法。 135 | 136 | 有了这样的定义,我们要注意两点: 137 | 138 | 1. 不能给 exports 变量重新赋值,因为会覆盖掉 module.exports 对象; 139 | 2. 在使用 exports.xxx = xxx 导出 xxx 变量后,如果同时使用了 module.exports = yyy,将无法得到 xxx,因为 module.exports 被重新赋值了; 140 | 141 | ## 模块的分类 142 | 143 | 模块大体分为「核心模块」和「文件模块」。 144 | 145 | ### 核心模块 146 | 147 | 核心模块是 Node 直接编译成二进制的那一类,这类模块总是会被优先加载,例如上述的 http 模块。在引用的时候,也最为方便,直接使用 require\(\) 方法即可。 148 | 149 | ### 文件模块 150 | 151 | 文件模块就是我们自己编写的或是他人编写的,我们自己编写的模块,一般都是通过文件路径进行引入,例如上述: 152 | 153 | ```javascript 154 | const template = require('./template.js'); 155 | // .js 可以省略,如果找不到 Node 会自动加上 .js .json .node 进行查找 156 | ``` 157 | 158 | 引用他人编写的模块,通常情况下,都是通过 npm 包管理器来安装,安装命令:`npm i xxx --save`,会自动将模块安装到项目根目录 node\_modules 下,引用的时候,直接 require\('xxx'\) 即可,同核心模块引用方式一样。假如没有找到模块,Node 会自动到文件的上一层父目录进行查找,直到文件系统的根目录。如果还没有找到,则会报错找不到。 159 | 160 | ## 小结 161 | 162 | 到这里,相信你对 Node 模块机制有了初步的了解,它给我们提供了一种便捷的方法,来组建我们的项目。这一节课程里,我们了解到 Node 的模块机制来源于 CommonJS 规范,在 CommonJS 规范中定义了关于 global、module、exports 以及 require 等功能。 163 | 164 | 回到我们最开始的问题,相信你已经能够回答「什么是 require?什么是 http?什么是 console?」这类问题了。 165 | 166 | * require 是挂在 global 对象下的方法,它一般用于加载其他模块 167 | * console 是挂在 global 下的对象,它封装了控制台的一些功能 168 | * http 是 Node 定义的核心模块,给我们提供了关于 HTTP 请求的功能 169 | 170 | > PS. 关于 CommonJS 的模块规范,远不止上述这些内容,如有兴趣,可自行再深入学习。 171 | 172 | -------------------------------------------------------------------------------- /Basic/README.md: -------------------------------------------------------------------------------- 1 | # 基础知识 2 | 3 | -------------------------------------------------------------------------------- /Basic/_image/2019-03-04-22-50-13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengloo53/node-fullstack-course/9da61ac77245e05035c65b46505f91211590caf9/Basic/_image/2019-03-04-22-50-13.jpg -------------------------------------------------------------------------------- /Basic/_image/2019-03-12-21-45-06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengloo53/node-fullstack-course/9da61ac77245e05035c65b46505f91211590caf9/Basic/_image/2019-03-12-21-45-06.png -------------------------------------------------------------------------------- /Basic/_image/2019-03-12-21-46-23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengloo53/node-fullstack-course/9da61ac77245e05035c65b46505f91211590caf9/Basic/_image/2019-03-12-21-46-23.png -------------------------------------------------------------------------------- /Basic/_image/2019-03-14-22-55-53.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengloo53/node-fullstack-course/9da61ac77245e05035c65b46505f91211590caf9/Basic/_image/2019-03-14-22-55-53.png -------------------------------------------------------------------------------- /Basic/_image/2019-03-15-21-19-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengloo53/node-fullstack-course/9da61ac77245e05035c65b46505f91211590caf9/Basic/_image/2019-03-15-21-19-40.png -------------------------------------------------------------------------------- /Basic/_image/2019-03-15-21-25-58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengloo53/node-fullstack-course/9da61ac77245e05035c65b46505f91211590caf9/Basic/_image/2019-03-15-21-25-58.png -------------------------------------------------------------------------------- /Basic/_image/2019-03-15-21-34-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengloo53/node-fullstack-course/9da61ac77245e05035c65b46505f91211590caf9/Basic/_image/2019-03-15-21-34-50.png -------------------------------------------------------------------------------- /Basic/_image/2019-03-20-21-18-39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengloo53/node-fullstack-course/9da61ac77245e05035c65b46505f91211590caf9/Basic/_image/2019-03-20-21-18-39.png -------------------------------------------------------------------------------- /Basic/_image/2019-03-20-22-37-43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengloo53/node-fullstack-course/9da61ac77245e05035c65b46505f91211590caf9/Basic/_image/2019-03-20-22-37-43.png -------------------------------------------------------------------------------- /Basic/_image/2019-03-20-23-16-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengloo53/node-fullstack-course/9da61ac77245e05035c65b46505f91211590caf9/Basic/_image/2019-03-20-23-16-29.png -------------------------------------------------------------------------------- /Practice/README.md: -------------------------------------------------------------------------------- 1 | # 进阶应用 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 《Node 全栈开发入门》教程 2 | 3 | 教程将分为三个部分,分别为基础知识、进阶应用以及 Web 实战。 4 | 5 | 1. **基础知识**主要介绍 Node 基础原理以及官方 API; 6 | 2. **进阶应用**将通过实际应用进一步了解 Node 开发; 7 | 3. **Web 实战**重点讲实际项目开发,以**后台管理系统**为例。采用的技术栈为:[Express](http://www.expressjs.com.cn/) + [AdminLTE](https://adminlte.io/) + [Mysql](https://www.mysql.com/) + [Sequelize](http://docs.sequelizejs.com/)。 8 | 9 | 后续可能的话,会使用 Vue 框架重构前台页面。 10 | 11 | 课程拟规划目录:[点击这里查看](./SUMMARY.md)。 12 | 13 | ## 关注我 14 | 个人微信公众号:个人学习,专注分享:个人成长、读书感悟以及产品技术主题。 15 | 16 | ![](./_image/weixin-qrcode.png) 17 | 18 | ## 联系我 19 | 个人微信号,请务必备注信息「Node」。 20 | 21 | ![](./_image/qrcode-self.jpeg) 22 | 23 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | * [基础介绍](Basic/README.md) 3 | * [01 走进 Node 的世界,认识 Node](Basic/01_know_node.md) 4 | * [02 开始 Node 开发之旅,Hello Node](Basic/02_start_node.md) 5 | * [03 从 Hello World 程序中了解模块与包](Basic/03_node_modules.md) 6 | * 04 何谓事件驱动?Node 高性能的秘诀 7 | * 05 Node 的异步编程思路,认识非阻塞I/O 8 | * 06 数据高效传输的秘诀,这一次搞懂 stream 9 | * 07 Node 网络编程,学习 http 和 socket 模块 10 | * 08 Node 系统级控制,学习 process 和 os 模块 11 | * [进阶应用](Practice/README.md) 12 | * 09 小图库应用:网页生成以及上传实战 13 | * 10 静态文件服务器:体会异步数据流的魅力 14 | * 11 终端聊天室:socket 网络编程的乐趣 15 | * 12 简单爬虫应用:对外发布一个应用 16 | * [Web 实战](Web/README.md) 17 | * 13 开发之前,一些必要准备工作 18 | * 14 后台模版库的引入 19 | * 15 重新定义路由 20 | * 16 如何连接 MySQL 数据库 21 | * 17 使用 ORM 框架连接数据库 22 | * 18 前后台传参的几种方式 23 | * 19 权限功能设计思路 24 | * 20 配置模块设计,实现在线表格的完整功能 25 | * 21 数据可视化功能入门 26 | * 22 项目本地构建 27 | * 23 项目上线,服务器端部署 28 | -------------------------------------------------------------------------------- /Web/README.md: -------------------------------------------------------------------------------- 1 | # Web 实战 -------------------------------------------------------------------------------- /_image/qrcode-self.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengloo53/node-fullstack-course/9da61ac77245e05035c65b46505f91211590caf9/_image/qrcode-self.jpeg -------------------------------------------------------------------------------- /_image/weixin-qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengloo53/node-fullstack-course/9da61ac77245e05035c65b46505f91211590caf9/_image/weixin-qrcode.png --------------------------------------------------------------------------------