-
[오픈소스코드리뷰] cookie카테고리 없음 2022. 8. 12. 09:28
들어가며
Cookie는 대부분의 웹사이트에서 사용되는 강력한 브라우저 API 이며
key=value로 쌍을 이루고 ;(Semicolon)으로 구분합니다.
브라우저마다 조금씩 다르지만 한 사이트 당 20개 정도로 한정되어 있고,
key=value 를 인코딩 이후 4kb 가 넘지 않아야 하고,
모든 문자가 허용되기 때문에 저장할 때는 반드시 encode 하여 저장하는 것이 좋습니다.
작은 단위 정보로만 사용할 수 있기 때문에, 주로 사용자 정보, 통계 수치, 토큰 저장과 같은 기능 개발에 사용됩니다.
현재 리뷰 버전은 0.4.1 입니다.
리뷰
... .travis.yml eslintrc.yml ...
특별한 설정은 없네요. Dayjs와 마찬가지로 Travis CI를 사용하고 있습니다.
rules: eol-last: error indent: ["error", 2, { "SwitchCase": 1 }] no-trailing-spaces: error
eslint 설정 역시 특별한 것은 없습니다..
{ "scripts": { "bench": "node benchmark/index.js", "lint": "eslint --plugin markdown --ext js,md .", "test": "mocha --reporter spec --bail --check-leaks --ui qunit test/", "test-ci": "nyc --reporter=text npm test", "test-cov": "nyc --reporter=html --reporter=text npm test", "version": "node scripts/version-history.js && git add HISTORY.md" } }
Mocha 로 테스트를 하고 있으며, 퍼포먼스 테스트 도구인 benchmark 도 사용하는 것을 확인할 수 있네요.
본격적으로 index.js 를 살펴볼까요?
주석을 제외하면 약 100여줄 정도밖에 되지 않는데,
정말 많은 사람들이 사용을 하고 있는 라이브러리입니다.// index.js // 생략 ... // 1) /** * RegExp to match field-content in RFC 7230 sec 3.2 * * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] * field-vchar = VCHAR / obs-text * obs-text = %x80-FF */ // 2) var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/; // 생략 ...
- 사용자가 많은 오픈소스일수록 JSDoc 을 잘 작성합니다.
JSDoc 작성 시 @example 도 추가로 작성하면 타입 스크립트를 사용하지 않는 환경에서도 협업하기 좋습니다.
최근 프론트엔드 개발 입사 지원 시 과제를 주는 기업이 상당히 많아졌는데,
JSDoc 작성 가산점이 있을 정도로 개발 문서화에 대한 관심이 많아지고 있습니다. - Unicode 로 작성된 내용은 \u0009(탭), \u0020(공백), 그 뒤에는 특정한 라틴/특수 문자에 대한 내용이 포함되어 있는지를 확인 하는 정규식입니다.
https://www.fileformat.info/info/unicode/char/a.htm 사이트에서 Unicode의 대한 내용을 확인 할 수 있습니다.
// index.js // 생략 ... function parse(str, options) { // 생략 ... // 1) var pairs = str.split(pairSplitRegExp); // 생략 ... for (var i = 0; i < pairs.length; i++) { // 2 var pair = pairs[i]; var eq_idx = pair.indexOf('='); // skip things that don't look like key=value if (eq_idx < 0) { continue; } var key = pair.substr(0, eq_idx).trim() var val = pair.substr(++eq_idx, pair.length).trim(); // quoted values if ('"' == val[0]) { val = val.slice(1, -1); } // only assign once if (undefined == obj[key]) { obj[key] = tryDecode(val, dec); } } return obj; }
- ;(Semicolon) 을 기준으로 split 하여 배열로 만든 후에
- =(Equal)의 포함 여부로 { key: value } 와 같은 Object 만들기 위한 반복문인데,
이 부분을 정규식으로 만들면 더 간결하게 할 수 있을 것 같네요..
// e.g const params = arr.map(str => /^(\S+)=(\S+)$/g.exec(str)).reduce((a,b) => { const [,key, value] = b; return !!key && !!value ? {...a, [key]:value} : a; }, {});
참고로 \S 는 공백을 제외한 문자에만 해당되는 표현식입니다..
// index.js // ...생략 switch (sameSite) { case true: str += '; SameSite=Strict'; break; case 'lax': str += '; SameSite=Lax'; break; case 'strict': str += '; SameSite=Strict'; break; case 'none': str += '; SameSite=None'; break; default: throw new TypeError('option sameSite is invalid'); }
이렇게 Case 별로 문자열을 만드는 경우 object 형식으로 개발을 하는 방법도 괜찮을 것 같습니다.// e.g let sameSite = 'none'; let str = ''; const mode = { "true": "Strict", "strict": "Strict", "lax": "Lax", "none": "None", }[String(sameSite).toLowerCase()] || null; str += !!mode ? `SameSite=${mode}` : ''; console.log(str);
쿠키의 사용이 어렵지 않아 코드가 길지 않은 것 같습니다.
마치며
en/de code 방법으로 encodeURIComponent, decodeURIComponent 이 외에
base64 API인 atob, btoa 도 많이 사용 하니 참고 하시면 좋습니다.
https://github.com/jshttp/cookie - 사용자가 많은 오픈소스일수록 JSDoc 을 잘 작성합니다.