Node.js基础随笔

栏目: Node.js · 发布时间: 5年前

内容简介:node没有全局作用域。在Node.js中,通过require方法加载和执行多个JavaScript脚本文件。文件与文件之间由于是模块作用域,即使加载执行多个文件,可以完全避免变量命名冲突污染。但是某些情况下,模块与模块是需要进行通信的,可通过require方法得加载文件模块导出的接口对象。即:每个模块都提供一个接口对象,默认为空对象,把需要被外部访问的成员挂载在exports接口对象4.2 require的加载规则
  • 基本的网页开发:前端(css/html/js),服务端(node.js/java/php等),运维部署
  • 作为前端开发,通过Node.js学习服务端,可以在js不用学习另一门新语言基础上,较容易上手

2. Node.js是什么?

  • 把Chrome的v8引擎(JavaScript引擎)移植出来,开发独立的JavaScript运行环境。代码只是特殊格式的字符串,JavaScript引擎可以去执行和解析。
  • node.js的特性:事件驱动和非堵塞IO模型
  • npm:世界上最大的开源生态系统,大多数js相关的包都放在npm上,方便开发人员下载使

3. Node.js的JavaScript(没有DOM和BOM)

  • ECMAScript: js基础语法
  • 核心模块
(在Node.js这个执行环境中为JavaScript提供一些服务器级别的api,这些api大多包装到一个具名的核心模块中)
    - fs 文件操作模块
    - http 网络服务构造模块
    - OS 操作系统模块
    - path 路径处理模块
    - url 路径操作模块
复制代码
  • 第三方模块: art-template(npm 下载)
  • 自定义模块: 自己创建的文件

3.1 浏览器的JavaScript

  • ECMAScript:js基础语法: 变量、运算符、流程控制(分支语句,循环结构)、数组、函数、内置对象(Math/Date/String/Array/Object)
  • 文档对象模型(DOM: 处理网页内容的方法和接口(api)。
  • 浏览器对象模型(BOM: 与浏览器进行交互的方法和接口(api)。

4. 模块系统

node没有全局作用域。在Node.js中,通过require方法加载和执行多个JavaScript脚本文件。文件与文件之间由于是模块作用域,即使加载执行多个文件,可以完全避免变量命名冲突污染。但是某些情况下,模块与模块是需要进行通信的,可通过require方法得加载文件模块导出的接口对象。即:

  • 模块作用域
  • 通过require方法,加载文件模块和执行里面的代码
  • 通过require方法,得加载文件模块导出的接口对象exports

4.1 接口对象

每个模块都提供一个接口对象,默认为空对象,把需要被外部访问的成员挂载在exports接口对象

  • 导出多个成员(存在对象中)
b.js中
    exports.a = 123
    exports.b = 'hello'
    exports.c = function () {
        console.log('ccc')
    }
    exports.d = {
        foo: 'bar'
    }
    
    a.js中
    var bExports = require('./b')//require加载模块时,可省略后缀名
    console.log(bExports.d)
复制代码
  • 导出单一成员(直接拿到一个字符串、函数或对象等等)
b.js中
    module.exports = 'hello'
    module.exports = function () {
        console.log(ccc)
    }
    module.exports = {
      add: function () {
        return x + y
      },
      str: 'hello'
    }
    会发生覆盖,只拿到最后一个
    
    a.js中
    var bExports = require('./b')
    console.log(bExports)
复制代码
  • 原理
//在 Node 中,每个模块内部都有一个自己的 module 对象,还有一个成员exports(也是一个对象) 
    当对外导出成员,只需要把导出的成员挂载到 module.exports 中
    var module = {
      exports: {
        foo: 'bar',
        add: function (x, y){
            return x + y
        }
      }
    }
    //添加或导出成员 modeule.exports.xxx = xxx,为了简化你的操作,专门提供了一个变量:exports 等于 module.exports
    var exports = module.exports
    //当两者一致时,可以通过任何一个添加和导出内部成员如:
    exports.a = 'hello'
    module.exports.b = 'hi'
    //当一个模块需要导出单个成员的时候,只能给module.exports赋值,给 exports直接 赋值是不管用的,因为exports的指向发生改变,而模块的接口对象是module.exports。
    //同理,给 module.exports 重新赋值,指向改变,断开和exports的引用
复制代码

4.2 require的加载规则

即根据模块标识来加载即:require('模块标识符')
  1.自己写的模块
    路径形式的模块:1./ 当前目录,不可省略 , 2../ 上一级目录,不可省略 3.js 后缀名可以省略
      var b = require('./foo.js')
      var b = require('./foo')
  2.核心模块
    核心模块的本质也是文件,已经被编译到了二进制文件中(下载后,编译在node.exe),我们只需要按照名字来加载就可以了
      var http = require('http')
      var fs = require('fs')
  3.第三方模块
       凡是第三方模块都必须通过 npm 来下载
       使用的时候就可以通过 require('包名') 的方式来进行加载才可以使用
       如: var template = require('art-template')
       整个加载过程中:
        先找到当前文件所处目录中的 node_modules 目录
        node_modules/art-template
        node_modules/art-template/
        node_modules/art-template/package.json
        node_modules/art-template/package.json 文件中的 main 属性
        main 属性中就记录了 art-template 的入口模块
        如果 package.json文件不存在或者main指定的入口模块是也没有,自动找该目录下的 index.js,index.js 是作为一个默认备选项
        如果以上所有任何一个条件都不成立,进入上一级目录找 node_modules
        按照这个规则依次往上找,直到磁盘根目录还找不到,最后报错:Can not find moudle xxx
        一个项目有且仅有一个 node_modules 而且是存放到项目的根目录
- 优先从缓存加载:再次加载某个模块,不会执行里面的代码,但可以从缓存中拿到其中的接口对象,这样可以避免重复加载,提高模块加载效率
复制代码

5. npm( node package manager)

5.1npm命令行工具

- npm --version版本
- npm install --global npm 升级
- npm init自动初始化package.json文件
- npm init -y跳过向导,快速生成
- npm install一次性把package.json文件的dependencies选项的所有依赖项下载回来
- npm install art-template只下载
- npm install art-template --save下载并保存到dependencies选项
- npm uninstall art-template删除,依赖项依然存在
- npm install art-template --save删除同时删除依赖信息
复制代码

5.2 解决npm被墙的问题

npm存储包文件的服务器在国外,有时会速度很慢。

淘宝开发团队把npm在国内作了个备份淘宝 NPM 镜像

安装淘宝cnpm

在任意目录执行都可以
--global表示安装到全局,而不是当前目录
npm install --global cnpm
cnpm intstall art-template
如果不想安装cnpm又想用淘宝的服务器下载
npm install art-template --registry=http://registry.npm.taobao.org
每次手动添加后面的参数很麻烦,可以把这个选项加入配置文件中
npm config set registry=http://registry.npm.taobao.org
查看npm配置信息是否成功
npm config list
经过上面命令的配置,以后所有的```npm install```都可以通过淘宝服务器来下载
复制代码

5.3 package.json 包描述文件

每个项目都应该有个package.json文件,通过npm init自动初始化出来

PS E:\迅雷下载\14Nodejs教程精讲(7天+5天赠送)\nodejs资料(7天)\03\code> npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (code)
version: (1.0.0) 0.0.1
description:
entry point: (index.js) main.js
test command:
git repository:
keywords:
author: zhanglichun
license: (ISC)
About to write to E:\迅雷下载\14Nodejs教程精讲(7天+5天赠送)\nodejs资料(7天)\03\code\package.json:

{
  "name": "code",
  "version": "0.0.1",
  "description": "",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "zhanglichun",
  "license": "ISC"
}
复制代码

再通过npm install art-template --save来下载第三方包,

{
  "name": "code",
  "version": "0.0.1",
  "description": "",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "zhanglichun",
  "license": "ISC",
  "dependencies": {
    "art-template": "^4.13.2"
  }
}
复制代码

package.json文件多了dependencies这个选项,可保存第三方包的依赖信息。

如果node_modules不小心被删,可通过npm install,自动地把package.json里的dependencies中所有的依赖项下载回来

5.4 修改完代码自动重启

问题:每次修改完有关Node.js的代码时,都要在命令行工具(cmd等)ctrl+c重启

解决:使用第三方命令行工具nodemon ,来帮我们解决修改代码频繁启动服务器的问题

nodemon是基于Node.js开发的第三方命令行工具,使用时我们需要独立安装

--global是全局安装,在任意目录执行该命令都可以
npm install --global nodemon
复制代码

安装完毕,通过nodemon app.js启动服务,它会监视文件变化,当文件发生变化时,自动重启服务器

6. web服务端开发

  • 端口号:
    • IP地址定位的是计算机
    • 端口号定位的是具体应用程序
    • 所有联网通信的软件都必须要端口号
  • Content-Type
    • 在服务端默认响应发送的数据内容是utf8编码,浏览器在不知道服务器响应内容的编码的情况下会按照当前操作系统的默认编码去解析,中文操作系统默认是gbk,特别文本类型的数据,会出现防止中文解析乱码问题,解决方法就是正确的告诉浏览器我给你发送的内容是什么编码的。
    • 不同的资源对应的 Content-Type 是不一样,具体参照: tool.oschina.net/commons
  • 状态码
    • 301 永久重定向,浏览器会记住,除非清除浏览器数据

    • 302 临时重定向,浏览器不会记住,会重新发出请求

      res.statusCode=302/res.setHeader('Location','/')

7. Node.js中其他成员

在每一个模块中,除了require、exports等模块相关的API外,还有两个特殊成员

__dirname 动态获取当前文件模块所属目录的绝对路径

__filename 动态获取当前文件的绝对路径

在文件操作中,相对路径是是不可靠的,因为在node文件操作路径被设计为相对于执行 node 命令所处的终端路径,所以在文件操作中的相对路径都统一转为 动态的绝对路径

在拼接过程中,为了避免手动拼接带来的低价错误,使用path.join(__dirname, './a.txt')来辅助拼接

补充:模块中的路径标识和这里的路径无关

9. 模板引擎

  • 客户端渲染 如商品评论等 不利于seo搜索引擎优化,客户体验更好
    • 如:整个页面,局部刷新获取数据库的数据,可通过Ajax向服务端发出请求数据接口(连接服务器,获取要展示的数据),响应返回数据,再通过模板引擎在客户端渲染数据
  • 服务端渲染 如商品列表 有利于seo搜索引擎优化
    • 如:通过Node.js建立服务端,发出请求,读取文件,通过模板引擎在服务端渲染数据,把响应返回
var fs = require('fs')
    var template = require('art-template')
    var server = http.createServer()
    var wwwDir = 'D:/movie/www/'
    server.on('request', function (req, res) {
      // 1.准备模板===读取template-apache.html
      fs.readFile('./template-apache.html', function (err, data) {
        if (err) {
          return res.end('404 Not Found')
        }
        // 2.准备数据===获取www目录列表
        fs.readdir(wwwDir, function (err, files) {
          if (err) {
            return res.end('404 Not Found')
          }
          // 3.使用模板引擎生成html内容,返回客户端
          var htmlStr = template.render(data.toString(), { files: files })
          res.end(htmlStr)
        })
      })
    })
    server.listen(3000, function (req, res) {
      console.log('running.....')
    })
    
    template-apache.html的模板
    <tbody id="tbody">
          {{each files}}
          <tr>
            <td data-value=""><a class="icon dir" href="/D:/Movie/www/">{{$value}}/</a></td>
            <td class="detailsColumn" data-value="0"></td>
            <td class="detailsColumn" data-value="1509589967">2017/11/2 上午10:32:47</td>
          </tr>
          {{/each}}
        </tbody>
复制代码

9. 其它

9.1 文件操作路径和模块路径

文件操作路径

在文件操作的相对路径中可以省略 ./
   ./data/a.txt 相对于当前目录
   data/a.txt   相对于当前目录
   /data/a.txt  绝对路径,当前文件模块所处磁盘根目录
   c:/xx/xx...  绝对路径
fs.readFile('./data/a.txt', function (err, data) {
  if (err) {
    console.log(err)
    return console.log('读取失败')
  }
  console.log(data.toString())
})
复制代码

模块路径

在模块加载中,相对路径中的不能省略./,同时后缀名可以省略
require(./data/a.txt) require(./data/a) 相对于当前目录
require(data/a.txt) 报错:Cannot find module 'data/a.txt'
require('/data/foo.js') C盘下没有,报错:Cannot find module 'C://data/a.txt'
复制代码

9.2 代码风格

  • javaScript Standard Style
    • 代码分号的问题:不写分号,但要在[]/()/``/前加分号,不然会报错
  • Airbnb JavaScript Style

9.3 each

  • art-template的each, 是 art-template 模板引擎支持的语法,只能在模板字符串中使用
{{each 数组}}
    <li>{{ $value }}</li>
    {{/each}} 
复制代码
  • js数组的foreach,不支持ie8以下版本
;['abc', 'd', 'efg'].forEach(function (item, index) {
      console.log(item)
    })
复制代码
  • jQuery的each
    • 可以在不兼容 forEach 的低版本浏览器中使用 jQuery 的 each 方法遍历数组
$.each(['abc', 'd', 'efg'], function (index, item) {
      console.log(item)
    })
复制代码
  • 遍历 jQuery 选择器选择到的伪数组实例对象
$('div').each(function (index, item) {
      console.log(item)
    })
复制代码
  • jQuery 因为原型是object,它的实例对象不能使用 forEach 方法。如果想要使用必须转为数组才可以使用
[].slice.call(jQuery实例对象
    原理是
    Array.prototype.mySlice = function () {
      var start = 0
      var end = this.length
      var tmp = []
      for (var i = start; i < end; i++) {
        // fakeArr[0]
        // fakeArr[1]
        // fakeArr[2]
        tmp.push(arguments[i])
      }
      return tmp
    }
    var fakeArr = {
      0: 'abc',
      1: 'efg',
      2: 'haha',
      length: 3
    }
    // 所以你就得到了真正的数组。 
    [].mySlice.call(fakeArr)
复制代码

9.4 软件开发版本

  • 一般是这些客户端软件、技术框架开发者比较理解的多,升级后,需要人去下载
  • 做网站很少涉及到版本的概念,不需要下载,只需输入url地址,
x.x.x 
    比如:2(新增功能比较多,甚至可能去除了某些功能).5(加入了新功能).0(修复bug,提升性能)
复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Concepts, Techniques, and Models of Computer Programming

Concepts, Techniques, and Models of Computer Programming

Peter Van Roy、Seif Haridi / The MIT Press / 2004-2-20 / USD 78.00

This innovative text presents computer programming as a unified discipline in a way that is both practical and scientifically sound. The book focuses on techniques of lasting value and explains them p......一起来看看 《Concepts, Techniques, and Models of Computer Programming》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

MD5 加密
MD5 加密

MD5 加密工具