创建 Node 项目

npm init -y # 初始化 Node 项目

package.json 文件

这个文件记录了项目的相关信息。

{
"name": "hello-node",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "node src/index.cjs",
"serve": "node server/index.js",
"compile": "babel src/babel --out-dir compiled"
},
"author": "",
"license": "ISC",
"devDependencies": {
...
}
}

其中 scripts 项记录了我们可以对项目运行的命令。使用 npm run xxx 就可以运行对应的命令。

项目命名规则

类型 释义 例子
范围包 具备 @scope/project-name 格式,一般有一系列相关的开发依赖之间会以相同的 scope 进行命名。 @vue/cli@vue/cli-service 就是一系列相关的范围包。
普通包 其他命名都属于普通包。 vuevue-router

模块化

CommonJS

CommonJS 是在 ES Module 标准出现之前的事实标准。在老项目中非常常见。

遵循 CommonJS 标准的 JavaScript 文件可以使用 .cjs 或者 .js 后缀。

CommonJS 使用 module.exports 导出模块,使用 require('module/path') 导入模块。

默认导出
// module.cjs
module.exports = 'Hello World' // 导出一个字符串
// index.cjs
const m = require('./module.cjs') // 导入的也是字符串
console.log(m)
命名导出

其实我觉得本质上就是默认导出

// module.cjs
function foo() {
console.log('Hello World from foo.')
} const bar = 'Hello World from bar.' module.exports = {
foo,
bar,
}
// index.cjs
const m = require('./module.cjs')
m.foo()
console.log(m.bar)

或者利用 ES6 的对象解构来直接拿到变量:

// index.cjs
const { foo, bar } = require('./module.cjs')
foo()
console.log(bar)

还可以导入时重命名:

// index.cjs
const {
foo: foo2, // 这里进行了重命名
bar,
} = require('./module.cjs') // 不会造成变量冲突
const foo = 1
console.log(foo) // 用新的命名来调用模块里的方法
foo2()

ES Module

ES Module(ESM)是在 ES6 中推出的。ES(ECMAScript)是 JavaScript 标准的名称。

ESM 使用 export default(默认导出)和 export(命名导出)两个语法导出模块,使用 import ... from 'module/path' 导入模块。

默认导出
// module.mjs
export default 'Hello World'
// index.mjs
import m from './module.mjs'
console.log(m)
命名导出
// module.mjs
export function foo() { // 导出 foo
console.log('Hello World from foo.')
} export const bar = 'Hello World from bar.' // 导出 bar
// src/esm/index.mjs
import { foo, bar } from './module.mjs'
foo()
console.log(bar)

也可以使用 * as 变量名 的方式将模块所有命名挂在指定的变量上:

// index.mjs
import * as m from './module.mjs' // 将所有命名导出挂在 m 变量上
m.foo()
console.log(m.bar)

也可以导入时重命名:

// index.mjs
import {
foo as foo2, // 这里进行了重命名
bar
} from './module.mjs' // 不会造成变量冲突
const foo = 1
console.log(foo) // 用新的命名来调用模块里的方法
foo2()

使用 npm 包

npm install md5 -S # 安装包到本地,并列为生产依赖(默认)
npm install md5 -D # 安装包到本地,并列为开发依赖

TypeScript

数据类型

原始数据类型:string, number, boolean, bigint, symbol, null, undefined

sonst num: number = 1
const str = 'Hello World' // 这样也不会报错,因为 TS 会推导类型

数组:number[], UserItem[]

const strs: string[] = ['Hello World', 'Hi World']
const nums = [1, 2, 3] // 自动推导类型

接口和类

接口:interface

// 定义用户对象的类型
interface UserItem {
name: string
age: number
enjoyFoods: string[]
friendList?: UserItem[] // ? 表示可选属性
} // 在声明变量的时候将其关联到类型上
const petter: UserItem = {
name: 'Petter',
age: 18,
enjoyFoods: ['rice', 'noodle', 'pizza'],
friendList: [
{
name: 'Marry',
age: 16,
enjoyFoods: ['pizza', 'ice cream'],
friendList: [],
}
]
}

继承:extends

// 这里继承了 UserItem 的所有属性类型,并追加了一个权限等级属性
interface Admin extends UserItem {
permissionLevel: number
} const admin: Admin = {
name: 'Petter',
age: 18,
enjoyFoods: ['rice', 'noodle', 'pizza'],
friendList: [
{
name: 'Marry',
age: 16,
enjoyFoods: ['pizza', 'ice cream'],
friendList: [],
}
],
permissionLevel: 1
}

部分继承:使用 Omit 帮助类型

// 这里在继承 UserItem 类型的时候,删除了两个多余的属性
interface Admin extends Omit<UserItem, 'enjoyFoods' | 'friendList'> {
permissionLevel: number
} // 现在的 admin 就非常精简了
const admin: Admin = {
name: 'Petter',
age: 18,
permissionLevel: 1,
}

类:class

// 定义一个类
class User {
// constructor 上的数据需要先这样定好类型
name: string // 入参也要定义类型
constructor(userName: string) {
this.name = userName
} getName() {
console.log(this.name)
}
} // 通过 new 这个类得到的变量,它的类型就是这个类
const petter: User = new User('Petter')
petter.getName() // Petter

类和接口之间也可以互相继承

联合类型:string | number

const ele: HTMLElement | null = document.querySelector('main') // ele 既可以是 HTMLElement,又可以是 null

函数

函数:

function sum1(x: number, y: number): number {
return x + y
} function sum(x: number, y: number, isDouble?: boolean): number { // 可选参数必须在必选参数后面
return isDouble ? (x + y) * 2 : x + y
} function sayHi(name: string): void { // 无返回值
console.log(`Hi, ${name}!`)
}

函数重载:

function greet(name: string): string  // 对 string 类型的重载
function greet(name: string[]): string[] // 对 string[] 类型的重载
function greet(name: string | string[]) { // 真正的函数体,此时可以省略返回类型
if (Array.isArray(name)) {
return name.map((n) => `Welcome, ${n}!`)
}
return `Welcome, ${name}!`
} // 单个问候语,此时只有一个类型 string
const greeting = greet('Petter')
console.log(greeting) // Welcome, Petter! // 多个问候语,此时只有一个类型 string[]
const greetings = greet(['Petter', 'Tom', 'Jimmy'])
console.log(greetings)
// [ 'Welcome, Petter!', 'Welcome, Tom!', 'Welcome, Jimmy!' ]

npm 包

一些早期的 npm 包是使用 JavaScript 写的,无法直接引入到 TypeScript 项目里。开源社区维护了一套 @types 类型包,提供这些包的 TypeScript 版本。

@types 类型包的命名格式为 @types/<package-name>,如 @types/md5

类型断言

类型断言可以让 TypeScript 不再检查变量的类型,而是直接使用你指定的类型。

// 原本要求 age 也是必须的属性之一
interface User {
name: string
age: number
} // 但是类型断言过程中,遗漏了
const petter = {} as User
petter.name = 'Petter' // TypeScript 依然可以运行下去,但实际上的数据是不完整的
console.log(petter) // { name: 'Petter' }

编译

直接运行 TypeScript 程序:

# 安装依赖
npm install -g ts-node
# 运行
ts-node main.ts

编译为 JavaScript:

# 安装依赖
npm install -g typescript
# 初始化 TypeScript 项目
tsc --init

编辑 TypeScript 项目配置文件 tsconfig.json

{
"compilerOptions": {
"target": "es6", // JavaScript 版本
"module": "es6", // 模块规范
"outDir": "./dist" // 输出目录
}
}

编译:

tsc

Node.js 使用的更多相关文章

  1. node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理

    一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...

  2. 利用Node.js的Net模块实现一个命令行多人聊天室

    1.net模块基本API 要使用Node.js的net模块实现一个命令行聊天室,就必须先了解NET模块的API使用.NET模块API分为两大类:Server和Socket类.工厂方法. Server类 ...

  3. Node.js:进程、子进程与cluster多核处理模块

    1.process对象 process对象就是处理与进程相关信息的全局对象,不需要require引用,且是EventEmitter的实例. 获取进程信息 process对象提供了很多的API来获取当前 ...

  4. Node.js:理解stream

    Stream在node.js中是一个抽象的接口,基于EventEmitter,也是一种Buffer的高级封装,用来处理流数据.流模块便是提供各种API让我们可以很简单的使用Stream. 流分为四种类 ...

  5. Node.js:Buffer浅谈

    Javascript在客户端对于unicode编码的数据操作支持非常友好,但是对二进制数据的处理就不尽人意.Node.js为了能够处理二进制数据或非unicode编码的数据,便设计了Buffer类,该 ...

  6. node.js学习(二)--Node.js控制台(REPL)&&Node.js的基础和语法

    1.1.2 Node.js控制台(REPL) Node.js也有自己的虚拟的运行环境:REPL. 我们可以使用它来执行任何的Node.js或者javascript代码.还可以引入模块和使用文件系统. ...

  7. Node.js npm 详解

    一.npm简介 安装npm请阅读我之前的文章Hello Node中npm安装那一部分,不过只介绍了linux平台,如果是其它平台,有前辈写了更加详细的介绍. npm的全称:Node Package M ...

  8. Node.js入门(一)

    一.Node.js本质上是js的运行环境. 二.可以解析js代码(没有浏览器安全级的限制): 提供系统级的API:1.文件的读写 2.进程的管理 3.网络通信 三.可以关注的四个网站: 1.https ...

  9. Node.js学习笔记——Node.js开发Web后台服务

    一.简介 Node.js 是一个基于Google Chrome V8 引擎的 JavaScript 运行环境.Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效.Node.j ...

  10. Node.js入门

    开始之前,安利一本正在看的书<站在两个世界的边缘>,作者程浩,上帝丢给他太多理想,却忘了给他完成理想的时间.OK,有兴趣的可以看一看. node.js如标题一样,我也是刚开始接触,大家一起 ...

随机推荐

  1. 【论文阅读】IROS2017: Voxblox & RAL2019: Voxblox++

    IROS2017: Voxblox & RAL2019: Voxblox++ Status: Finished Type: RAL Year: 2019 组织/Sensor: ETH-ASL ...

  2. 🚀 Karpor - 让 AI 全面赋能 Kubernetes!

    什么是 Karpor? 一言以蔽之,Karpor 是一个现代化的 Kubernetes 可视化工具,核心特性聚焦在  搜索. 洞察. AI ,目标是更方便快捷地连接平台和多集群,并用 AI 赋能 Ku ...

  3. P9376 题解

    首先考虑怎么暴力. 考虑把每个数进行 \(B\) 进制分解,然后我们惊奇的发现这两个操作就是把最低位去掉和往最低位后面插入一个数. 然后我们顺藤摸瓜,把每个数的分解扔到 Trie 树上,我们发现我们要 ...

  4. vue-router 路由模式有几种?

    实际上存在三种模式: Hash:      使用URL的hash值来作为路由.支持所有浏览器. History:   以来HTML5 History API 和服务器配置.参考官网中HTML5 His ...

  5. UML类图的表示

    1.类的表示方法 2.接口的两种表示方法 3.类的继承怎么表示 空心三角形+实线 4.类实现接口 空心三角形+虚线 5.关联(association)关系 实线箭头 6.聚合(aggregation) ...

  6. 「Pygors跨平台GUI」2:安装MinGW-w64、MSYS2还是WSL2

    「Pygors系列」一句话导读: MinGW-w64只有编译器,MSYS2带着更新环境,WSL2实用性比较高 历史与渊源   Windows平台 Linux平台 二进制兼容 WSL2:运行Linux程 ...

  7. MySQL_数据库命名规范及约定

    操作规范 如无说明,建表时一律采用innodb引擎: 如无说明,数据库表编码集(utf8,utf8_bin)ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf ...

  8. 制作KubeVirt镜像

    目录 制作KubeVirt镜像 1. 准备磁盘文件 2. 编写Dockerfile 3. 构建镜像 4. 上传镜像到仓库(可选) 5. 导出镜像 6. 虚拟机yaml文件 7. 启动虚拟机 8. 启动 ...

  9. 免费正版 IntelliJ IDEA license 详细指南

    一.前言 IntelliJ IDEA 一直是我非常喜欢的 IDE 自从用上之后就回不了头了,但是 Ultimate 版本的费用十分昂贵,其实 JetBrains 自己就提供了6种免费申请授权的方式:本 ...

  10. 【Java】Jsoup 解析HTML报告

    一.需求背景 有好几种报告文件,目前是人肉找报告信息填到Excel上生成统计信息 跟用户交流了下需求和提供的几个文件,发现都是html文件 其实所谓的报告的文件,就是一些本地可打开的静态资源,里面也有 ...