13+ распространенных проблем и решений, возникающих при рассмотрении проектов узлов

Node.js JavaScript
13+ распространенных проблем и решений, возникающих при рассмотрении проектов узлов

Автор последовательно взял на себя несколькоnodejsПроект, также участвовал в нескольких битах среднегоnodejsПроект с открытым исходным кодом, я недавно разобрался с некоторыми проблемами и решениями, встречающимися в нем, дабы не дать всем впредь наступить на яму. Начнем, не говоря об этом~

1. Проблема установки переменной NODE_ENV под windows и mac

Все мы знаем, что во фронтенд-проектах будет обрабатываться разная логика в соответствии с разными переменными окружения.nodejsТочно так же нам нужно установить локальную среду разработки, тестовую среду, онлайн-среду и т. д. В настоящее время существует решение всегда устанавливать переменные среды вpackage.jsonсерединаscriptсвойства следующим образом:

"scripts": {
   "start": "export NODE_ENV=development && nodemon -w src --exec \"babel-node src\"",
   "build": "babel src --out-dir dist",
   "run-build": "node dist",
   "test": "echo \"Error: no test specified\" && exit 1"
 }

отstartВ инструкции мы можем найти, что мы используемexport NODE_ENV=developmentЧтобы определить переменные среды среды разработки, поскольку автор используетmacкомпьютер, такexportопределитьnodeПеременные среды.Но при разработке проекта с другом я обнаружил, что реализацияyarn startОб ошибке будет сообщено позже, и сообщение об ошибке будет найдено позжеwindowне опознаноexport, позже я нашелwindowЧтобы определить переменные среды, вы можете использоватьset, Таким образом, дляwindowпользователя, если вы используете описанный выше метод для установкиNODE_ENV, можно использовать следующим образом:

"scripts": {
   "start": "set NODE_ENV=development && nodemon -w src --exec \"babel-node src\""
 }

2. Проблема ошибки node-gyp при выполнении npm install

В процессе разработки проекта иногда тянуть новыеnodeВыполнить после кода проектаnpm install, сообщит о следующей ошибке: node-gypтолько что вnodeФайлы проекта, используемые в среде для создания разных компиляторов для разных платформ, если вы столкнулись с одной и той же проблемой, мы можем использовать следующие решения:

npm install -g node-gyp

или просто удалитьpackage-lock.jsonилиyarn.lock, а затем повторноyarn installилиnpm installВсе, явный тест автора эффективен.

3. Решение для удаления установленного файла cookie в проекте node + koa2.

Поскольку HTTP является протоколом без сохранения состояния, файлы cookie необходимы для различения пользователей. Мы можем думать о файлах cookie как о спецификации, реализуемой браузером и сервером вместе.

cookieОбработка разделена на следующие три шага (Базовые и важные знания):

  1. Сервер отправляет клиентуcookie
  2. браузер будетcookieСохранить (вы можете установить expires или maxAge в бэкэнде наsessionформа есть)
  3. Каждый раз браузер будет устанавливать ранее установленноеcookieотправить на сервер

в разработкеnodeМы часто включаем модули управления пользователя в фоновых проектах, что означает, что нам нужносостояние входауправление, которое может удалять данные пользователя вовремя, когда пользователь выходит из системыcookie, к счастьюkoa2идет с обработкойcookieметод, мы можем установить его следующим образомcookie:

router.post(api.validVip,
    async ctx => {
      ctx.cookies.set('vid', 'xuxiaoxi', { maxAge: 24 * 3600 * 1000 });
    }
);

Выше мы произвольно установили срок действия 1 день.cookieТогда, если бизнес изменяется, вам нужно очистить этоcookie?, Как мы справляемся с этим дает решения для решения относительно доступных:

ctx.cookies.set('vid', '', { maxAge: 0 });

В это время у клиентаcookieАвтоматически истечет при следующем запросе.

4. Как socket.io работает с koa/egg

мы все знаем полнуюsocket.ioКоммуникация состоит из двух частей:

  1. а такжеNodeJS HTTPСервер интеграции (или установленный на нем)socket.io
  2. Клиентская библиотека загружается на стороне браузераsocket.io-client

Если мы непосредственно используемkoaилиegg, нам нужно интегрировать их внутриhttpа такжеsocket.ioБыть совместимым, мы можем справиться с этим так:

import koa from 'koa';
import http from 'http';

const app = new koa();
const server = http.createServer(app.callback());
const io = require('socket.io')(server);
//  正常的业务处理
// io
io.on('connection', (socket) => {
    console.log('a user connected');
    socket.on('doc load', (msg) => {
      console.log('doc load', msg)
      io.emit('getData', users)
    })
  });

server.listen(3000, () => {
    // ...
});

Вышеуказанным способом нормальнаяkoaа такжеsocket.ioСделай совместимость.Позже можем нормально развиватьсяIMПрименить ~

5. Решение ошибки, вызванной тем, что сторонний модуль nodejs зависит от конкретной версии узла.

Автор и раньше сталкивался с такой ситуацией, основная причина в том, что третья сторона не сотрудничала сnodeВерсия очень обратно совместима, и решение в настоящее время состоит в том, чтобы обновить этот сторонний пакет до последней версии (если он все еще поддерживается) или использоватьnodeИнструмент управления пакетами (n) для перехода на адаптированныйnodeверсии, следующим образом:

// 更新最新的包
npm i xxx@latest

// 使用包管理工具n
npm i -g n

использоватьnМожно легко управлятьnodeверсии, вы можете попробовать, если вам интересно.

6. Как создавать запланированные задачи в nodejs

Запланированные задачи — одна из распространенных функций в бэкенд-разработке, и их суть заключается в следующем.В соответствии с временными правилами система автоматически выполняет соответствующие задачи в фоновом режиме.. существуетjava, PHPСуществует богатая поддержка запланированных задач на фоновых языках, таких какnodejsДля этой восходящей звезды, хотя у нее нет такой зрелой экосистемы, у нее все еще есть модули для задач на время, таких какnode-schedule.

Node Schedule— это гибкий планировщик заданий, похожий на cron и не похожий на cron, для Node.js. Это позволяет нам планировать задания (произвольные функции) для выполнения в определенные даты, используя необязательные правила повторения. Он использует только один таймер в любой момент времени (вместо переоценки предстоящих заданий каждую секунду/минуту).

Очень практичный сценарий состоит в том, что мы хотим, чтобы ежегодный выпуск Double Eleven или Double TwelvenodeПрограмма автоматически захватывает "товарную вату" интернет-бизнеса и отправляет ее в свой почтовый ящик. В это время мы можем использоватьNode ScheduleЧтобы запустить временную задачу для выполнения наших бизнес-операций, многие из авторскихnodeВсе приложения используют схожую модель, если вам интересно, вы можете общаться друг с другом.

что это такоеcronКак насчет планирования в стиле?githubКраткое введение приведено выше:

Таким образом, мы можем написать запланированную задачу следующим образом:

let schedule = require('node-schedule');

let testJob = schedule.scheduleJob('42 * * * *', function(){
  console.log('将在未来的每个时刻的42分时执行此代码, 比如22:42, 23:42');
});

7. Используйте синтаксис импорта, экспорта и декоратора @decorator в проекте nodejs.

мы все знаем сейчасnodejsВерсия достигла версии 14.0+, и поддержка последнего синтаксиса es достаточно хороша, но все еще есть некоторые синтаксисы, которые не поддерживаются, такие как импорт и экспорт модуля es (import, export), декоратор (@decorator) и так далее, на этом этапе мы собираемсяnodeЧтобы использовать эти новые функции в проекте, мы должны использовать инструменты, здесь автор принимаетbabel7Чтобы решить вышеуказанную проблему, выполните следующие действия:

# .babelrc
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "node": "current"
        }
      }
    ]
  ],
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose" : true }]
  ]
}

Нам нужно только создать и записать указанный выше файл в корневой каталог проекта и установитьbabelСоответствующие модули могут быть следующими:

yarn add 
@babel/cli 
@babel/core 
@babel/node 
@babel/plugin-proposal-class-properties 
@babel/plugin-proposal-decorators 
@babel/preset-env

На этом этапе вы можете использовать эти новые синтаксические функции, такие как написание интерфейсных проектов~

8. Элегантно обрабатывать файлы json в nodejs и улучшать производительность чтения и записи json.

дляnodejsНа самом деле, в плане оптимизации можно много говорить, здесь мы в основном говорим о ней.jsonСвязанные решения по оптимизации.Нам нужно оптимизировать с двух сторон, одна из нихjsonПроизводительность чтения и записи файла, в настоящее время мы можем использоватьfast-json-stringifyзначительно улучшитьjsonСкорость чтения и записи, ее суть заключается в обеспечении набораjson-schemaсдерживать, пустьjsonСтруктура становится более упорядоченной, что улучшаетjsonСкорость запроса на чтение. Используйте следующим образом:

const fastJson = require('fast-json-stringify')
const stringify = fastJson({
  title: 'H5 Dooring Schema',
  type: 'object',
  properties: {
    firstName: {
      type: 'string'
    },
    lastName: {
      type: 'string'
    },
    age: {
      description: 'Age in years',
      type: 'integer'
    },
    reg: {
      type: 'string'
    }
  }
})

например вH5-DooringВ фоновом режиме есть много необходимости часто читать и писатьjsonИнтерфейс данных, используйте на этот разfast-json-stringifyПроизводительность чтения и записи будет значительно улучшена.

С другой стороны, мыnodeБыло бы очень хлопотно использовать нативный способ написания json в конце, в этот раз нам лучше инкапсулировать чтение json, чтобы упростить код, или мы напрямую используем стороннюю библиотеку.jsonfileлегко читать и писатьjsonфайла, следующие варианты использования:

const json = require('jsonfile')
const fileName = 'h5-dooring.json'
const jsonData = jsonFile.readFileSync(fileName)

9. Решение Nodejs для чтения больших файлов

существуетnodejsМы можем использовать два способа чтения и записи файлов, а именно:

  1. fs.readFile()Считайте файл в память за один раз, если файл слишком большой, это вызоветnodeНедостаточно памяти и ошибка
  2. fs.createReadStream()Чтение в виде файлового потока, в настоящее время вам не нужно беспокоиться о размере файла.

Из приведенного выше введения видно, что если файл, который мы хотим прочитать, может быть очень большим (например, видео и другие большие файлы), мы будем использовать его в начале.fs.createReadStream(), на самом деле, если нам нужно разобрать файл, например, разобрать резюме и другие файлы построчно для извлечения корпуса ключей, мы можем использоватьnodeизreadlinemodule, в этот момент мы можем читать и анализировать файл построчно, как в следующем случае:

const fs = require("fs");
const path = require("path");
const readline = require("readline");

const readlineTask = readline.createInterface({
    input: fs.createReadStream(path.join(__dirname, './h5-dooring')),
});
 
readlineTask.on('line', function(chunk) {
  // 读取每一行数据
});
 
readlineTask.on('close', function() {
  //文件读取结束的逻辑
}

10. Как nodejs позволяет gzip оптимизировать производительность веб-сайта

дляnodejsвключиgzipОперация также является частью оптимизации производительности узла, после такой обработки наш сайт может загружаться быстрее, мы можем использоватьkoaизkoa-compressпромежуточное ПО для реализацииgzipФункция Конкретная реализация выглядит следующим образом:

import koa from 'koa';
import compress from 'koa-compress';

const app = new koa();
// 开启gzip
const options = { threshold: 2048 };
app.use(compress(options));

Конечноkoa-compressТакже есть много настраиваемых элементов конфигурации, это чувствуется.

11. Решить проблему несовместимости разделителей путей в системах Windows и Linux.

Эта проблема также вызвана различиями между системами, и это также проблема, которую необходимо учитывать, мы все знаем, что вlinuxРазделитель пути под системой/, Напримерh5-dooring/src/pages, Но когдаwindowСледующий анализ может бытьh5-dooring\\src\\pagesДля такого пути нам нужно адаптироваться в это время, иначе нам неизбежно будет развертываться в разных системах и сообщать об ошибках, поэтому нам нужно настроить подстановочный знак пути глобально.Решение автора выглядит следующим образом:

import os from 'os'
const _$ = (os.platform().toLowerCase() === 'win32') ? '\\' : '/';

На этом этапе, когда задействованы определенные пути, мы используем_$Вместо этого мы использовали приведенный выше кодnodeизosмодуль, желающие могут изучить его, мы можем использоватьosМодули решают множество интересных проблем из-за системных различий.

12. Как nodejs реализует связь между родительскими и дочерними процессами

из-заnodejsОн однопоточный, но иногда нам нужно поддерживать бизнес обработки нескольких процессов, в настоящее времяnodejsМногопроцессность может быть смоделирована в режиме родительско-дочернего процесса, мы можем использоватьchild_processПримерный процесс выглядит следующим образом:Я поделился многимnodeПрактические проекты принятыchild_process, общий процесс реализации выглядит следующим образом:

// child.js
function computedTotal(arr, cb) {
    // 耗时计算任务
}

// 与主进程通信
// 监听主进程信号
process.on('message', (msg) => {
  computedTotal(bigDataArr, (flag) => {
    // 向主进程发送完成信号
    process.send(flag);
  })
});

// main.js
const { fork } = require('child_process');

app.use(async (ctx, next) => {
  if(ctx.url === '/fetch') {
    const data = ctx.request.body;
    // 通知子进程开始执行任务,并传入数据
    const res = await createPromisefork('./child.js', data)
  }
  
  // 创建异步线程
  function createPromisefork(childUrl, data) {
    // 加载子进程
    const res = fork(childUrl)
    // 通知子进程开始work
    data && res.send(data)
    return new Promise(reslove => {
        res.on('message', f => {
            reslove(f)
        })
    })  
  }
  
  await next()
})

13. Редактирование/сжатие изображений на стороне узла

Редактирование и сжатие изображений распространены во многих сценариях с использованием интерфейсных технологий.nodeТак же есть много картинок, которые нужно обрабатывать на стороне клиента.Ведь качество обработки на стороне клиента контролировать непросто.На данный момент мы можем использоватьnode-images, онnodeЛегкая кроссплатформенная библиотека кодеков изображений сбоку, ее основные функции заключаются в следующем:

  • легкий: Нет необходимости устанавливать какую-либо библиотеку обработки изображений.
  • Кроссплатформенность: Скомпилированный файл .node выпускается под Windows, и его можно использовать после загрузки.
  • Простой в использовании: API в стиле JQuery, простая зависимость

Мы можем использовать его для обрезки и сжатия изображений, основное использование заключается в следующем:

const images = require("images");

images("input.jpg")                     //加载图像文件                            
  .size(400)                          //等比缩放图像到400像素宽
     .draw(images("logo.png"), 10, 10)   //在(10,10)处绘制Logo
       .save("output.jpg", {             //保存图片到文件,图片质量为50
        quality : 50                    
       });

существуетH5-DooringВ редакторе вы также используете его для обработки и редактирования изображений, а также можете использовать его в соответствии с вашим реальным бизнесом.

14. Сторона узла анализирует «командную строку командной строки» для автоматической упаковки и развертывания проекта в Интернете.

оnodeРазобратьcmdПеред строкой и выполните то, как я командную строку в письменной формеВнедрите автоматизированный рабочий процесс самостоятельноТакже в статье представлено использованиеchild_processмодульныйexec, конкретная реализация может относиться к статье:

Создайте автоматизированный онлайн-процесс упаковки с нуля на основе NodeJS (H5-Dooring Special Edition).

Напишите простой пример здесь:

const cmdStr = `cd ${outWorkDir} && yarn build ${fid}`
// 解析命令行指令, 实现线上自动打包构建项目
exec(cmdStr, function(err, stdout, stderr){
  if(err) {
    console.log('api error:'+stderr);
    io.emit('htmlWorked', { result: 'error', message: stderr })
  } else {
    // ...
  }
})

15. Как решить проблему сбоя приложения узла, балансировки нагрузки и управления процессами

Лучший способ решить эту проблему — использоватьpm2илиforever, что обеспечивает мощныйnodeУправление процессами, возможности балансировки нагрузки и определенный уровень мониторинга приложений рекомендуется использовать в онлайн-среде.pm2управлять нашимnodeзаявление.

найти его полезным? Добавьте в избранное, если вам это нравится, и, кстати, поставьте лайк Ваша поддержка - моя самая большая поддержка! Поиск в WeChat »Интересный разговор о фронтенде», откройте для себя больше интересных игр H5, webpack, node, gulp, css3, javascript, nodeJS, визуализацию данных на холсте и другие интерфейсные знания и реальный бой.