>  기사  >  웹 프론트엔드  >  2017년에 더 나은 노드 개발자가 되기 위한 10가지 팁

2017년에 더 나은 노드 개발자가 되기 위한 10가지 팁

阿神
阿神원래의
2017-01-24 11:40:351078검색

아래에는 2017년에 더 나은 Node 개발자가 되는 데 도움이 될 수 있는 10가지 제안 사항이 나와 있습니다. 이 조언 중 일부는 제가 일상 업무에서 배운 내용이고, 일부는 가장 인기 있는 Node 및 npm 모듈을 작성한 사람들로부터 배운 것입니다. 우리가 다룰 내용은 다음과 같습니다.

1. 복잡함 방지 — 코드 블록을 가능한 한 가장 작은 크기로 분할하세요.

2. 비동기 프로그래밍 사용 — 전염병과 같은 동기 코드를 피하세요.

3.require 차단 방지 — require는 동기식이며 코드 실행을 차단하므로 모든 require 문을 파일 상단에 배치하세요.

4.필요 캐시 이해 — 알고 있으면 활용할 수 있고, 그렇지 않으면 버그가 발생할 수 있습니다.

5.항상 오류를 확인하세요 — 오류는 축구가 아니며, 언제든지 오류를 던지거나 오류 검사를 건너뛰지 않습니다.

6.동기 코드에서는 try...catch만 사용하세요 — try...catch는 비동기 코드에서는 효과가 없습니다. V8 엔진은 try...catch에 최적화될 수 없습니다.

7.콜백을 반환하거나 if ... else 사용 — 실행이 계속되지 않도록 콜백을 반환합니다.

8.오류 이벤트 듣기 — 거의 모든 노드 클래스/객체에는 이벤트 방출기(관찰자 모드)가 있으며 오류 이벤트를 브로드캐스팅하므로 꼭 들어보세요.

9.npm을 알아보세요 — 모듈을 설치하려면 --save 또는 --save-dev` 대신 -S 또는 -D를 사용하세요.

10.package.json에서 정확한 버전 번호 사용: npm은 -S를 사용하여 모듈을 설치할 때 자동으로 기본 버전 번호를 사용합니다. 버전 번호. 오픈 소스 모듈이 아니라면 프로젝트에서 SemVer(Semantic Versioning Standard)를 신뢰하지 마십시오.

11. 보너스 포인트 — 다양한 종속성을 사용합니다. 개발 단계에서 프로젝트에 필요한 사항을 devDependency에 넣고 npm i --production을 사용하는 것을 잊지 마세요. 중복된 종속성이 많을수록 문제가 발생할 위험이 커집니다.

자, 위의 내용을 하나씩 이해해 보도록 하겠습니다.


복잡함을 피하세요

한 번 살펴보겠습니다. npm use-strict의 작성자인 Isaac Z. Schlueter가 작성한 일부 모듈은 Javascript에서 엄격 모드를 강제로 사용하는 데 사용됩니다. 이 모듈에는

var module = require('module')
module.wrapper[0] += '"use strict";'
Object.freeze(module.wrap)
그렇다면 복잡성을 피해야 하는 이유는 무엇입니까? 미 해군에서 유래한 유명한 문구: KEEP IT SIMPLE STUPID(또는 "Keep it simple, stupid"). 그렇기 때문에. 인간의 두뇌는 작업 기억에 한 번에 5~7개의 항목만 저장할 수 있는 것으로 나타났습니다.

코드를 작은 조각으로 모듈화하면 귀하와 다른 개발자가 코드를 더 잘 이해할 수 있습니다. 더 잘 테스트할 수도 있습니다. 예를 들어,

app.use(function(req, res, next) {
  if (req.session.admin === true) return next()
  else return next(new Error('Not authorized'))
}, function(req, res, next) {
  req.db = db
  next()
})

또는

const auth = require('./middleware/auth.js')
const db = require('./middleware/db.js')(db)

app.use(auth, db)

는 특히 이름만 봐도 그 기능을 알 수 있기 때문에 대부분의 사람들이 두 번째 예를 좋아할 것이라고 믿습니다. 예전에는 코드를 작성할 때 코드가 어떻게 작동하는지 알고 있다고 생각했을 것입니다. 또는 여러 기능을 동일한 라인에 함께 연결하여 얼마나 영리한지 보여주고 싶을 수도 있습니다. 그러나 당신은 어리석은 코드를 작성하고 있습니다. 이 코드를 작성하는 것이 매우 복잡하게 생각된다면, 나중에 이 코드를 볼 때 이해하기 어려울 것입니다. 특히 Node의 비동기 코드에서 코드를 단순하게 유지하세요.

물론 왼쪽 패드 이벤트도 있겠지만 실제로는 왼쪽 패드 모듈에 의존하는 프로젝트에만 영향을 미치고 11분 후에 교체품이 출시되었습니다. 코드 최소화의 이점은 단점보다 큽니다. npm은 릴리스 정책을 변경했으며 모든 심각한 프로젝트는 캐시된 저장소나 개인 저장소를 (임시 솔루션으로) 사용해야 합니다.


비동기 프로그래밍 사용

Node Just에서 코드 동기화 작은 부분. 이 코드의 대부분은 웹 애플리케이션과 관련이 없는 명령줄 도구나 기타 스크립트용입니다. 대부분의 Node 개발자는 웹 애플리케이션을 작성하므로 비동기 코드를 사용하면 장면 차단을 피할 수 있습니다.

예를 들어 데이터베이스 스크립트를 작성하거나 병렬 처리를 제어할 필요가 없는 작업을 작성할 때 다음과 같이 작성해도 괜찮을 수 있습니다.

let data = fs.readFileSync('./acconts.json')
db.collection('accounts').insert(data, (results))=>{
  fs.writeFileSync('./accountIDs.json', results, ()=>{process.exit(1)})
})

그러나 웹 애플리케이션을 생성할 때는 다음이 더 좋을 것 같습니다:

app.use('/seed/:name', (req, res) => {
  let data = fs.readFile(`./${req.params.name}.json`, ()=>{
    db.collection(req.params.name).insert(data, (results))=>{
      fs.writeFile(`./${req.params.name}IDs.json`, results, ()={res.status(201).send()})
    })
  })
})

동시(보통 장기 실행) 시스템을 작성해야 하는지 아니면 비동시(단기 실행) 시스템을 작성해야 하는지의 차이점이 있습니다. 경험상 Node.js에서는 항상 비동기 코드를 사용하는 것이 좋습니다.


요구 차단 방지

노드에 용도 A가 있습니다. CommonJS 모듈 형식을 위한 간단한 모듈 로딩 시스템입니다. 이는 다양한 파일에 모듈을 쉽게 도입할 수 있는 require 기능을 기반으로 합니다. AMD/requirejs와 달리 Node/CommonJS 모듈은 동기적으로 로드됩니다. require가 작동하는 방식은 모듈의 내용이나 파일 내보내기를 소개하는 것입니다.

`const react = require('react')`

但是大多数的开发者并不知道require是会被缓存的。因此,只要解析的文件名(resolved filename)没有剧烈的变化(比如npm模块不存在的情况),模块的代码只会被执行并存入变量中一次(在当前进程中)。这是一个很好的优化。当然,即使有了缓存,你最好还是把你的require声明写在开头。下面这段代码,它在路由中真正使用到了axios模块的时候才加载。当请求发送的时候/connect会因为需要加载模块所以会变得慢。

app.post('/connect', (req, res) => {
  const axios = require('axios')
  axios.post('/api/authorize', req.body.auth)
    .then((response)=>res.send(response))})

一个更好,性能更优的方式是在服务定义之前就引入模块而不是在路由中:

const axios = require('axios')
const express = require('express')
app = express()
app.post('/connect', (req, res) => {
  axios.post('/api/authorize', req.body.auth)
    .then((response)=>res.send(response))
})


知道require会被缓存

我在上面一节已经提到了require会被缓存,但是有趣的是我们在module.exports之外也会有代码。举例来说:

console.log('I will not be cached and only run once, the first time')

module.exports = () => {
  console.log('I will be cached and will run every time this module is invoked')
}

从中我们了解到有一些代码只会运行一次,你可以使用这个特性来优化你的代码。


始终检查错误

Node不是Java。在Java中,你可以抛出错误,因为如果发生了错误那么你会希望应用不在继续执行。在Java中,你可以在外层仅仅使用一个简单的try...catch就可以处理多个错误。

但是在Node中并不是这样的。自从Node使用了事件循环和异步执行后,任何的错误发生时都会与错误处理器(例如try...catch)的上下文分离,下面这样做在Node中是没有用的:

try {
  request.get('/accounts', (error, response)=>{
    data = JSON.parse(response)
  })
} catch(error) {
  // Will NOT be called
  console.error(error)
}

但是try...catch在同步代码中是可以被用的。前面的代码片段可以被更好的重构为:

request.get('/accounts', (error, response)=>{
  try {
    data = JSON.parse(response)
  } catch(error) {
    // Will be called
    console.error(error)
  }
})

如果我们无法将request的返回内容包裹在try...catch中,那么我们将没有办法去处理请求的错误。Node的开发者通过在返回的参数里面加上error来解决了这个问题。因此,我们需要在每一个回调中手动去处理错误。你可以去检查这些错误(判断error不是null),然后展示错误信息给用户或者展示在客户端上并且记录它, 或者你可以通过调用 callback ,给它传 error 参数,将错误传回给上一级调用栈(如果你在调用栈之上有另一个回调函数)。

request.get('/accounts', (error, response)=>{
  if (error) return console.error(error)
  try {
    data = JSON.parse(response)
  } catch(error) {
    console.error(error)
  }
})

一个小技巧是你可以使用okay库。你可以像下面的例子一样使用它去避免在回调地狱中手动去检查错误(你好, 回调地狱).

var ok = require('okay')

request.get('/accounts', ok(console.error, (response)=>{
  try {
    data = JSON.parse(response)
  } catch(error) {
    console.error(error)
  }
}))


返回回调或者使用if … else

Node是并行的。但是如果你不够细心也会因为这个特性产生bug。 为了安全起见,应该要使用return来终止代码的继续执行:

let error = true
if (error) return callback(error)
console.log('I will never run - good.')

这样可以避免一些因为代码逻辑的处理不当导致一些不应该执行的内容(或者错误)被执行。

let error = true
if (error) callback(error)
console.log('I will run. Not good!')

请确保使用return去阻止代码的继续执行。


监听 error 事件

Node中几乎所有的类/对象都有事件分发器(观察者模式)并且会广播 error 事件。 这是一个很好的特性,可以使开发者在这些讨厌的错误造成巨大后果之前捕捉到它们。

养成一个通过.on()来创建error事件监听的好习惯:

var req = http.request(options, (res) => {
  if (('' + res.statusCode).match(/^2\d\d$/)) {
    // Success, process response
  } else if (('' + res.statusCode).match(/^5\d\d$/))
    // Server error, not the same as req error. Req was ok.
  }
})

req.on('error', (error) => {
  // Can't even make a request: general error, e.g. ECONNRESET, ECONNREFUSED, HPE_INVALID_VERSION
  console.log(error)
})


了解你的npm

很多的Node和前端的开发者知道在安装模块的时候使用--save会在安装模块的同时,会在package.json保存一条含有模块版本信息的条目。当然,还有--save-dev可以用于安装devDependencies(在生成环境中不需要的模块)。但是你知道用-S和-D是否可以代替--save 和--save-dev么?答案是可以的。

当你安装模块的时候,你需要删除-S和-D自动为你模块的版本号添加的^标签。否者当你使用npm install(或者npm i)安装模块的时候,就会自动拉取最新的镜像(版本号的第二位数字)。例如v6.1.0就是v6.2.0的一个镜像分支。

npm团队推荐使用semver,但是你最好不要这样。npm团队认为开源开发者会遵守semver所以他们在npm安装时自动加上了^。没有人可以去保证,所以最好是锁定你的版本号。更好的办法是使用shrinkwrap:npm shrinkwrap会生成一个包含依赖的具体版本的文件。


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.