정보실

웹학교

정보실

javascript 더 나은 JavaScript를 작성하는 실용적인 방법

본문

JavaScript를 개선 할 수 있는 실용적인 방법에 대해 말하는 사람들이 충분하지 않습니다. 더 나은 JS를 작성하기 위해 사용하는 최고의 방법 중 일부는 다음과 같습니다.


https://stackoverflow.blog/2019/09/12/practical-ways-to-write-better-javascript/ 


TypeScript 사용 


JS를 향상 시키기 위해 할 수 있는 가장 중요한 일은 JS를 작성하지 않는 것입니다. 초기에 TypeScript (TS)는 JS의 "컴파일 된"수퍼 세트입니다 (JS에서 실행되는 것은 TS에서 실행 됨). TS는 바닐라 JS 환경에 종합적인 옵션 타이핑 시스템을 추가합니다. 오랫동안 생태계 전체의 TS 지원이 일관성이 없어서 추천하는 것이 불편하다고 느꼈습니다. 고맙게도 그 시절은 오래 걸렸으며 대부분의 프레임 워크는 TS를 즉시 지원합니다. TS가 무엇인지에 대해 모두 같은 페이지에 올랐으니, 왜 그것을 사용하고 싶은지 이야기 해 봅시다.


TypeScript는 유형 안전을 강화합니다 


타입 안전성은 컴파일러가 코드 전체에서 모든 타입이 합법적으로 사용되고 있는지 확인하는 프로세스를 설명합니다. 다시 말해, 숫자를 받는 함수 foo를 만들면 :


function foo(someNum: number): number {
  return someNum + 5;
}

이 foo 함수는 숫자로만 호출해야 합니다.


good
console.log(foo(2)); // prints "7"
no good
console.log(foo("two")); // invalid TS code

코드에 유형을 추가하는 오버 헤드 외에도 유형 안전 시행에 대한 단점은 없습니다. 반면에 이점은 너무 커서 무시할 수 없습니다. 타입 안전은 일반적인 오류 / 버그에 대해 추가적인 보호를 제공합니다. 이는 JS와 같은 무법한 언어에 대한 축복입니다.


타입 스크립트 유형을 사용하면 더 큰 애플리케이션을 리팩토링 할 수 있습니다 


큰 JS 애플리케이션을 리팩토링하는 것은 진정한 악몽 일 수 있습니다. JS 리팩토링의 어려움은 대부분 함수 시그니처를 적용하지 않기 때문입니다. 이것은 JS 함수가 실제로 잘못 사용될 수 없다는 것을 의미합니다. 예를 들어, 1000 개의 다른 서비스에서 사용하는 myAPI 함수가 있는 경우 :


function myAPI(someNum, someString) {
  if (someNum > 0) {
    leakCredentials();
  } else {
    console.log(someString);
  }
}

통화 서명을 약간 변경합니다.

function myAPI(someString, someNum) {
  if (someNum > 0) {
    leakCredentials();
  } else {
    console.log(someString);
  }
}

나는이 함수가 사용되는 모든 장소 (수천 곳)에서 사용법을 올바르게 업데이트 한다는 것을 100 % 확신해야 합니다. 하나라도 놓치면 자격 증명이 유출 될 수 있습니다. TS와 동일한 시나리오는 다음과 같습니다.


before
function myAPITS(someNum: number, someString: string) { ... }
after
function myAPITS(someString: string, someNum: number) { ... }

보시다시피 myAPITS 함수는 JavaScript와 동일한 변경을 거쳤습니다. 그러나 사용되는 수천 개의 장소에서 잘못된 유형을 제공하므로 이 코드는 유효한 JavaScript를 생성하는 대신 잘못된 TypeScript를 생성합니다. 앞에서 설명한 유형 안전성으로 인해 수천 건의 사례가 컴파일을 차단하고 자격 증명이 유출되지 않습니다 (항상 좋았습니다).


TypeScript로 팀 아키텍처 커뮤니케이션이 쉬워집니다 


TS가 올바르게 설정되면 먼저 인터페이스와 클래스를 정의하지 않고 코드를 작성하기가 어렵습니다. 간결하고 의사 소통적인 아키텍처 제안을 공유 할 수 있는 방법을 제공합니다. TS 이전에는 이 ​​문제에 대한 다른 솔루션이 있었지만 추가 작업을 수행하지 않고는 기본적으로 해결 한 것이 없습니다. 예를 들어 백엔드에 새로운 요청 유형을 제안하려면 TS를 사용하여 팀원에게 다음을 보낼 수 있습니다.

interface BasicRequest {
  body: Buffer;
  headers: { [header: string]: string | string[] | undefined; };
  secret: Shhh;
}

이미 코드를 작성해야 했지만 이제 더 많은 시간을 투자하지 않고도 증분 진행 상황을 공유하고 피드백을 받을 수 있습니다. TS가 JS보다 버그가 발생하기 쉬운 지 모르겠습니다. 개발자가 인터페이스와 API를 정의하도록 강요하면 더 나은 코드가 생성된다고 확신합니다. 전반적으로 TS는 바닐라 JS에 대한 성숙하고 예측 가능한 대안으로 발전했습니다. 개발자는 여전히 바닐라 JS에 익숙해야 하지만 요즘 시작하는 대부분의 새로운 프로젝트는 처음부터 TS입니다.



최신 기능 사용 


JavaScript는 세계에서 가장 많이 사용되는 프로그래밍 언어 중 하나입니다. 수억 명의 사람들이 사용하는 20 년 이상 된 언어가 현재 대부분 이해 될 것으로 예상 할 수 있지만 실제로는 그 반대입니다. 최근 JS에 많은 변경과 추가가 있었으며 (예, ECMAScript는 기술적으로 ECMAScript 임) 개발자 경험을 근본적으로 변화 시켰습니다. 지난 2 년 동안 JS를 쓰기 시작한 사람으로서 나는 편견이나 기대 없이 들어올 수 있다는 이점이 있었습니다. 이로 인해 언어의 어떤 기능을 사용하고 피해야 하는지에 대한 훨씬 실용적인 선택이 이루어졌습니다.


async and await 


오랫동안 비동기 이벤트 중심 콜백은 JS 개발에서 피할 수 없는 부분이었습니다.


traditional callback
makeHttpRequest('google.com', function (err, result) {
  if (err) {
    console.log('Oh boy, an error');
  } else {
    console.log(result);
  }
});

나는 왜 위의 문제가 발생했는지 설명하지 않을 것입니다 (그러나 이전에는 가지고 있습니다). 콜백 문제를 해결하기 위해 새로운 개념 인 약속이 JS에 추가되었습니다. 약속을 통해 이전에 콜백 기반 코드를 괴롭힌 중첩 문제를 피하면서 비동기 논리를 작성할 수 있습니다.


Promises
makeHttpRequest('google.com').then(function (result) {
  console.log(result);
}).catch(function (err) {
  console.log('Oh boy, an error');
});

콜백에 대한 약속의 가장 큰 장점은 가독성과 연결성 입니다. 약속은 위대하지만 여전히 원하는 것을 남겼습니다. 많은 사람들에게 Promise의 경험은 여전히 ​​콜백을 연상케 했습니다. 특히 개발자는 Promise 모델의 대안을 요구했습니다. 이를 해결하기 위해 ECMAScript위원회는 약속을 활용하고 비 동기화하고 기다리는 새로운 방법을 추가하기로 결정했습니다.


async and await 
try {
  const result = await makeHttpRequest('google.com');
  console.log(result);
} catch (err) {
  console.log('Oh boy, an error');
}

하나의 주의 사항은 당신이 기다리는 모든 것이 비동기로 선언 된 것입니다 :


required definition of makeHttpRequest in prev example
async function makeHttpRequest(url) {
  // ...
}

비동기 기능은 실제로 멋진 Promise 래퍼이므로 Promise를 직접 기다리는 것도 가능합니다. 또한 비동기 / 대기 코드와 Promise 코드는 기능적으로 동일합니다. 따라서 죄책감을 느끼지 않고 비동기식 / 기다리는 것을 자유롭게 사용하십시오.


let and const 


JS가 존재하는 대부분의 경우 변수 범위 한정자는 하나뿐입니다. var. var에는 범위를 처리하는 방법과 관련하여 매우 독특하고 흥미로운 규칙이 있습니다. var의 범위 지정 동작은 일관성이 없고 혼동되어 예상치 못한 동작이 발생하여 JS 수명 동안 버그가 발생했습니다. 그러나 ES6부터는 var, const 및 let에 대한 대안이 있습니다. 더 이상 var를 사용할 필요가 거의 없으므로 그렇게 하지 마십시오. var를 사용하는 모든 논리는 항상 동등한 const로 변환되고 코드 기반으로 할 수 있습니다.


const 대 let을 언제 사용 해야 하는지에 관해서는 항상 모든 const를 선언하여 시작합니다. const는 훨씬 더 제한적이고“불변하지 않기 때문에”일반적으로 더 나은 코드를 만듭니다. let을 사용해야 하는 “실제 시나리오”는 많지 않습니다. let으로 선언 한 1/20 변수를 말합니다. 나머지는 모두 const입니다.


const는 C / C ++의 const와 같은 방식으로 작동하지 않기 때문에“immutablish”라고 말했다. const가 JavaScript 런타임에 의미하는 것은 해당 const 변수에 대한 참조가 변경되지 않는다는 것입니다. 그렇다고 해당 참조에 저장된 내용이 변경되지는 않습니다. 기본 유형 (숫자, 부울 등)의 경우 const는 단일 메모리 주소이므로 불변성으로 변환됩니다. 그러나 모든 객체 (클래스, 배열, dicts)에 대해 const는 불변성을 보장하지 않습니다.


Arrow => Functions 


화살표 함수는 JS에서 익명 함수를 선언하는 간결한 방법입니다. 익명 함수는 명시적으로 명명되지 않은 함수를 설명합니다. 일반적으로 익명 함수는 콜백 또는 이벤트 후크로 전달됩니다.


vanilla anonymous function 
someMethod(1, function () { // has no name
  console.log('called');
});

대부분이 스타일에 "잘못된"것은 없습니다. 바닐라 익명 함수는 범위와 관련하여 "흥미롭게"동작하여 예기치 않은 많은 버그가 발생할 수 있습니다. 화살표 기능 덕분에 더 이상 걱정할 필요가 없습니다. 화살표 함수로 구현 된 동일한 코드는 다음과 같습니다.

anonymous arrow function
someMethod(1, () => { // has no name
  console.log('called');
});

훨씬 간결한 것 외에도 화살표 기능에는 훨씬 더 실용적인 범위 지정 동작이 있습니다. 화살표 함수는 정의 된 범위에서 이것을 상속합니다. 경우에 따라 화살표 기능이 더 간결해질 수 있습니다.


const added = [0, 1, 2, 3, 4].map((item) => item + 1);
console.log(added) // prints "[1, 2, 3, 4, 5]"

한 줄에 있는 화살표 함수에는 암시 적 return 문이 포함됩니다. 단일 행 화살표 기능이 있는 대괄호 또는 세미콜론이 필요하지 않습니다. 명확하게 하고 싶습니다. 이것은 var 상황이 아닙니다. 바닐라 익명 함수 (특히 클래스 메소드)에 대한 유효한 사용 사례가 여전히 있습니다. 즉, 항상 화살표 기능을 기본값으로 사용하면 바닐라 익명 기능을 기본값으로 사용하는 것과는 달리 디버깅이 훨씬 적습니다.

As usual, the Mozilla docs are the best resource

Spread Operator ... 


한 객체의 키 / 값 쌍을 추출하여 다른 객체의 자식으로 추가하는 것은 매우 일반적인 시나리오입니다. 역사적으로 이 작업을 수행 할 수 있는 몇 가지 방법이 있었지만 이러한 모든 방법은 매우 복잡합니다.


const obj1 = { dog: 'woof' };
const obj2 = { cat: 'meow' };
const merged = Object.assign({}, obj1, obj2);
console.log(merged) // prints { dog: 'woof', cat: 'meow' }

이 패턴은 매우 일반적이므로 위의 접근 방식은 빠르게 지루합니다. 스프레드 연산자 덕분에 다시 사용할 필요가 없습니다.


const obj1 = { dog: 'woof' };
const obj2 = { cat: 'meow' };
console.log({ ...obj1, ...obj2 }); // prints { dog: 'woof', cat: 'meow' }

가장 큰 장점은 배열과도 원활하게 작동한다는 것입니다.

const arr1 = [1, 2];
const arr2 = [3, 4];
console.log([ ...arr1, ...arr2 ]); // prints [1, 2, 3, 4]

아마도 가장 중요한 최신 JS 기능은 아니지만 가장 좋아하는 기능 중 하나입니다.


Template Literals (Template Strings) 


문자열은 가장 일반적인 프로그래밍 구성 중 하나입니다. 이것이 기본적으로 문자열을 선언하는 것이 여전히 많은 언어에서 제대로 지원되지 않는 것이 당황스러운 이유입니다. 오랫동안 JS는 "크 래피 스트링"제품군에 있었습니다. 그러나 템플릿 리터럴을 추가하면 JS가 자체 범주에 속합니다. 템플릿 리터럴은 문자열 작성과 관련된 두 가지 가장 큰 문제인 동적 콘텐츠 추가 및 여러 줄을 연결하는 문자열 작성을 기본적으로 편리하게 해결합니다.


const name = 'Ryland';
const helloString =
`Hello
 ${name}`;

나는 그 코드가 그 자체를 말한다고 생각한다. 정말 놀라운 구현입니다.


Object Destructuring 


객체 파괴는 데이터를 반복하거나 키에 명시적으로 액세스 할 필요 없이 데이터 수집 (객체, 배열 등)에서 값을 추출하는 방법입니다.


old way
function animalParty(dogSound, catSound) {}

const myDict = {
  dog: 'woof',
  cat: 'meow',
};

animalParty(myDict.dog, myDict.cat);

destructuring 


function animalParty(dogSound, catSound) {}

const myDict = {
  dog: 'woof',
  cat: 'meow',
};

const { dog, cat } = myDict;
animalParty(dog, cat);

그러나 더 많은 것이 있습니다. 함수의 시그니처에서 파괴를 정의 할 수도 있습니다.


destructuring 2 


function animalParty({ dog, cat }) {}

const myDict = {
  dog: 'woof',
  cat: 'meow',
};

animalParty(myDict);

배열과도 작동합니다.


destructuring 3 

[a, b] = [10, 20];

console.log(a); // prints 10

활용해야 할 다른 최신 기능이 많이 있습니다. 나에게 눈에 띄는 소수의 다른 사람들이 있습니다.


항상 시스템이 분산 되어 있다고 가정 


병렬 응용 프로그램을 작성할 때 목표는 한 번에 수행하는 작업량을 최적화 하는 것입니다. 사용 가능한 코어가 4 개이고 코드에서 단일 코어 만 사용할 수 있는 경우 잠재적 인 75 %가 낭비됩니다. 이는 병렬 컴퓨팅의 궁극적 인 적이며 블로킹, 동기 작업을 의미합니다. 그러나 JS가 단일 스레드 언어라는 점을 고려하면 여러 코어에서 작동하지 않습니다. 


JS는 단일 스레드이지만 단일 파일이 아닙니다 (학교의 줄에서와 같이). 병렬 적이지는 않지만 여전히 동시적입니다. HTTP 요청을 보내는 데 몇 초 또는 몇 분이 걸릴 수 있으므로 요청에서 응답이 다시 올 때까지 JS가 코드 실행을 중지하면 언어를 사용할 수 없게 됩니다.


JavaScript는이를 이벤트 루프로 해결합니다. 이벤트 루프는 등록 된 이벤트를 반복하여 내부 스케줄링 / 우선 순위 화 논리에 따라 실행합니다. 이를 통해 수천 개의 동시 HTTP 요청을 보내거나 디스크에서 여러 파일을 동시에 읽을 수 있습니다. 유용한 기능 : 올바른 기능을 사용하는 경우에만 JavaScript가 이 기능을 활용할 수 있습니다. 가장 간단한 예는 for-loop입니다.


let sum = 0;
const myArray = [1, 2, 3, 4, 5, ... 99, 100];
for (let i = 0; i < myArray.length; i += 1) {
  sum += myArray[i];
}

바닐라 for- 루프는 프로그래밍에 존재하는 최소 병렬 구성 중 하나입니다. 마지막 직업에서, 나는 전통적인 R lang for-loops를 자동 병렬 코드로 변환하는 데 몇 달을 소비 한 팀을 이끌었습니다. 기본적으로 불가능한 문제이며 딥 러닝이 향상되기를 기다려야 해결할 수 있습니다. for-loop를 병렬화 하는 것은 몇 가지 문제가 있는 패턴에서 비롯됩니다. 순차 for-loop는 매우 드물지만 for-loops 분해성을 보장 할 수는 없습니다.


let runningTotal = 0;
for (let i = 0; i < myArray.length; i += 1) {
  if (i === 50 && runningTotal > 50) {
    runningTotal = 0;
  }
  runningTotal += Math.random() + runningTotal;
}

이 코드는 순서에 따라 반복적으로 실행되는 경우 의도 한 결과 만 생성합니다. 한 번에 여러 반복을 실행하려고 하면 프로세서가 부정확한 값을 기반으로 잘못 분기 되어 결과가 무효화 될 수 있습니다. 사용법이 다르고 컴파일러가 루프로 할 수 있는 몇 가지 트릭이 있기 때문에 C 코드 인 경우 다른 대화를 할 것입니다. JavaScript에서, 전통적인 for-loops는 반드시 필요한 경우에만 사용해야 합니다. 그렇지 않으면 다음 구성을 활용하십시오.


map

// in decreasing relevancy :0
const urls = ['google.com', 'yahoo.com', 'aol.com', 'netscape.com'];
const resultingPromises = urls.map((url) => makHttpRequest(url));
const results = await Promise.all(resultingPromises);

map with index

// in decreasing relevancy :0
const urls = ['google.com', 'yahoo.com', 'aol.com', 'netscape.com'];
const resultingPromises = urls.map((url, index) => makHttpRequest(url, index));
const results = await Promise.all(resultingPromises);

for-each

const urls = ['google.com', 'yahoo.com', 'aol.com', 'netscape.com'];
// note this is non blocking
urls.forEach(async (url) => {
  try {
    await makHttpRequest(url);
  } catch (err) {
    console.log(`${err} bad practice`);
  }
});

이것이 왜 전통적인 for-loop보다 개선 된 이유를 설명하겠습니다. 각 반복을 순서대로 (순차적으로) 실행하는 대신 map과 같은 구문은 모든 요소를 ​​가져 와서 사용자 정의 map 함수에 개별 이벤트로 제출합니다. 대부분의 경우 개별 반복에는 서로 고유 한 연결이나 종속성이 없으므로 동시에 실행할 수 있습니다. 이것은 for-loops로 똑같은 일을 할 수 없다는 것을 말하는 것은 아닙니다. 실제로 다음과 같이 보일 것입니다.


const items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

async function testCall() {
  // do async stuff here
}

for (let i = 0; i < 10; i += 1) {
  testCall();
}

보시다시피, for-loop는 올바른 방법으로 방해하지는 않지만 더 쉽게 만들지는 않습니다. 맵 버전과 비교하십시오.


const items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
items.map(async (item) => {
 // do async stuff here
});

보시다시피,지도는 작동합니다. 모든 개별 비동기 작업이 완료 될 때까지 차단하려는 경우 맵의 이점이 더욱 명확 해집니다. for-loop 코드를 사용하면 배열을 직접 관리해야 합니다. 지도 버전은 다음과 같습니다.


const items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
 const allResults = await Promise.all(items.map(async (item) => {
  // do async stuff here
 }));

it's really that easy

for-loop가 map 또는 forEach와 비교할 때 성능이 우수하거나 더 많은 경우가 많습니다. 나는 여전히 몇 주기를 잃는 것이 잘 정의 된 API를 사용하는 이점이 있다고 주장합니다. 이렇게 하면 향후 해당 데이터 액세스 패턴 구현이 향상되어 코드에 도움이 됩니다. for-loop는 동일한 패턴에 대해 의미 있는 최적화를 하기에는 너무 일반적입니다.


for-await-of와 같이 map 및 forEach 외부에 유효한 다른 비동기 옵션이 있습니다. 


코드 린트 및 스타일 적용 


일관된 스타일 (모양과 느낌)이없는 코드는 읽고 이해하기가 매우 어렵습니다. 따라서 어떤 언어로든 고급 코드를 작성하는 데있어 중요한 측면은 일관되고 합리적인 스타일입니다. JS 생태계의 폭이 넓기 때문에, 린터 및 스타일 특정을 위한 많은 옵션이 있습니다. 내가 충분히 강조 할 수 없는 것은 린터를 사용하고 특별히 선택한 린터 / 스타일보다 스타일을 적용하는 것이 훨씬 중요하다는 것입니다. 하루가 끝나면 아무도 내가 원하는 방식으로 코드를 작성하지 않을 것이므로 이를 최적화 하는 것은 비현실적인 목표입니다.


나는 많은 사람들이 eslint를 사용해야 하는지 아니면 prettier 사용해야 하는지 묻습니다. 나를 위해, 그들은 매우 다른 목적을 제공하므로 함께 사용해야 합니다. Eslint는 대부분 전통적 쓰레기통입니다. 스타일과 관련이 없고 정확성과 관련이 있는 코드 관련 문제를 식별 할 것입니다. 예를 들어 AirBNB 규칙과 함께 eslint를 사용합니다. 해당 구성을 사용하면 다음 코드는 linter가 실패하도록 합니다.


var fooVar = 3; // airbnb rules forebid "var"


eslint가 개발주기에 가치를 더하는 방법은 매우 분명합니다. 본질적으로, 그것은 좋은 습관과 그렇지 않은 것에 관한 규칙을 준수하도록 합니다. 이로 인해, 린 터는 본질적으로 의견이 있습니다. 모든 의견과 마찬가지로 소금 알갱이로 섭취하십시오. 린터가 잘못되었을 수 있습니다.


Prettier는 코드 포맷터입니다. 정확성에 대한 관심이 적고 균일 성과 일관성에 대해 훨씬 걱정합니다. Prettier는 var 사용에 대해 불평하지 않지만 코드의 모든 대괄호를 자동으로 정렬합니다. 개인 개발 프로세스에서 코드를 Git에 푸시 하기 전에 항상 마지막 단계로 더 예쁘게 실행합니다. 많은 경우에, Repo에 커밋 할 때마다 Prettier가 자동으로 실행되도록 하는 것이 좋습니다. 이를 통해 소스 제어로 들어오는 모든 코드의 스타일과 구조가 일관되게 됩니다.


코드 테스트 


테스트 작성은 작성하는 JS 코드를 개선하는 간접적이지만 매우 효과적인 방법입니다. 다양한 테스트 도구에 익숙해지는 것이 좋습니다. 테스트 요구 사항은 다양하며 모든 것을 처리 할 수 있는 단일 도구는 없습니다. JS 생태계에는 수많은 테스팅 툴이 존재하므로 툴 선택은 주로 개인 취향에 달려 있습니다. 항상 그렇듯이 자신을 생각하십시오.


테스트 드라이버 – Ava 


Github의 AvaJS


테스트 드라이버는 구조와 유틸리티를 매우 높은 수준으로 제공하는 프레임 워크입니다. 테스트 요구 사항에 따라 다른 특정 테스트 도구와 함께 사용되는 경우가 많습니다. 


Ava는 표현력과 간결함의 올바른 균형입니다. Ava의 병렬 및 격리 된 아키텍처는 대부분의 내 사랑의 원천입니다. 더 빠르게 실행되는 테스트는 개발자의 시간과 회사 비용을 절약합니다. Ava는 내장 어설 션과 같은 훌륭한 기능을 자랑하면서도 최소한으로 유지합니다.


대안 : Jest, Mocha, Jasmine


Spies and Stubs – Sinon 


Sinon on Github


스파이는 함수 호출 횟수, 호출 횟수 및 기타 통찰력 있는 데이터와 같은 함수 분석을 제공합니다. 


Sinon은 많은 작업을 수행하는 라이브러리이지만 몇 가지만 잘 수행합니다. 특히, sinon은 스파이와 스터브와 관련하여 뛰어납니다. 기능 세트는 풍부하지만 구문은 간결합니다. 공간을 절약하기 위해 부분적으로 존재한다는 점에서 스텁에 특히 중요합니다.


대안 : testdouble


Mocks – Nock 


Nock on Github


HTTP 조롱은 http 요청 프로세스의 일부를 위조하는 프로세스이므로 테스터는 사용자 정의 로직을 주입하여 서버 동작을 시뮬레이션 할 수 있습니다. 


HTTP 조롱은 실제로 고통스러울 수 있지만 노크는 덜 고통스럽게 만듭니다. Nock은 nodejs에 내장 된 요청을 직접 대체하고 발신 http 요청을 차단합니다. 결과적으로 응답을 완벽하게 제어 할 수 있습니다.


Web Automation – Selenium 


Selenium on Github


셀레늄 추천에 대한 감정이 혼재되어 있습니다. 웹 자동화에 가장 널리 사용되는 옵션이므로 대규모 커뮤니티 및 온라인 리소스 세트가 있습니다. 불행히도 학습 곡선은 매우 가파르며 실제로 사용하기 위해 많은 외부 라이브러리에 의존합니다. 즉, 유일한 무료 옵션이므로 엔터프라이즈 급 웹 자동화를 수행하지 않는 한 Selenium이 작업을 수행합니다.


대안 : Cypress, PhantomJS


끝없는 여행 


대부분의 경우와 마찬가지로 더 나은 JavaScript를 작성하는 것은 지속적인 프로세스입니다. 코드는 항상 깨끗하고 항상 새로운 기능이 추가되며 테스트가 충분하지 않습니다. 압도적으로 보일지 모르지만, 개선해야 할 잠재적인 측면이 너무 많기 때문에 자신의 진도에 따라 진전 할 수 있습니다. 한 번에 한 단계씩 수행하면 알기 전에 JavaScript 에이스가 됩니다.




페이지 정보

조회 72회 ]  작성일19-10-12 11:39

웹학교