前言

最近想用NodeJS给自己搭建一个内网系统,想起了之前有段时间买了NodeJS的课程,于是乎打算重新学习一下。课程地址《The Complete Node.js Course》 By Mosh

正文

1. 安装NodeJS

我这里用的是Ubuntu来学习, 直接用sudo apt install nodejs安装即可。

# check if node here
node --version
# download from apt
sudo apt install nodejs

2. NodeJS的第一个程序

学习一下NodeJS的第一个Program,输出Hello + 自己的名字。

// First NodeJs program
function sayHello(name) {
        console.log('Hello' + name);
}

sayHello('Xinhai Zou');

运行程序的话使用node <program name>

node app.js

3. Module相关

3.1 Export module

假设我们有一个module名字叫logger.js,我们可以将logger.js的任意元素,通过module.exports.<variables/functions>,来输出,并且之后在外面通过require('<module path>')在另一个module中获取。

// module
 var url = 'https://seanzou.com';
function log(msg) {
	console.log(msg);
}

// exports
module.exports.log = log;
module.exports.endPoint = url; // Unnecessary to be the same as the variable name

在另一个module中import logger.js

const logger = require('./logger.js');
logger.log(logger.endPoint);

3.2 将函数作为整个module来输出

我们也可以将其中一个函数,作为module来输出,但是我个人不是很喜欢这样,因为这样给我感觉相当于将整个module给覆盖了。

function log(msg) {
	console.log(msg);
}
module.exports = log;

在另一个module中import logger.js,并且直接就是能使用log(),而不用像上一节那样还要通过logger.log()来调用。

const log = requre('./logger.js');
log('Hello Wolrd');

3.3 Module Wrapper Function

我们来了解一下module整个模块,每个module其实都是被一个函数(function(exports, require, module, __filename, __dirname){<module>})包裹住的,所以这也就是为什么,在特定module下定义的变量或者函数,只能是局部变量或者局部函数,因为它们只存在于这个wrapper function下面,如果需要export出去,那么就需要使用到module.exports,如果需要import外界的module,那就需要require;然后__filename__dirname就是文件的路径和当前文件所在目录的路径。

(function (exports, require, module, __filename, __dirname) {

... Module code

})

4. Node项目创建

4.1 创建一个node 项目

一般来说,如果我们要做node项目,就需要创建一个node 项目,就比如如果你要用git 你就得git init,你要用ide,也会给相应的folde 添加上一些ide的配置,让ide能够识别、管理和操作等。node也是一样的,具体node 项目初始化的命令如下。

npm init           # 初始化node项目
npm init --yes     # 初始化node项目并且所有配置为默认default

4.2 添加第三方node包到你的项目

如题,就是如何添加第三方的lib到你的项目,第三方可以从NodeJS包管理网站npmjs来查询。具体命令如下:

npm install <package-name>。 # 安装<package-name>这个包

4.3 导入node包

导入包的过程,和我们一样导入自己文件夹的包一样,对于require('<package-name>')这个命令而言,他有着搜索优先级

  1. 先查看<package-name>,是不是不在core module中,如果是则运用
  2. 再查看是否<package-name>是一个本地文件或者目录,如果是则运用
  3. 否则则会去node_modules文件夹里面,寻找<package-name>,是否是一个第三方的应用
var _ = require('underscore');

4.4 .gitignore文件

这里是一些关于.gitignore文件的小介绍,如果不想让node_modules/文件夹上传到github上的话,在这里添加node_modules/文件夹即可。

.gitignore文件中:

node_modules/


一些额外的.gitignore知识

这里有一个其他的小应用就是,通常来说github只上传代码,一些空文件夹是不上传的,但是如果你出于某种原因想把空文件夹也上传的话,那么在git目录下添加一个空的.gitignore就可以了,这就相当于告诉github,这个目录下没有任何一个文件是需要ignore的,全部都要上传。

.gitignore文件在 Git 版本控制系统中起着非常重要的作用。这个文件允许你指定哪些文件或文件夹应该被 Git 忽略,即不被添加到版本控制中。这样做有几个理由和好处:

  1. 减少噪音:开发过程中会产生很多临时文件或编译产物,如日志文件、构建目录等。这些文件通常是个人的或机器特定的,不适合提交到代码仓库中。通过使用.gitignore,你可以避免这些文件干扰版本控制状态,让关注点保持在源代码上。
  2. 避免冲突:一些文件,比如用户特定的配置文件或IDE设置文件,可能在不同开发者之间引起冲突。将这些文件类型添加到.gitignore中,可以防止它们被提交到仓库中,从而减少合作开发中的冲突。
  3. 保护敏感信息:在项目中可能会有包含敏感信息的文件,比如配置文件含有数据库密码等。通过将这类文件列入.gitignore,可以防止这些敏感信息被不小心提交到仓库中,从而增强项目的安全性。
  4. 优化性能:避免将大量不必要的文件添加到版本控制中可以帮助减少仓库的大小,提高 Git 操作的效率,比如克隆和拉取更新。

.gitignore 文件使用相对简单的模式匹配规则来确定哪些文件或目录应该被忽略。例如:

  • *.log 会忽略所有以.log结尾的文件。
  • build/ 会忽略整个build目录。(类似我们这里的node_modules/
  • !important.log 会重新包含被前面规则排除的important.log文件。

通常,.gitignore文件会被放在仓库的根目录下,但你也可以在子目录中添加.gitignore文件以应用局部规则。每个项目都可以有自己定制的.gitignore文件,以满足其特定需求。GitHub 提供了许多针对不同编程语言和框架的.gitignore模板,这些可以作为起点来定制你自己的忽略规则。

4.5 语义版本控制 Semantic Versioning (SemVer)

其实就是版本控制,简单来讲就是通过集中语义符号来进行版本控制。通常来说一个确定的版本表示为Major.Minor.Patch,如如4.13.6,其中4就是Major13就是Minor6就是Patch

  • 其中Major表示这次更新会破坏当前的API、也就是所谓的大改,很多事情都要改变,有可能引发不兼容的错误
  • Minor表示,虽然有功能上的更新,但是所有的API接口,或者函数名称、功能都未改变,向上兼容
  • Patch表示,功能未更新,只是修复一些功能上存在的bugs

语义控制即为通过^~两个符号来控制版本的更新,具体如下看一下其实也就明白了:

  • ^4.13.6 - 更新到major=4的目前最新的版本
  • ~4.13.6 - 更新到major=4minor=13的目前最新的版本
  • 4.13.6 - 更新到major=4minor=13patch=6的目前最新的版本,也就是更新到确定版本4.13.6

4.6 查看npm项目lib结构

就是查看当前目录下npm项目的结构,包名、包版本等,具体命令如下:

npm list                  # lib结构
npm list --depth=0        # lib结构,只看depth=0的深度

npm view mongoose         # view
npm view mongoose dependencies
npm view mongoose version # history

4.7 局部命令和全局命令

这里我们其实可以适当区分一下局部lib 和 全局的lib,局部lib是只在本npm项目下安装lib,而全局lib是在整个npm环境下安装lib,而不是单单这个npm项目下,比如npm就是一个全局的lib,通常在terminal命令行中使用。

下面是局部命令:


npm outdated # 这个命令只作用于minor 和 patch,并不会查看major是否过期。
npm install <package-name>        # 局部安装,只在当前npm项目
npm install mongoose@2.4.2
npm uninstall <package-name>      # 局部卸载,只在当前npm项目
npm uninstall mongoose

下面是全局命令

npm -g outdated
npm install -g <package-name>      # 全局安装,在node全局
npm uninstall -g <package-name>    # 全局卸载,在node全局

npm i -g npm-check-updates # not for npm(8.5.1) and node(v12.22.9)
npm-check-updates # not for npm(8.5.1) and node(v12.22.9)

4.8 开发依赖 (to a specific project)

在使用npm(Node Package Manager)安装包时,--save-dev 选项的作用是将安装的包作为开发依赖(development dependencies)添加到项目的 package.json 文件中。这与生产依赖(dependencies)不同,生产依赖是项目运行时必须的依赖,而开发依赖则是仅在开发过程中需要的。

npm i jshint --save-dev # development dependencies

比如以上一个命令,具体来说,当你运行npm i jshint --save-dev命令时,npm会执行以下操作:

  1. 安装jshint包:将jshint包及其依赖安装到项目的node_modules目录中。
  2. 更新package.json:在package.json文件的devDependencies对象中添加jshint。这意味着jshint是该项目开发过程中需要的依赖,而不是生产环境下运行应用时必需的。

使用--save-dev的好处在于,它帮助开发者区分开发依赖和生产依赖,使得项目结构更清晰,同时也可以优化最终部署的包的大小。例如,测试框架、构建工具或代码格式化工具通常只在开发过程中使用,将它们作为开发依赖安装可以避免在生产环境中安装不必要的包。

总结一下,--save-dev用于指定包是开发依赖,有助于项目依赖管理,确保开发环境和生产环境的依赖清晰分离。

总结

估计此文章只会记录NodeJS的安装,和相关的module导入导出,其他NodeJS相关内容应该会开其他的文章来填。

(●'◡'●)嘻嘻,这样就可以愉快地水很多文章了~!

更新

[1] 2024年3月10日更新:好吧我还是更新了一点nodeJS,包管理之类的东西。并没有开新的文章水捏~

参考

[1] The Complete Node.js Course

Q.E.D.


立志做一个有趣的碳水化合物