最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

手把手教你如何優(yōu)雅的書(shū)寫NestJS服務(wù)配置

 更新時(shí)間:2026年04月03日 08:54:48   作者:Mr_li  
Nest.js是一個(gè)漸進(jìn)的Node.js框架,可以在TypeScript和JavaScript (ES6、ES7、ES8)之上構(gòu)建高效、可伸縮的企業(yè)級(jí)服務(wù)器端應(yīng)用程序,這篇文章主要介紹了如何優(yōu)雅的書(shū)寫NestJS服務(wù)配置的相關(guān)資料,需要的朋友可以參考下

前言

開(kāi)發(fā)服務(wù)端應(yīng)用,配置肯定是少不了的。端口號(hào)、數(shù)據(jù)庫(kù)賬號(hào)、Redis 密碼、各種業(yè)務(wù)白名單……這些東西如果硬編碼在代碼里,不僅不安全,每次切環(huán)境還得改代碼,簡(jiǎn)直是災(zāi)難。

配置的來(lái)源五花八門:簡(jiǎn)單的可以直接讀環(huán)境變量(env),稍微復(fù)雜點(diǎn)的用 JSON、YAML 配置文件,遇到敏感信息或者微服務(wù)架構(gòu),可能還得去 Nacos、Apollo 這樣的遠(yuǎn)端配置中心拉取。

在 NestJS 里,寫配置的方式有很多。如果團(tuán)隊(duì)沒(méi)個(gè)統(tǒng)一的規(guī)范,大家各寫各的,雖然代碼也能跑,但后期維護(hù)起來(lái)絕對(duì)會(huì)讓人抓狂。這幾年再使用 NestJS 過(guò)程中踩了不少坑,摸索出了一套比較舒服的配置管理姿勢(shì),今天就來(lái)系統(tǒng)地梳理一遍。

1. 刀耕火種:直接硬剛 process.env

最原始、最暴力的寫法,就是直接在代碼里讀 process.env

// 這種代碼散落在項(xiàng)目的各個(gè)角落,后期維護(hù)極其痛苦
const port = process.env.PORT || 3000;
const dbHost = process.env.DATABASE_HOST;

這種寫法最大的問(wèn)題是毫無(wú)約束。字段名字全靠腦子記,類型全都是 string | undefined,還得自己手動(dòng)轉(zhuǎn)數(shù)字、轉(zhuǎn)布爾值。哪天要是改個(gè)環(huán)境變量的名字,你得全局搜索一遍才能確認(rèn)是不是都改全了。所以,這只能算是個(gè)起點(diǎn),正經(jīng)項(xiàng)目千萬(wàn)別這么搞。

2. 官方標(biāo)配:@nestjs/config 模塊

為了解決配置問(wèn)題,NestJS 官方提供了一個(gè) @nestjs/config 包。它的底層其實(shí)就是我們熟悉的 dotenv,這也是目前處理配置的標(biāo)準(zhǔn)入口。

先裝個(gè)包(注意:它要求 TypeScript 4.1 及以上版本):

npm i --save @nestjs/config

2.1 怎么用起來(lái)?

最基礎(chǔ)的用法,就是在根模塊 AppModule 里引入 ConfigModule,調(diào)一下 forRoot()。它會(huì)自動(dòng)去項(xiàng)目根目錄找 .env 文件并解析:

// app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true, // 強(qiáng)烈建議設(shè)為全局,這樣其他模塊就不用反復(fù) import 了
    }),
  ],
})
export class AppModule {}

?? 踩坑預(yù)警:當(dāng)系統(tǒng)的環(huán)境變量和 .env 文件里出現(xiàn)了同名的 key 時(shí),系統(tǒng)環(huán)境變量的優(yōu)先級(jí)更高,.env 里的值會(huì)被無(wú)情覆蓋。這是 dotenv 的默認(rèn)規(guī)則,在線上部署排查問(wèn)題時(shí)一定要記住這一點(diǎn)。

設(shè)置了 isGlobal: true 后,你在任何 Service 里都可以直接注入 ConfigService 來(lái)拿配置了。

2.2 應(yīng)對(duì)多環(huán)境

真實(shí)項(xiàng)目肯定不止一個(gè)環(huán)境,起碼有開(kāi)發(fā)(dev)、測(cè)試(staging)、生產(chǎn)(prod)。我們可以傳個(gè)數(shù)組給 envFilePath,讓它按需加載。通常配合 NODE_ENV 動(dòng)態(tài)決定加載哪個(gè)文件:

ConfigModule.forRoot({
  envFilePath: [
    `.env.${process.env.NODE_ENV}.local`, // 優(yōu)先級(jí)最高:本地覆蓋文件
    `.env.${process.env.NODE_ENV}`,        // 當(dāng)前環(huán)境配置
    '.env',                                // 兜底默認(rèn)配置
  ],
  isGlobal: true,
});

?? 踩坑預(yù)警:數(shù)組里越靠前的文件優(yōu)先級(jí)越高。如果幾個(gè)文件里有相同的 key,它只會(huì)認(rèn)第一個(gè)找到的值,后面的文件里重復(fù)的 key 會(huì)被靜默忽略。

3. 進(jìn)階:把"散裝字符串"變成結(jié)構(gòu)化對(duì)象

只用 .env 有個(gè)很煩人的點(diǎn):讀出來(lái)的全是一層扁平的字符串。如果配置一多,找起來(lái)費(fèi)勁,而且到處都要寫 parseInt。

NestJS 允許我們寫配置工廠函數(shù),把這些零散的環(huán)境變量組裝成有結(jié)構(gòu)、有類型、有默認(rèn)值的對(duì)象。

// config/database.config.ts
export default () => ({
  port: parseInt(process.env.PORT, 10) || 3000,
  database: {
    host: process.env.DATABASE_HOST || 'localhost',
    port: parseInt(process.env.DATABASE_PORT, 10) || 5432,
    user: process.env.DATABASE_USER,
    password: process.env.DATABASE_PASSWORD,
  },
});

然后在 AppModule 里通過(guò) load 屬性把這個(gè)工廠函數(shù)塞進(jìn)去:

import databaseConfig from './config/database.config';
ConfigModule.forRoot({
  isGlobal: true,
  load: [databaseConfig], // 這里是個(gè)數(shù)組,可以塞多個(gè)配置進(jìn)去,互不干擾
});

用的時(shí)候,就可以用點(diǎn)號(hào)(.)來(lái)讀取嵌套屬性了:

const dbHost = this.configService.get<string>('database.host');
const dbPort = this.configService.get<number>('database.port');

這比到處散落的 process.env.DATABASE_HOST 好多了,至少做到了集中管理。但這種寫法還有個(gè)問(wèn)題:字符串路徑 'database.host' 沒(méi)有類型提示,寫錯(cuò)了只能靠運(yùn)行時(shí)暴露。下面這個(gè)方案才是真正的終極解法。

4. 終極利器:命名空間(Namespace)

registerAs() 函數(shù)是 @nestjs/config 里最值得推薦的功能。它不只是給配置起個(gè)名字,更重要的是它返回的對(duì)象帶有 .KEY 屬性,可以直接用于依賴注入——這意味著你可以注入整個(gè)配置對(duì)象,而不是一個(gè)個(gè)字符串地去 get()。

4.1 劃分命名空間

把不同業(yè)務(wù)的配置拆到各自的文件里:

// config/database.config.ts
import { registerAs } from '@nestjs/config';
export default registerAs('database', () => ({
  host: process.env.DATABASE_HOST || 'localhost',
  port: parseInt(process.env.DATABASE_PORT, 10) || 5432,
  name: process.env.DATABASE_NAME,
}));
// config/redis.config.ts
import { registerAs } from '@nestjs/config';
export default registerAs('redis', () => ({
  host: process.env.REDIS_HOST || 'localhost',
  port: parseInt(process.env.REDIS_PORT, 10) || 6379,
}));

然后在根模塊統(tǒng)一加載:

ConfigModule.forRoot({
  isGlobal: true,
  load: [databaseConfig, redisConfig],
});

4.2 享受強(qiáng)類型的快感

用了命名空間后,可以直接注入整個(gè)配置對(duì)象,TypeScript 類型推導(dǎo)完整,IDE 有完整提示,字段名寫錯(cuò)了編譯階段就報(bào)錯(cuò):

import { Inject, Injectable } from '@nestjs/common';
import { ConfigType } from '@nestjs/config';
import databaseConfig from './config/database.config';
@Injectable()
export class DatabaseService {
  constructor(
    @Inject(databaseConfig.KEY)
    private readonly dbConfig: ConfigType<typeof databaseConfig>,
  ) {}
  getConnection() {
    // 敲下 this.dbConfig. 的時(shí)候,IDE 會(huì)完整提示 host, port, name
    return `${this.dbConfig.host}:${this.dbConfig.port}/${this.dbConfig.name}`;
  }
}

?? 小貼士ConfigType<typeof databaseConfig> 是官方提供的工具類型,它能自動(dòng)反推工廠函數(shù)的返回值結(jié)構(gòu),省得你再去手寫一遍 Interface。

4.3 絲滑對(duì)接第三方模塊

命名空間配置還有個(gè)殺手锏:.asProvider() 方法。

平時(shí)配置 TypeORM 或 Redis 這類第三方模塊時(shí),往往要寫一長(zhǎng)串 useFactory、inject、imports。用了 .asProvider() 后,這些樣板代碼全部省掉——它的本質(zhì)是把依賴聲明和工廠函數(shù)打包成了標(biāo)準(zhǔn)的 forRootAsync 入?yún)?,NestJS 會(huì)據(jù)此建立正確的模塊初始化順序:

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true, load: [databaseConfig] }),
    // 等價(jià)于手寫 imports/inject/useFactory 的完整異步配置
    TypeOrmModule.forRootAsync(databaseConfig.asProvider()),
  ],
})
export class AppModule {}

關(guān)于為什么這能保證初始化順序,以及手寫 useFactory 時(shí)要注意什么,我們?cè)诘?7.2 節(jié)會(huì)展開(kāi)說(shuō)。

5. 換個(gè)口味:YAML、JSON 怎么搞?

.env 用起來(lái)最順手,但它有個(gè)天然的短板:所有值讀出來(lái)都是字符串,端口、超時(shí)時(shí)間這些數(shù)字都得自己手動(dòng) parseInt,布爾值也要寫 === 'true' 來(lái)判斷,一不小心就出錯(cuò)。

相比之下,YAML 和 JSON 本身就支持?jǐn)?shù)字、布爾等原生類型,寫配置的時(shí)候是什么類型讀出來(lái)還是什么類型,完全不需要轉(zhuǎn)換。而且層級(jí)結(jié)構(gòu)更清晰,改起來(lái)更直觀,后期維護(hù)成本也低得多。如果項(xiàng)目的配置項(xiàng)比較多,主動(dòng)選擇 YAML 或 JSON 來(lái)管理是個(gè)很合理的決定。

@nestjs/configload 機(jī)制非常靈活,只要你的工廠函數(shù)最終返回一個(gè)普通對(duì)象,它才不管數(shù)據(jù)是從哪來(lái)的。

5.1 玩轉(zhuǎn) YAML

先裝解析庫(kù):npm i js-yamlnpm i -D @types/js-yaml

// config/yaml.config.ts
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import * as yaml from 'js-yaml';
export default () => {
  return yaml.load(
    readFileSync(join(__dirname, 'config.yaml'), 'utf8'),
  ) as Record<string, any>;
};

?? 踩坑預(yù)警:Nest CLI 默認(rèn)打包時(shí)不會(huì)拷貝非 TS 文件。如果你用了 YAML,一定要去 nest-cli.json 里配置 assets,不然打完包跑起來(lái)絕對(duì)報(bào)找不到文件的錯(cuò)。

{
  "compilerOptions": {
    "assets": [{ "include": "../config/*.yaml", "outDir": "./dist/config" }]
  }
}

5.2 遠(yuǎn)端配置中心(如 Nacos、Apollo)

如果你們用了配置中心,最常見(jiàn)的有兩種接入方式:

方式一:CD 流程在容器啟動(dòng)前下發(fā)配置文件,把配置寫到本地磁盤,應(yīng)用啟動(dòng)時(shí)當(dāng)普通本地文件讀,和 5.1 的 YAML 方式一模一樣,沒(méi)有額外復(fù)雜度。

方式二:應(yīng)用啟動(dòng)時(shí)主動(dòng)拉取,把工廠函數(shù)寫成異步的,在 ConfigModule 初始化期間完成拉?。?/p>

import { registerAs } from '@nestjs/config';
export default registerAs('secret', async () => {
  // 去遠(yuǎn)端拉配置,拉不到就拋異常,阻止應(yīng)用啟動(dòng)
  const data = await fetchFromConfigCenter('/api/config/secret');
  return { apiKey: data.apiKey, jwtSecret: data.jwtSecret };
});

兩種方式的選擇取決于你們的部署流程,不存在好壞之分。

6. 防患未然:配置校驗(yàn)

沒(méi)有校驗(yàn)的配置就像是一顆定時(shí)炸彈。萬(wàn)一線上環(huán)境少配了一個(gè)數(shù)據(jù)庫(kù)密碼,應(yīng)用可能照樣啟動(dòng),直到用戶發(fā)起請(qǐng)求才原地爆炸。

我們必須讓應(yīng)用在啟動(dòng)階段就把缺少的配置暴露出來(lái)。NestJS 給了兩套方案:

6.1 簡(jiǎn)單粗暴的 Joi 校驗(yàn)

import * as Joi from 'joi';
ConfigModule.forRoot({
  validationSchema: Joi.object({
    NODE_ENV: Joi.string().valid('dev', 'prod').default('dev'),
    PORT: Joi.number().default(3000),
    DATABASE_HOST: Joi.string().required(), // 必填項(xiàng),沒(méi)有就不準(zhǔn)啟動(dòng)!
  }),
  validationOptions: {
    allowUnknown: true,  // 允許出現(xiàn)沒(méi)在 schema 里定義的變量
    abortEarly: false,   // 別一遇到錯(cuò)就停,把所有錯(cuò)一塊報(bào)出來(lái)
  },
});

?? 踩坑預(yù)警:如果你傳了 validationOptions,那些沒(méi)寫的選項(xiàng)會(huì)回退到 Joi 的默認(rèn)值,而不是 @nestjs/config 的默認(rèn)值!比如 allowUnknown,Joi 默認(rèn)是 false,但 Nest 默認(rèn)是 true。為了不被坑,建議把這倆屬性老老實(shí)實(shí)寫清楚。

6.2 面向?qū)ο蟮?class-validator

如果你更喜歡用類和裝飾器,也可以自己寫個(gè)校驗(yàn)函數(shù):

import { plainToInstance } from 'class-transformer';
import { IsNumber, IsString, validateSync } from 'class-validator';
class EnvVariables {
  @IsNumber() PORT: number;
  @IsString() DATABASE_HOST: string;
}
export function validate(config: Record<string, unknown>) {
  const validated = plainToInstance(EnvVariables, config, { enableImplicitConversion: true });
  const errors = validateSync(validated, { skipMissingProperties: false });
  if (errors.length > 0) throw new Error(errors.toString());
  return validated;
}
// app.module.ts
ConfigModule.forRoot({ validate });

兩種校驗(yàn)方式效果相同,Joi 更簡(jiǎn)潔,class-validator 在項(xiàng)目里已經(jīng)有 DTO 校驗(yàn)體系時(shí)風(fēng)格更統(tǒng)一,按喜好選就行。

7. 特殊場(chǎng)景

7.1 局部注冊(cè)(forFeature)的生命周期坑

如果你的項(xiàng)目比較大,不想把所有配置都塞在 AppModule 里,可以在各自的業(yè)務(wù)模塊里按需加載:

@Module({
  imports: [ConfigModule.forFeature(databaseConfig)],
})
export class DatabaseModule {}

?? 踩坑預(yù)警:用 forFeature 注冊(cè)的配置,千萬(wàn)別在構(gòu)造函數(shù)(constructor)里去讀!因?yàn)槟K初始化的順序是不確定的,這時(shí)候配置可能還沒(méi)加載完。正確的做法是用屬性注入,然后在 onModuleInit 生命周期鉤子里讀取。

import { Inject, Injectable, OnModuleInit } from '@nestjs/common';
import { ConfigType } from '@nestjs/config';
import databaseConfig from './database.config';
@Injectable()
export class DatabaseService implements OnModuleInit {
  // 屬性注入,不在構(gòu)造函數(shù)里觸碰配置
  @Inject(databaseConfig.KEY)
  private readonly dbConfig: ConfigType<typeof databaseConfig>;
  onModuleInit() {
    // ? 到這里所有依賴模塊都已初始化完畢,安全讀取
    console.log('db host:', this.dbConfig.host);
  }
  // ? 下面這種寫法會(huì)在某些場(chǎng)景下讀到 undefined
  // constructor(
  //   @Inject(databaseConfig.KEY)
  //   private readonly dbConfig: ConfigType<typeof databaseConfig>,
  // ) {
  //   console.log(this.dbConfig.host); // 危險(xiǎn)!配置可能還沒(méi)就緒
  // }
}

7.2 配置之間的依賴鏈問(wèn)題

這是一個(gè)很容易被忽略但實(shí)際開(kāi)發(fā)中會(huì)真實(shí)踩到的坑。

以 TypeORM 為例,完整的啟動(dòng)依賴鏈?zhǔn)沁@樣的:

ConfigModule 加載 .env / 配置文件
       ↓
databaseConfig 工廠函數(shù)讀取環(huán)境變量,生成配置對(duì)象
       ↓
TypeOrmModule 拿到配置,建立數(shù)據(jù)庫(kù)連接池
       ↓
各業(yè)務(wù) Service / Repository 可以正常使用
       ↓
應(yīng)用啟動(dòng)完成,開(kāi)始接受請(qǐng)求

這條鏈上的順序必須是確定的。如果配置還沒(méi)就緒,TypeOrmModule 就開(kāi)始初始化,輕則連接參數(shù)是 undefined,重則應(yīng)用直接起不來(lái)。

第 4.3 節(jié)提到的 .asProvider() 能自動(dòng)保證這個(gè)順序,因?yàn)樗归_(kāi)后等價(jià)于:

{
  imports: [ConfigModule.forFeature(databaseConfig)], // 聲明:我依賴這個(gè)配置
  useFactory: (config: ConfigType<typeof databaseConfig>) => config,
  inject: [databaseConfig.KEY],
}

imports 字段就是向 NestJS 聲明依賴關(guān)系的地方??蚣芸吹竭@個(gè)聲明,就會(huì)等 databaseConfig 就緒后再初始化 TypeOrmModule,順序由框架保證,不需要你操心。

如果不用 .asProvider(),自己手寫 useFactory一定要記得寫 imports,不然就是在賭運(yùn)氣:

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],   // ← 必須寫!告訴框架:等 ConfigModule 好了再來(lái)初始化我
  inject: [ConfigService],
  useFactory: (configService: ConfigService) => ({
    type: 'mysql',
    host: configService.get<string>('database.host'),
    port: configService.get<number>('database.port'),
    // ...
  }),
}),

還有一個(gè)更細(xì)的場(chǎng)景:兩個(gè)配置文件之間能互相依賴嗎?比如 databaseConfig 想引用 appConfig 里的某個(gè)值。答案是不行@nestjs/config 不支持配置工廠之間的注入。正確的做法是所有工廠函數(shù)都平級(jí)地從 process.env 取原始值,誰(shuí)需要哪個(gè)環(huán)境變量就自己讀,不要試圖跨工廠函數(shù)共享:

// ? 錯(cuò)誤:試圖在配置工廠里引用另一個(gè)配置對(duì)象
export default registerAs('database', () => {
  const appConfig = someHowGetAppConfig(); // 根本不存在這種 API
  return { host: appConfig.defaultHost };
});
// ? 正確:直接從 process.env 取,各配置工廠平級(jí)獨(dú)立
export default registerAs('database', () => ({
  host: process.env.APP_DEFAULT_HOST || 'localhost',
}));

7.3 在 main.ts 里怎么拿配置?

像監(jiān)聽(tīng)端口、CORS 域名這種配置,在 main.ts 里就要用到,這時(shí)候可以通過(guò) app.get() 拿到 ConfigService 實(shí)例:

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const configService = app.get(ConfigService);
  const port = configService.get<number>('PORT') ?? 3000;
  await app.listen(port);
}

8. 總結(jié):到底該怎么選?

寫了這么多,咱們來(lái)拉個(gè)表對(duì)比一下:

姿勢(shì)類型安全結(jié)構(gòu)化評(píng)價(jià)
直接硬剛 process.env? 純盲寫? 扁平適合寫完就扔的臨時(shí)腳本
ConfigModule + .env弱(全靠泛型強(qiáng)轉(zhuǎn))? 扁平適合小型項(xiàng)目快速起步
自定義工廠函數(shù)?(需手寫類型)? 嵌套對(duì)象中規(guī)中矩,能處理默認(rèn)值和類型轉(zhuǎn)換
registerAs() 命名空間??(全自動(dòng)推導(dǎo))? 按業(yè)務(wù)隔離強(qiáng)烈推薦!中大型項(xiàng)目的標(biāo)準(zhǔn)答案

?? 個(gè)人最推薦的實(shí)戰(zhàn)組合: registerAs() 命名空間 + isGlobal: true + 啟動(dòng)時(shí) Joi 強(qiáng)校驗(yàn)。

這套組合的核心邏輯是:配置在哪定義,就在哪描述它的結(jié)構(gòu);業(yè)務(wù)代碼只管用,根本不需要關(guān)心底層到底是 .env 還是 YAML。 這樣哪怕以后要把配置遷移到云端,業(yè)務(wù)代碼也一行都不用改,這才叫真正的優(yōu)雅。

到此這篇關(guān)于如何優(yōu)雅的書(shū)寫NestJS服務(wù)配置的文章就介紹到這了,更多相關(guān)NestJS服務(wù)配置內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于NodeJS開(kāi)發(fā)釘釘回調(diào)接口實(shí)現(xiàn)AES-CBC加解密

    基于NodeJS開(kāi)發(fā)釘釘回調(diào)接口實(shí)現(xiàn)AES-CBC加解密

    這篇文章主要介紹了基于NodeJS開(kāi)發(fā)釘釘回調(diào)接口 實(shí)現(xiàn)AES-CBC加解密,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • package.json中overrides用法示例詳解

    package.json中overrides用法示例詳解

    在前端開(kāi)發(fā)中,package.json和package-lock.json是兩個(gè)經(jīng)常打交道的文件,這篇文章主要介紹了package.json中overrides用法的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2026-02-02
  • Node.js?實(shí)現(xiàn)簡(jiǎn)單爬蟲(chóng)的示例代碼

    Node.js?實(shí)現(xiàn)簡(jiǎn)單爬蟲(chóng)的示例代碼

    本文主要介紹了Node.js?實(shí)現(xiàn)簡(jiǎn)單爬蟲(chóng),爬取美食網(wǎng)站的菜品標(biāo)題和圖片鏈接,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-02-02
  • node.js express框架實(shí)現(xiàn)文件上傳與下載功能實(shí)例詳解

    node.js express框架實(shí)現(xiàn)文件上傳與下載功能實(shí)例詳解

    這篇文章主要介紹了node.js express框架實(shí)現(xiàn)文件上傳與下載功能,結(jié)合具體實(shí)例形式詳細(xì)分析了node.js express框架針對(duì)文件上傳與下載的前后臺(tái)相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2019-10-10
  • 三種Node.js寫文件的方式

    三種Node.js寫文件的方式

    這篇文章主要為大家詳細(xì)介紹了三種Node.js寫文件的方式,感興趣的小伙伴們可以參考一下
    2016-03-03
  • 一文詳解NodeJS和Javascript之間有什么區(qū)別

    一文詳解NodeJS和Javascript之間有什么區(qū)別

    在前端和后端開(kāi)發(fā)的技術(shù)棧中,JavaScript?和?Node.js?經(jīng)常是新手和經(jīng)驗(yàn)豐富的開(kāi)發(fā)者討論的熱門話題,這篇文章主要介紹了NodeJS和Javascript之間有什么區(qū)別的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-11-11
  • Node學(xué)習(xí)筆記:Node.js安裝及環(huán)境配置 史詩(shī)級(jí)詳細(xì)版【含測(cè)試與鏡像說(shuō)明】

    Node學(xué)習(xí)筆記:Node.js安裝及環(huán)境配置 史詩(shī)級(jí)詳細(xì)版【含測(cè)試與鏡像說(shuō)明】

    這篇文章主要介紹了Node學(xué)習(xí)筆記之Node.js安裝及環(huán)境配置方法,詳細(xì)分析了node.js的基本安裝、配置、環(huán)境變量設(shè)置、以及環(huán)境測(cè)試與鏡像使用說(shuō)明,需要的朋友可以參考下
    2023-05-05
  • Node安裝教程&環(huán)境變量配置方式(Window11)

    Node安裝教程&環(huán)境變量配置方式(Window11)

    這篇文章詳細(xì)介紹了如何在Windows 11上安裝和配置Node.js,包括下載、安裝、驗(yàn)證安裝、創(chuàng)建目錄、配置環(huán)境變量、下載驗(yàn)證以及更換淘寶鏡像等步驟
    2026-03-03
  • 在Ubuntu系統(tǒng)上安裝Node.JS的教程

    在Ubuntu系統(tǒng)上安裝Node.JS的教程

    這篇文章主要介紹了在Ubuntu系統(tǒng)上安裝Node.JS的教程,Node.JS的高性能V8解釋器運(yùn)行及異步機(jī)制為其帶來(lái)了巨大的人氣,需要的朋友可以參考下
    2015-10-10
  • nodejs簡(jiǎn)單實(shí)現(xiàn)操作arduino

    nodejs簡(jiǎn)單實(shí)現(xiàn)操作arduino

    本文給大家分享的是使用nodejs來(lái)驅(qū)動(dòng)arduino,主要是基于cylonjs 和 gort,有需要的小伙伴可以參考下
    2016-09-09

最新評(píng)論

松桃| 扶余县| 潼南县| 浪卡子县| 隆德县| 汪清县| 鲁甸县| 含山县| 台东市| 格尔木市| 定陶县| 渑池县| 昭觉县| 开鲁县| 常德市| 浏阳市| 伊川县| 鞍山市| 云龙县| 新巴尔虎右旗| 商丘市| 肥西县| 吴江市| 迁西县| 公主岭市| 昔阳县| 正安县| 忻州市| 松滋市| 垣曲县| 翁源县| 收藏| 白玉县| 广水市| 寿阳县| 永仁县| 凭祥市| 台北市| 香港 | 张北县| 姚安县|