Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
ǰ¶Ë¹¤³Ì»¯Êµ¼ù×ܽá
 
×÷ÕߣºÇ°¶ËÃÔ
  1942  次浏览      27
 2021-5-6 
 
±à¼­ÍƼö:
±¾ÎÄÖ÷Òª½éÉÜÔÚǰ¶Ë¹¤³Ì»¯µÄÏÖ×´£¬¼¼ÊõÑ¡ÐÍ£º¹¹½¨·½°¸¡¢UI×é¼þ¿ª·¢ºÍÎĵµ¡¢Jestµ¥Ôª²âÊÔµÈÏà¹ØÄÚÈÝ¡£
±¾ÎÄÀ´×ÔÓÚÔÆÉçÇø,ÓÉ»ðÁú¹ûÈí¼þAnna±à¼­ÍƼö¡£

Ëæ×ÅÒµÎñµÄ²»¶ÏÀ©Õ¹£¬ÍŶӵÄÏîĿԽÀ´Ô½¶à£¬Ãæ¶ÔÈÕÒæ¸´ÔÓµÄÒµÎñ³¡¾°ºÍ´úÂëÂß¼­£¬ÎÒÃÇ·¢ÏÖÔÚǰ¶Ë¹¤³Ì»¯·½ÃæÍŶӻ¹ÓкܶàÐèÒªÓÅ»¯µÄµØ·½¡£ÏÖÓеĽâ¾ö·½°¸ÒѾ­ÎÞ·¨Âú×ã¸÷ÖÖ¸´Ôӵij¡¾°£¬ÎÒÃÇÿÌì¶¼ÔÚÆ£ÓÚÓ¦¸¶ºÜ¶àÖØ¸´µÄ¹¤×÷£¬Îª´ËÎÒÃÇ»ùÓÚÒÆ¶¯¶Ë»ù´¡¿âÖØ¹¹ºÍUI×é¼þ¿âµÄ½¨ÉèÕâÁ½¸öÏîÄ¿¶ÔÍŶӵÄÏîÄ¿¹¹½¨Á÷³Ì½øÐÐÁËÏêϸµÄ·ÖÎöºÍÊáÀí£¬²¢Öƶ¨ÁËÒ»Ì×ÊÊÓÃÓÚÍŶӵŤ³Ì»¯·½°¸¡£

dz̸ǰ¶Ë¹¤³Ì»¯

ǰ¶Ë¹¤³Ì»¯ÊÇÒ»¸ö·Ç³£¹ã·ºµÄÒéÌ⣬°üº¬µÄ¼¼ÊõºÍ½â¾ö·½°¸Ò²ÊǷdz£·á¸»µÄ¡£Ò»¸öǰ¶Ë¹¤³ÌµÄÉúÃüÖÜÆÚ¿ÉÒÔ´óÖ»®·ÖΪÕâËĸö¹ý³Ì£º

ǰ¶Ë¹¤³ÌµÄÉúÃüÖÜÆÚ

ÈκÎÔÚÕâËĸö¹ý³ÌÖÐÓ¦ÓõÄϵͳ»¯¡¢ÑϸñÔ¼Êø¡¢¿ÉÁ¿»¯µÄ·½·¨¶¼¿ÉÒÔ³ÆÖ®Îª¹¤³Ì»¯¡£¹¤³Ì»¯µÄ³Ì¶ÈÔ½¸ß£¬ÔÚ¹¤×÷ÖÐÒòÈ˵ĸöÌå²îÒìÐÔµ¼ÖµÄȱÏÝ»òÕ߶̰å¾Í»áÔ½ÉÙ£¬ÏîÄ¿ÖÊÁ¿¿ÉÒԵõ½¸üÓÐЧµÄ±£ÕÏ¡£¶ÔÉÏÃæËĸö¹ý³ÌµÄ¹¤³Ì»¯²¢²»ÊÇÍêÈ«·Ö¸ôµÄ£¬¶øÊÇÏศÏà³É£¬±ÈÈ翪·¢½×¶ÎµÄÓÅ»¯Ò²»á¶Ô²âÊÔ¡¢²¿ÊðºÍά»¤²úÉúºÜ´óµÄÓ°Ïì¡£

ÏÂÃæ´ÓÄ£¿é»¯¡¢×é¼þ»¯¡¢¹æ·¶»¯ºÍ×Ô¶¯»¯ÕâËĸö·½Ãæ½øÐоßÌå½éÉÜ¡£

Ä£¿é»¯

Ä£¿é»¯¿ÉÒÔ¶Ô¸´ÔÓÂß¼­½øÐÐÓÐЧ·Ö¸î£¬Ã¿¸öÄ£¿é¸ü¹Ø×¢×ÔÉíµÄ¹¦ÄÜ£¬Ä£¿éÄÚ²¿µÄÊý¾ÝºÍʵÏÖÊÇ˽Óеģ¬Í¨¹ýÏòÍⲿ±©Â¶Ò»Ð©½Ó¿ÚÀ´ÊµÏÖ¸÷Ä£¿é¼äµÄͨÐÅ¡£¿ª·¢½×¶Îǰ¶ËÐèÒª¹Ø×¢JS¡¢CSSºÍHTML£¬ÏÂÃæÎÒÃǽ«·Ö±ð¶ÔJS¡¢CSS¡¢HTMLµÄÄ£¿é»¯½øÐмòµ¥½éÉÜ¡£

1. JSÄ£¿é»¯

JSÄ£¿é»¯ÊÇÒ»¸öÖð½¥ÑݱäµÄ¹ý³Ì£¬¿ªÊ¼µÄnamespace¸ÅÄîʵÏÖÁ˼òµ¥¶ÔÏó·â×°£¬Ô¼¶¨Ë½ÓÐÊôÐÔʹÓÃ_¿ªÍ·£¬µ½ºóÀ´µÄIIFEģʽ£¬ÀûÓÃÄäÃûº¯Êý±Õ°üµÄÔ­Àí½â¾öÄ£¿éµÄ¸ôÀëÓëÒýÓã¬ÏÂÃæ½éÉÜÏÖÔڱȽÏÁ÷Ðеļ¸ÖÖÄ£¿é»¯±ê×¼¡£

2. CommonJS

NodejsÖеÄÄ£¿é»¯·½°¸£¬¾ÍÊÇ»ùÓÚCommonJS¹æ·¶ÊµÏֵġ£Ò»¸öÎļþ¾ÍÊÇÒ»¸öÄ£¿é£¬ÓÐ×Ô¼ºµÄ×÷ÓÃÓò£¬Ã»ÓÐexportµÄ±äÁ¿ºÍ·½·¨¶¼ÊÇ˽Óе쬲»»áÎÛȾȫ¾Ö×÷ÓÃÓò£¬Ä£¿éµÄ¼ÓÔØÊÇÔËÐÐʱͬ²½¼ÓÔØµÄ¡£CommonJS¿ÉÒÔϸ·ÖΪCommonJS1ºÍCommonJS2£¬¶þÕßµÄÄ£¿éµ¼³ö·½Ê½²»Í¬£¬CommonJS2¼æÈÝCommonJS1£¬Ôö¼ÓÁËmodule.exportsµÄµ¼³ö·½Ê½£¬ÏÖÔÚÒ»°ãËùÖ¸µÄ¶¼ÊÇCommonJS2¡£

ÿ¸öÎļþÒ»¸öÄ£¿é£¬ÓÐ×Ô¼ºµÄ×÷ÓÃÓò£¬²»»áÎÛȾȫ¾Ö£»

ʹÓÃrequireͬ²½¼ÓÔØÒÀÀµµÄÆäËûÄ£¿é£¬Í¨¹ýmodule.exportsµ¼³öÐèÒª±©Â¶µÄ½Ó¿Ú£»

¶à´ÎrequireµÄͬһģ¿éÖ»»áÔÚµÚÒ»´Î¼ÓÔØÊ±ÔËÐУ¬²¢½«ÔËÐнá¹û»º´æ£¬ºóÐøÖ±½Ó¶ÁÈ¡»º´æ½á¹û£¬Èç¹ûÐèÒªÖØÐÂÖ´ÐУ¬ÐèÒªÏÈÇåÀí»º´æ£»

Nodejs»·¾³Ï¿ÉÒÔÖ±½ÓÔËÐУ¬¸÷¸öÄ£¿é°´ÒýÈë˳ÐòÒÀ´ÎÖ´ÐС£

module.exports.add = function (a, b) {
return a + b;
}

exports.add = function (a, b) {
return a + b;
}
const sum = require('sum');
sum.add(1, 2);

AMD

ä¯ÀÀÆ÷¼ÓÔØjsÎļþÐèÒª½øÐÐÍøÂçÇëÇ󣬶øÍøÂçÇëÇóµÄºÄʱÊDz»¿ÉÔ¤ÆÚµÄ£¬ÕâʹµÃCommonJSͬ²½¼ÓÔØÄ£¿éµÄ»úÖÆÔÚä¯ÀÀÆ÷¶Ë²¢²»ÊÊÓã¬ÎÒÃDz»ÄÜÒòΪҪ¼ÓÔØÄ³¸öÄ£¿éjs¶øÒ»Ö±×èÈûä¯ÀÀÆ÷¼ÌÐøÖ´ÐÐÏÂÃæµÄ´úÂë¡£AMD¹æ·¶Ôò²ÉÓÃÒì²½µÄ·½Ê½¼ÓÔØÄ£¿é£¬ÔÊÐíÖ¸¶¨»Øµ÷º¯Êý£¬Õâ·Ç³£ÊʺÏÓÃÓÚä¯ÀÀÆ÷¶ËµÄÄ£¿é»¯³¡¾°¡£

ʹÓÃdefine¶¨ÒåÒ»¸öÄ£¿é£¬Ê¹ÓÃrequire¼ÓÔØÄ£¿é£»

Òì²½¼ÓÔØ£¬¿ÉÒÔ²¢ÐÐÇëÇóÒÀÀµÄ£¿é£»

Ô­ÉúJavaScriptÔËÐл·¾³ÎÞ·¨Ö±½ÓÖ´ÐÐAMD¹æ·¶µÄÄ£¿é´úÂ룬ÐèÒªÒýÈëµÚÈý·½¿âÖ§³Ö£¬ÈçrequirejsµÈ£»

// ¶¨ÒåÒ»¸öÄ£¿é
define(id ? , dependencies ? , factory);
// ÒýÓÃÒ»¸öÄ£¿é
require([module], callback)

CMD

ÀàËÆÓÚAMD¹æ·¶£¬ÊÇÓ¦ÓÃÔÚä¯ÀÀÆ÷¶ËµÄJSÄ£¿é»¯·½°¸£¬ÓÉsea.jsÌá³ö£¬Ïê¼û https://www.zhihu.com/question/20351507 ¡£

UMD

UMD¹æ·¶¼æÈÝAMDºÍCommonJS£¬ÔÚä¯ÀÀÆ÷ºÍNodejsÖоù¿ÉÒÔÔËÐС£

(function (root, factory) {
if (typeof define === 'function' && define.amd) {

define(['jquery', 'underscore'], factory);
} else if (typeof exports === 'object') {

module.exports = factory(require('jquery'), require('underscore'));
} else {

root.returnExports = factory(root.jQuery, root._);
}
}(this, function ($, _) {

function a() {};
function b() {};
function c() {};
return {
b: b,
c: c
}
}));

ES6 Module

ES6´ÓÓïÑÔ±ê×¼µÄ²ãÃæÉÏʵÏÖÁËÄ£¿é»¯£¬ÊÇECMAÌá³öµÄÄ£¿é»¯±ê×¼£¬ºóÐøä¯ÀÀÆ÷ºÍNodejs¶¼Ðû²¼»áÔ­ÉúÖ§³Ö£¬Ô½À´Ô½ÊÜ¿ª·¢ÕßÇàíù¡£

ʹÓÃimportÒýÈëÄ£¿é£¬exportµ¼³öÄ£¿é£»

ÓëCommonJSµÄÖ´ÐÐʱ»ú²»Í¬£¬Ö»ÊǸöÖ»¶ÁÒýÓã¬Ö»»áÔÚÕæÕýµ÷Óõĵط½¿ªÊ¼Ö´ÐУ¬¶ø²»ÊÇÏñCommonJSÄÇÑù£¬ÔÚrequireµÄʱºò¾Í»áÖ´ÐдúÂ룻

Ö§³Ö¶ÈÔݲ»ÍêÉÆ£¬ÐèÒª½øÐдúÂëת»»³ÉÉÏÃæ½éÉܵÄijһÖÖÄ£¿é»¯¹æ·¶¡£

ÔÚä¯ÀÀÆ÷ÖпÉÒÔͨ¹ýÏÂÃæµÄ·½Ê½ÒýÈëes6¹æ·¶µÄÄ£¿éjs£º

<script type="module" src="foo.mjs"></script>

<script type="module" src="foo.mjs" defer></script>

deferºÍasync²»Í¬£¬Ëü»á×èÈûDomContentLoadedʼþ£¬Ã¿¸öÄ£¿éjs»á¸ù¾ÝÒýÈëµÄ˳ÐòÒÀ´ÎÖ´ÐС£

Ëæ×Ÿü¶àä¯ÀÀÆ÷¶ÔES6µÄÖ§³Ö£¬ÏÖÔÚÓÐһЩ·½°¸¿ªÊ¼Ìá³öÖ±½ÓʹÓÃES2015+µÄ´úÂëÔÚä¯ÀÀÆ÷ÖÐÖ±½ÓÖ´ÐÐÀ´Ìá¸ßÔËÐÐЧ¹û£¬ÕâÆªÎÄÕ¡¶Deploying ES2015+ Code in Production Today¡·ÖÐÓÐÏêϸµÄ½éÉÜ£¬¿ÉÒÔ½áºÏÕâ·ÝÐÔÄܲâÊÔ±¨¸æ×ÛºÏÆÀ¹ÀES6ÔÚnodeÒÔ¼°¸÷ÖÖä¯ÀÀÆ÷»·¾³ÏµÄÖ´ÐÐЧÂʶԱȡ£

3. CSSÄ£¿é»¯

CSS ×Ôµ®ÉúÒÔÀ´£¬»ù±¾Óï·¨ºÍºËÐÄ»úÖÆÒ»Ö±Ã»Óб¾ÖÊÉϵı仯£¬ËüµÄ·¢Õ¹¼¸ºõÈ«ÊDZíÏÖÁ¦²ãÃæÉϵÄÌáÉý¡£²»Í¬ÓÚJS£¬CSS±¾Éí²»¾ßÓи߼¶±à³ÌÊôÐÔ£¬ÎÞ·¨Ê¹ÓñäÁ¿¡¢ÔËËã¡¢º¯ÊýµÈ£¬ÎÞ·¨¹ÜÀíÒÀÀµ£¬È«¾Ö×÷ÓÃÓòʹµÃÔÚ±àдCSSÑùʽµÄʱºòÐèÒª¸ü¶àÈ˹¤È¥´¦ÀíÓÅÏȼ¶µÄÎÊÌ⣬ÑùʽÃû»¹ÓÐѹËõ¼«ÏÞµÄÎÊÌ⣬Ϊ´Ë£¬³öÏÖÁ˺ܶࡰ±àÒ빤¾ß¡±ºÍ¡°¿ª·¢·½°¸¡±ÎªCSS¸³Óè¡°±à³ÌÄÜÁ¦¡±¡£

Ô¤´¦ÀíÆ÷

Ëæ×ÅÒ³ÃæÔ½À´Ô½¸´ÔÓ£¬ÎªÁ˱ãÓÚ¿ª·¢ºÍά»¤£¬ÎÒÃdz£³£»á½«CSSÎļþ½øÐÐÇз֣¬È»ºóÔÙ½«ÐèÒªµÄÎļþ½øÐкϲ¢¡£ÖîÈçLESS¡¢SASS¡¢StylusµÈÔ¤´¦ÀíÆ÷ΪCSS´øÀ´Á˱à³ÌÄÜÁ¦£¬ÎÒÃÇ¿ÉÒÔʹÓñäÁ¿¡¢ÔËËã¡¢º¯Êý£¬@importÖ¸Áî¿ÉÒÔÇáËɺϲ¢Îļþ¡£µ«¸÷ÖÖÔ¤´¦ÀíÆ÷²¢²»ÄÜÍêÈ«½â¾öÈ«¾Ö×÷ÓÃÓòµÄÎÊÌ⣬ÐèÒª½áºÏnamespaceµÄ˼ÏëÈ¥ÃüÃû¡£

OOCSS & SMACSS

OOCSSºÍSMACSS¶¼ÊÇÓйØcssµÄ·½·¨ÂÛ¡£OOCSS(Object Oriented CSS)¼´ÃæÏò¶ÔÏóµÄCSS£¬Ö¼ÔÚ±àд¸ß¿É¸´ÓᢵÍñîºÏºÍ¸ßÀ©Õ¹µÄCSS´úÂ룬ÓÐÁ½¸öÖ÷ÒªÔ­Ôò£¬ËüÃǶ¼ÊÇÓÃÀ´¹æ¶¨Ó¦¸Ã°ÑʲôÊôÐÔ¶¨ÒåÔÚʲôÑùʽÀàÖС£

Separate structure and skin£¨·ÖÀë½á¹¹ºÍÖ÷Ì⣩

Separate container and content£¨·ÖÀëÈÝÆ÷ºÍÄÚÈÝ£©

SMACSS(Scalable and Modular Architecture for CSS)ÊÇ¿ÉÀ©Õ¹Ä£¿é»¯µÄCSS£¬ËüµÄºËÐľÍÊǽṹ»¯CSS´úÂ룬ÔòÓÐÈý¸öÖ÷Òª¹æÔò£º

Categorizing CSS Rules (CSS·ÖÀà¹æÔò)£º½«CSS·Ö³ÉBase¡¢Layout¡¢Module¡¢State¡¢ThemeÕâ5Àà¡£

Naming Rules£¨ÃüÃû¹æÔò£©£º¿¼ÂÇÓÃÃüÃûÌåÏÖÑùʽ¶ÔÓ¦µÄÀà±ð£¬Èçlayout-ÕâÑùµÄǰ׺¡£

Minimizing the Depth of Applicability£¨×îС»¯ÊÊÅäÉî¶È£©£º½µµÍ¶ÔÌØ¶¨html½á¹¹µÄÒÀÀµ¡£

/* ÒÀÀµhtml½á¹¹£¬²»Ìᳫ */
.sidebar ul h3 { }
/* ½¨ÒéÖ±½Ó¶¨Òå */
.sub-title { }

 

BEM

BEMÊÇÒ»ÖÖCSSÃüÃû¹æ·¶£¬Ö¼ÔÚ½â¾öÑùʽÃûµÄÈ«¾Ö³åÍ»ÎÊÌâ¡£BEMÊǿ飨block£©¡¢ÔªËØ£¨element£©¡¢ÐÞÊηû£¨modifier£©µÄ¼òд£¬ÎÒÃdz£ÓÃÕâÈý¸öʵÌ忪·¢×é¼þ¡£

¿é(block)£ºÒ»ÖÖ²¼¾Ö»òÕßÉè¼ÆÉϵijéÏó£¬Ã¿Ò»¸ö¿éÓµÓÐÒ»¸öÃüÃû¿Õ¼ä£¨Ç°×º£©¡£

ÔªËØ(element)£ºÊÇ.blockµÄºó´ú£¬ºÍ¿éÒ»ÆðÐγÉÒ»¸öÍêÕûµÄʵÌå¡£

ÐÞÊηû(modifier)£º´ú±íÒ»¸ö¿éµÄ״̬£¬±íʾËü³ÖÓеÄÒ»¸öÌØ¶¨ÊôÐÔ¡£

ÔÚÑ¡ÔñÆ÷ÖУ¬BEMÒªÇóֻʹÓÃÀàÃû£¬²»ÔÊÐíʹÓÃid£¬ÓÉÒÔÏÂÈýÖÖ·ûºÅÀ´±íʾÀ©Õ¹µÄ¹ØÏµ£º

Öл®Ïß( - ) £º½ö×÷ΪÁ¬×Ö·ûʹÓ㬱íʾij¸ö¿é»òÕßij¸ö×ÓÔªËØµÄ¶àµ¥´ÊÖ®¼äµÄÁ¬½Ó¼ÇºÅ¡£

˫ϻ®Ïß( __ )£ºË«Ï»®ÏßÓÃÀ´Á¬½Ó¿éºÍ¿éµÄ×ÓÔªËØ¡£

µ¥Ï»®Ïß( _ )£ºµ¥Ï»®ÏßÓÃÀ´ÃèÊöÒ»¸ö¿é»òÕß¿éµÄ×ÓÔªËØµÄÒ»ÖÖ״̬¡£

´ÓÉÏÃæBEMµÄÃüÃûÒªÇó¿ÉÒÔ¿´µ½£¬ÀàÃû¶¼ºÜ³¤£¬Õâ¾Íµ¼ÖÂÔÚ¶ÔCSSÎļþ½øÐÐѹËõµÄʱºò£¬ÎÒÃÇÎÞ·¨µÃµ½¸ü´óµÄÓÅ»¯¿Õ¼ä¡£¶øÇÒBEM½ö½öÊÇÒ»Öֹ淶£¬ÐèÒªÍŶÓÖеĿª·¢Õß×ÔÐÐ×ñÊØ£¬ÔÚ¿É¿¿ÐÔÉÏÎÞ·¨µÃµ½ÓÐЧ±£ÕÏ£¬¶øÇÒ»¹¿ÉÄܺ͵ÚÈý·½¿âµÄÃüÃû³åÍ»¡£

CSS in JS

CSS in JSÊÇÒ»ÖֱȽϼ¤½øµÄ·½°¸£¬³¹µ×ÅׯúÁËCSS£¬ÍêȫʹÓÃJSÀ´±àдCSS£¬ÓÖÓÃÆðÁËÐÐÄÚÑùʽ£¨inline style£©£¬ËüµÄ·¢Õ¹µÃÒæÓÚReactµÄ³öÏÖ£¬¾ßÌåµÄÔ­Òò¿ÉÒԲμû×é¼þ»¯Õⲿ·ÖÄÚÈÝ¡£

½â¾öÈ«¾ÖÃüÃûÎÛȾµÄÎÊÌ⣻

¸üÌù½üWeb×é¼þ»¯µÄ˼Ï룻

¿ÉÒÔÔÚһЩÎÞ·¨½âÎöCSSµÄÔËÐл·¾³ÏÂÖ´ÐУ¬±ÈÈçReact NativeµÈ£»

JS¸³ÓèCSS¸ü¶àµÄ±à³ÌÄÜÁ¦£¬ÊµÏÖÁËCSSºÍJS¼äµÄ±äÁ¿¹²Ïí£»

Ö§³ÖCSSµ¥Ôª²âÊÔ£¬Ìá¸ßCSSµÄ°²È«ÐÔ£»

Ô­ÉúJS±àдCSSÎÞ·¨Ö§³Öµ½ºÜ¶àÌØÐÔ£¬±ÈÈçαÀà¡¢media queryµÈ£¬ÐèÒªÒýÈë¶îÍâµÄµÚÈý·½¿âÀ´Ö§³Ö£¬¸÷ÖÖ¿âµÄ¶Ô±ÈÏê¼ûcss-in-js£»

ÓÐÔËÐÐʱËðºÄ£¬ÐÔÄܱÈÖ±½ÓclassÒª²îһЩ£»

²»ÈÝÒ×debug£»

ÏÂÃæÒÔstyled-componentsΪÀý£º

import React from 'react';
import styled from 'styled-components';
const Container = styled.div`
text-align: center;
`;
const App = () => (
<Container>
It is a test!
</Container>
);
render(<App />, document.getElementById('content'));

¹¹½¨ºóµÄ½á¹ûÈçÏ£¬ÎÒÃÇ·¢ÏÖ²»»áÔÙÓÐ.cssÎļþ£¬Ò»¸ö.jsÎļþ°üº¬ÁË×é¼þÏà¹ØµÄÈ«²¿´úÂ룺

var _templateObject = _taggedTemplateLiteral(['\n text-align: center;\n'], ['\n text-align: center;\n']);
function _taggedTemplateLiteral(strings, raw) {
return Object.freeze(Object.defineProperties(strings, {
raw: { value: Object.freeze(raw) } }));
}
var Container = _styledComponents2.default.div(_templateObject);
var App = function App() {
return _react2.default.createElement(
Container,
null,
'It is a test!'
);
};

CSS module

CSS moduleÔò×î´ó»¯µØ½áºÏÁËÏÖÓÐCSSÉú̬ºÍJSÄ£¿é»¯µÄÄÜÁ¦£¬ÒÔǰÓÃÓÚCSSµÄ¼¼Êõ¶¼¿ÉÒÔ¼ÌÐøÊ¹Óá£CSS module×îÖջṹ½¨³öÁ½¸öÎļþ£ºÒ»¸ö.cssÎļþºÍÒ»¸ö.js¡£

½â¾öÈ«¾ÖÃüÃûÎÛȾµÄÎÊÌ⣻

ĬÈÏÊǾֲ¿µÄ£¬¿ÉÒÔÓÃ:globalÉùÃ÷È«¾ÖÑùʽ£»

ÊÜCSSµÄÏÞÖÆ£¬Ö»ÄÜÒ»²ãǶÌ×£¬ºÍJSÎÞ·¨¹²Ïí±äÁ¿£»

ÄÜÖ§³ÖÏÖÔÚËùÓеÄCSS¼¼Êõ¡£

ÒÔwebpackΪÀý£¬Ê¹ÓÃcss-loader¾Í¿ÉÒÔʵÏÖCSS module£º

/* style.css */
.color {
color: green;
}
:local .className .subClass :global(.global-class-name) {
color: blue;
}

 

/* component.js */
import styles from './style.css';
elem.outerHTML = `<h1 class=${styles.color}>It is a test title</h1>`;

 

¹¹½¨ÔËÐкóÉú³ÉµÄdom½á¹¹ÈçÏ£º

<h1 class="style__color--rUMvq">It is a test title</h1>

component.jsÖÐstyles±äÁ¿µÄÖµÈçÏ£¬ÎÒÃÇ¿´µ½ÉùÃ÷³É:globalµÄÀàÃû.global-class-nameûÓб»×ª»»£¬¾ßÓÐÈ«¾Ö×÷ÓÃÓò¡£

const styles = {
"color": "style__color--rUMvq",
"className": "style__className--3n_7c",
"subClass": "style__subClass--1lYnt"
}

˵Ã÷£ºReact¶ÔÑùʽÈçºÎ¶¨Ò岢ûÓÐÃ÷ȷ̬¶È£¬ÎÞÂÛÊÇBEM¹æ·¶£¬»¹ÊÇCSS in JS»òÕßCSS module¶¼ÊÇÖ§³ÖµÄ£¬Ñ¡ÔñºÎÖÖ·½°¸ÊÇ¿ª·¢Õß×ÔÐоö¶¨µÄ¡£

×é¼þ»¯

×î³õ£¬ÍøÒ³¿ª·¢Ò»°ã¶¼»á×ñÑ­Ò»¸öÔ­Ôò¡±¹Ø×¢µã·ÖÀ롱£¬¸÷¸ö¼¼ÊõÖ»¸ºÔð×Ô¼ºµÄÁìÓò£¬²»ÄÜ»ìºÏÔÚÒ»Æð£¬ÐγÉñîºÏ¡£HTMLÖ»¸ºÔð½á¹¹£¬CSS¸ºÔðÑùʽ£¬JS¸ºÔðÂß¼­ºÍ½»»¥£¬ÈýÕßÍêÈ«¸ôÀ룬²»ÌᳫдÐÐÄÚÑùʽ£¨inline style£©ºÍÐÐÄڽű¾£¨inline script£©¡£ReactµÄ³öÏÖ´òÆÆÁËÕâÖÖÔ­Ôò£¬ËüµÄ¿¼ÂÇά¶È±ä³ÉÁËÒ»¸ö×é¼þ£¬ÒªÇó°Ñ×é¼þÏà¹ØµÄHTML¡¢CSSºÍJSдÔÚÒ»Æð£¬ÕâÖÖ˼Ïë¿ÉÒԺܺõؽâ¾ö¸ôÀëµÄÎÊÌ⣬ÿ¸ö×é¼þÏà¹ØµÄ´úÂë¶¼ÔÚÒ»Æð£¬±ãÓÚά»¤ºÍ¹ÜÀí¡£

ÎÒÃÇ»ØÏëÒ»ÏÂÔ­ÓÐÒýÓÃ×é¼þµÄ²½Ö裺

ÒýÈëÕâ¸ö×é¼þµÄJS£»

ÒýÈëÕâ¸ö×é¼þµÄÑùʽCSS£¨Èç¹ûÓУ©£»

ÔÚÒ³ÃæÖÐÒýÈëÕâ¸ö×é¼þµÄ£»

×îºóÊDZàд³õʼ»¯×é¼þµÄ´úÂë¡£

ÕâÖÖÒýÈ뷽ʽºÜ·±Ëö£¬Ò»¸ö×é¼þµÄ´úÂë·Ö²¼ÔÚ¶à¸öÎļþÀïÃæ£¬¶øÇÒ×÷ÓÃÓò±©Â¶ÔÚÈ«¾Ö£¬È±·¦ÄÚ¾ÛÐÔÈÝÒײúÉú³åÍ»¡£

×é¼þ»¯¾ÍÊǽ«Ò³Ãæ½øÐÐÄ£¿é²ð·Ö£¬½«Ä³Ò»²¿·Ö¶ÀÁ¢³öÀ´£¬¶à¸ö×é¼þ¿ÉÒÔ×ÔÓÉ×éºÏÐγÉÒ»¸ö¸ü¸´ÔÓµÄ×é¼þ¡£×é¼þ½«Êý¾Ý¡¢ÊÓͼºÍÂß¼­·â×°ÆðÀ´£¬½ö½ö±©Â¶³öÐèÒªµÄ½Ó¿ÚºÍÊôÐÔ£¬µÚÈý·½¿ÉÒÔÍêÈ«ºÚºÐµ÷Ó㬲»ÐèҪȥ¹Ø×¢×é¼þÄÚ²¿µÄʵÏÖ£¬ºÜ´ó³Ì¶ÈÉϽµµÍÁËϵͳ¸÷¸ö¹¦ÄܵÄñîºÏÐÔ£¬²¢ÇÒÌá¸ßÁ˹¦ÄÜÄÚ²¿µÄ¾ÛºÏÐÔ¡£

1.React¡¢Vue¡¢Angular¡­

React¡¢Vue¡¢AngularµÈ¿ò¼ÜµÄÁ÷ÐÐÍÆ¶¯ÁËWeb×é¼þ»¯µÄ½ø³Ì¡£ËüÃǶ¼ÊÇÊý¾ÝÇý¶¯ÐÍ£¬²»Í¬ÓÚDOM²Ù×÷ÊÇË鯬µÄÃüÁîʽ£¬ËüÔÊÐí½«Á½¸ö×é¼þͨ¹ýÉùÃ÷ʽ±à³Ì½¨Á¢ÄÚÔÚÁªÏµ¡£

<!-- Êý¾ÝÇý¶¯µÄÉùÃ÷ʽDeclarative-->
<pagination
current={current} total={maxCount/20}
on-nav={this.nav(1)}>
</pagination>

<!-- DOM²Ù×÷µÄÃüÁîʽImprective -->
<pagination id='pagination'></pagination>
<script>
// »ñÈ¡ÔªËØ
var pagination = document.querySelector('#pagination');
// °ó¶¨Ê¼þ
pagination.addEventListener('pagination-nav', function(event){
...
})
// ÉèÖÃÊôÐÔ
$.ajax('/blogs').then(function( json ){
pagination.setAttribute('current', 0)
pagination.setAttribute('total', json.length / 20)
})
</script>

´ÓÉÏÃæµÄÀý×Ó¿ÉÒÔ¿´µ½£¬ÉùÃ÷ʽ±à³ÌÈÃ×é¼þ¸ü¼òµ¥ÁË£¬ÎÒÃDz»ÐèҪȥ¼Çס¸÷ÖÖDOMÏà¹ØµÄAPI£¬ÕâЩȫ²¿½»¸ø¿ò¼ÜÀ´ÊµÏÖ£¬¿ª·¢Õß½ö½öÐèÒªÉùÃ÷ÿ¸ö×é¼þ¡°ÏëÒª»­³ÉʲôÑù×Ó¡±¡£

JSX vs Ä£°åDSL

ReactʹÓÃJSX£¬·Ç³£Áé»î£¬ÓëJSµÄ×÷ÓÃÓòÒ»Ö¡£Vue¡¢Angular²ÉÓÃÄ£°åDSL£¬¿É±à³ÌÐÔÊܵ½ÏÞÖÆ£¬×÷ÓÃÓòºÍJSÊǸôÀëµÄ£¬µ«Ò²ÊÇÕâ¸öȱµãʹµÃÎÒÃÇ¿ÉÒÔÔÚ¹¹½¨ÆÚ¼ä¶ÔÄ£°å×ö¸ü¶àµÄÊÂÇ飬±ÈÈ羲̬·ÖÎö¡¢¸üºÃµØ´úÂë¼ì²é¡¢ÐÔÄÜÓÅ»¯µÈµÈ¡£¶þÕß¶¼Ã»ÓÐä¯ÀÀÆ÷Ô­ÉúÖ§³Ö£¬ÐèÒª¾­¹ýTransform²ÅÄÜÔËÐС£

2.Web Component

Web ComponentÊÇW3CרÃÅΪ×é¼þ»¯´´½¨µÄ±ê×¼£¬Ò»Ð©Shadow DOMµÈÌØÐÔ½«³¹µ×µÄ¡¢´Óä¯ÀÀÆ÷µÄ²ãÃæ½â¾öµôһЩ×÷ÓÃÓòµÄÎÊÌ⣬¶øÇÒд·¨Ò»Ö£¬ËüÓм¸¸ö¸ÅÄ

Custom Element£º ´øÓÐÌØ¶¨ÐÐΪÇÒÓû§×ÔÃüÃûµÄ HTML ÔªËØ£¬À©Õ¹HTMLÓïÒ壻

<x-foo>Custom Element</x-foo>

 

/* ¶¨ÒåÐÂÔªËØ */
var XFooProto = Object.create(HTMLElement.prototype);
// ÉúÃüÖÜÆÚÏà¹Ø
XFooProto.readyCallback = function() {
this.textContent = "I'm an x-foo!";
};
// ÉèÖÃ JS ·½·¨
XFooProto.foo = function() { alert('foo() called'); };
var XFoo = document.register('x-foo', { prototype: XFooProto });
// ´´½¨ÔªËØ
var xFoo = document.createElement('x-foo');

 

Shadow DOM£º¶Ô±êÇ©ºÍÑùʽµÄÒ»²ã DOM ·â×°£¬¿ÉÒÔʵÏÖ¾Ö²¿×÷ÓÃÓò£»µ±ÉèÖÃ{mode: closed}ºó£¬Ö»ÓÐÆäËÞÖ÷²Å¿É¶¨ÒåÆä±íÏÖ£¬ÍⲿµÄapiÊÇÎÞ·¨»ñÈ¡µ½Shadow DOMÖеÄÈκÎÄÚÈÝ£¬ËÞÖ÷µÄÄÚÈݻᱻShadow DOMÑڸǡ£

var host = document.getElementById('js_host');
var shadow = host.attachShadow({mode: 'closed'});
shadow.innerHTML = '<p>Hello World</p>';

Chromeµ÷ÊÔ¹¤¾ß£ºDevTool > Settings > Preferences> Show user agent shadow DOM

Chromeµ÷ÊÔ¹¤¾ß²é¿´shadow DOM

HTML Template & Slots£º ¿É¸´ÓÃµÄ HTML ±êÇ©£¬ÌṩÁ˺ÍÓû§×Ô¶¨Òå±êÇ©Ïà½áºÏµÄ½Ó¿Ú£¬Ìá¸ß×é¼þµÄÁé»îÐÔ¡£¶¨ÒåÁËtemplateµÄ±êÇ©£¬ÀàËÆÎÒÃǾ­³£ÓõÄ<script type='tpl'>£¬Ëü²»»á±»½âÎöΪdomÊ÷µÄÒ»²¿·Ö£¬templateµÄÄÚÈÝ¿ÉÒÔ±»ÈûÈëµ½Shadow DOMÖв¢ÇÒ·´¸´Ê¹Óã»templateÖж¨ÒåµÄstyleÖ»¶Ô¸ÃtemplateÓÐЧ£¬ÊµÏÖÁ˸ôÀë¡£

<template id="tpl">
<style>
p {
color:red;
}
</style>
<p>hello world</p>
</template>
<script>
var host = document.getElementById('js_host');
var shadow = host.attachShadow({mode: 'open'});
var tpl = document.getElementById("tpl").content.cloneNode(true);
shadow.appendChild(tpl);
</script>

 

domÊ÷ÖеÄtemplate±êÇ©£¬²»½âÎö£º

HTML template-1

×îÖÕ²åÈëµÄÓ°×Ó½ÚµãЧ¹û£º

HTML template-2

ÓÉÓÚShadow DOMÖÐËÞÖ÷ÔªËØµÄÄÚÈݻᱻӰ×Ó½ÚµãÑڸǣ¬Èç¹ûÏ뽫ËÞÖ÷ÖÐijЩÄÚÈÝÏÔʾ³öÀ´µÄ»°¾ÍÐèÒª½èÖúslot£¬ËüÊǶ¨ÒåÔÚËÞÖ÷ºÍtemplateÖеÄÒ»¸ö²å²Û£¬ÓÃÀ´¡°Õ¼Î»¡±¡£

<div id="host">
<span>Test1</span>
<span slot="s1">slot1</span>
<span slot="s2">slot2</span>
<span>Test2</span>
</div>
<template id="tpl">
<span>tpl1</span>
<slot name="s1"></slot>
<slot name="s2"></slot>
<span>tpl2</span>
</template>

ËÞÖ÷ÔªËØÖÐÉèÖÃÁËslotÊôÐԵĽڵ㱻¡°±£Áô¡±ÁËÏÂÀ´£¬²¢ÇÒ²åÈëµ½ÁËtemplateÖж¨ÒåµÄslotµÄλÖá£

slotµÄʾÀý

HTML Imports£º ´ò°ü»úÖÆ£¬½«HTML´úÂëÒÔ¼°Web Componnetµ¼Èëµ½Ò³ÃæÖУ¬Õâ¸ö¹æ·¶Ä¿Ç°ÒѾ­²»ÔõÃ´ÍÆ¶¯ÁË£¬Ôڲο¼ÁËES6 moduleµÄ»úÖÆºó£¬FireFoxÍŶÓÒѾ­²»´òËã¼ÌÐøÖ§³Ö¡£

Polymer

PolymerÊÇ»ùÓÚWeb ComponetµÄÒ»ÖÖÊý¾ÝÇý¶¯ÐÍ¿ª·¢¿ò¼Ü£¬¿ÉÒÔʹÓÃES6 classÀ´¶¨ÒåÒ»¸öWeb Component£¬ÓÉÓÚÏÖÔÚä¯ÀÀÆ÷¶ÔWeb ComponentµÄÖ§³Ö¶È»¹²»ÊǺܺã¬ÐèÒªÒýÈëһЩpolyfill²ÅÄÜʹÓá£

ReactºÍWeb Component²¢²»ÊǶÔÁ¢µÄ£¬ËüÃǽâ¾ö×é¼þ»¯µÄ½Ç¶ÈÊDz»Í¬£¬¶þÕß¿ÉÒÔÏ໥²¹³ä¡£ÓëWeb Component²»Í¬µÄÊÇReactÖеÄHTML±êÇ©ÔËÐÐÔÚVirtual DOMÖУ¬ÔڷDZê×¼µÄä¯ÀÀÆ÷»·¾³£¬ReactµÄÕâÖÖ»úÖÆ¿ÉÒÔ¸üºÃµØÊµÏÖ¿çÆ½Ì¨£¬Web ComponentÔò¸üÓпÉÄÜʵÏÖä¯ÀÀÆ÷´óͳһ£¬ÊÇä¯ÀÀÆ÷¶Ë¸ü³¹µ×µÄÒ»ÖÖ½â¾ö·½°¸¡£

¹æ·¶»¯

¹æ·¶»¯ÊDZ£ÕÏÏîÄ¿ÖÊÁ¿µÄÒ»¸öÖØÒª»·½Ú£¬¿ÉÒԺܺõؽµµÍÍŶÓÖиöÌåµÄ²îÒìÐÔ¡£

1.´úÂë¹æ·¶

´úÂë¹æ·¶ÊÇÒ»¸öÀÏÉú³£Ì¸µÄ»°Ì⣬ÎÒÃÇÐèÒªÖÆ¶¨Ò»Ð©Ô­ÔòÀ´Í³Ò»´úÂë·ç¸ñ£¬ËäÈ»²»×ñÊØ¹æ·¶µÄ´úÂëÒ²ÊÇ¿ÉÒÔÔËÐе쬵«ÊÇÕâ»á¶Ô´úÂëµÄά»¤´øÀ´ºÜ¶àÂé·³¡£

Lint

¸ù¾Ýά»ù°Ù¿ÆµÄ½éÉÜ£¬Ê×ÏÈ¿´Ò»ÏÂlintµÄ¶¨Ò壺

lint×î³õÊÇÒ»¸öÌØ¶¨³ÌÐòµÄÃû³Æ£¬ËüÔÚCÓïÑÔÔ´´úÂëÖбê¼ÇÁËһЩ¿ÉÒɵĺͲ»¿ÉÒÆÖ²µÄ¹¹Ô죨¿ÉÄÜÊÇbug£©¡£Õâ¸öÊõÓlint»òÕßlinter£©ÏÖÔÚÒ»°ãÓÃÓڳƺôÄÇЩ¿ÉÒÔ±ê¼ÇÈκμÆËã»úÓïÑÔ±àдµÄÈí¼þÖпÉÒÉÓ÷¨µÄ¹¤¾ß£¬ÕâЩ¹¤¾ßͨ³£Ö´ÐÐÔ´´úÂëµÄ¾²Ì¬·ÖÎö¡£

Ò»°ã´úÂëµÄLinter¹¤¾ßÌṩÏÂÃæÁ½´óÀàµÄ¹æÔò£º

¸ñʽ»¯¹æÔò£º±ÈÈç max-len, no-mixed-spaces-and-tabsµÈµÈ£¬ÕâЩ¹æÔòÖ»ÊÇÓÃÀ´Í³Ò»Êéд¸ñʽµÄ¡£

´úÂëÖÊÁ¿¹æÔò£º±ÈÈç no-unused-vars, no-extra-bind, no-implicit-globalsµÈµÈ£¬ÕâЩ¹æÔò¿ÉÒÔ°ïÖúÌáÉý´úÂëÖÊÁ¿£¬¼õÉÙbug¡£

ÔÚʵ¼ÊµÄÏîÄ¿ÖпÉÒÔÒýÈëlintµÄ»úÖÆÀ´ÌáÉý´úÂëÖÊÁ¿£¬¿ÉÒԲο¼GitHub ¹Ù·½³öÆ·µÄ Lint ¹¤¾ßÁÐ±í £¬ÏÂÃæ¼òµ¥½éÉܼ¸¸ö³£Óù¤¾ß¡£

Prettier

PrettierÊÇÒ»¸ö´úÂë¸ñʽ»¯¹¤¾ß£¬¿ÉÒÔͳһÍŶÓÖеÄÊéд·ç¸ñ£¬±ÈÏÂÃæEslintÕâÀ๤¾ßµÄ¹¦ÄÜÒªÈõ£¬ÒòΪֻÊǶԸñʽÉϵÄÔ¼Êø£¬ÎÞ·¨¶Ô´úÂëÖÊÁ¿½øÐмì²â¡£

ESlint

ESLintÊÇÒ»¿î·Ç³£³£ÓõÄJS±à³Ì¹æ·¶¿â£¬µ±È»»¹ÓкܶàÆäËûµÄlint¹¤¾ß¡£ÏÂÃæµÄ±í¸ñÀï¼òµ¥½éÉÜÁË3ÖÖ³£ÓõĹ淶±ê×¼£¬¿ÉÒÔÔÚESLintÖÐÅäÖÃÑ¡ÔñÄÄÒ»ÖÖ±ê×¼£¬Ã¿Ò»ÖÖ±ê×¼¶¼»á°üº¬ºÜ¶à±à³Ì¹æÔò¡£¸÷¸ö±ê׼ûÓоø¶ÔµÄÊëÓÅÊëÁÓ£¬Ñ¡ÔñÊÊÓÃÓÚÍŶӵıà³Ì·ç¸ñºÍ¹æ·¶¾ÍºÃ¡£

±ê×¼

¼ò½é

Airbnb JavaScript Style Guide

Ŀǰ×îÊÜ»¶Ó­µÄJS±à³Ì¹æ·¶Ö®Ò»£¬¶ÔºÜ¶àJS¿ò¼Ü¶¼ÓÐÖ§³Ö£¬±ÈÈçReactµÈ¡£

Google JavaScript Style Guide

Google StyleµÄJS±à³Ì¹æ·¶¡£

JavaScript Standard Style Guide

ºÜÇ¿´ó£¬×Ô´ølinterºÍ×Ô¶¯´úÂë¾ÀÕý£¬ÎÞÐèÅäÖã¬×Ô¶¯¸ñʽ»¯´úÂë¡£ºÜ¶àÖªÃû¹«Ë¾Ëù²ÉÓ㬱ÈÈç Nodejs¡¢npm¡¢express¡¢GitHub¡¢mongoDB µÈ¡£

husky

Èç¹ûÎÒÃǰÑLint·ÅÔÚÁ˳ÖÐø¼¯³ÉCI½×¶Î£¬¾Í»áÓöµ½ÕâÑùÒ»¸öÎÊÌ⣺CIϵͳÔÚLintʱ·¢ÏÖÁËÎÊÌâµ¼Ö¹¹½¨Ê§°Ü£¬Õâ¸öʱºòÎÒÃÇÐèÒª¸ù¾Ý´íÎóÖØÐÂÐ޸ĴúÂ룬ȻºóÖØ¸´Õâ¸ö¹ý³ÌÖ±µ½Lint³É¹¦£¬Õû¸ö¹ý³Ì¿ÉÄÜ»áÀ˷ѵô²»ÉÙʱ¼ä¡£Õë¶ÔÕâ¸öÎÊÌ⣬ÎÒÃÇ·¢ÏÖÖ»ÔÚCI½×¶Î×öLintÊDz»¹»µÄ£¬ÐèÒª°ÑLintÌáǰµ½±¾µØÀ´Ëõ¶ÌÕû¸öÐÞ¸ÄÁ´Â·¡£µ«Êǽ«Lint·ÅÔÚ±¾µØ½ö½öÒÀ¿¿¿ª·¢ÕßµÄ×Ô¾õ×ñÊØÊDz»¹»µÄ£¬ÎÒÃÇÐèÒª¸üºÃµÄ·½°¸£¬ÐèÒªÒÀ¿¿Á÷³ÌÀ´±£Õ϶ø²»ÊÇÈ˵Ä×Ô¾õÐÔ¡£

LintµÄÎÊÌâ

husky¿ÉÒÔ×¢²ágit hooks£¬À¹½ØÒ»Ð©´íÎóµÄÌá½»£¬±ÈÈçÎÒÃǾͿÉÒÔÔÚpre-commitÕâ¸öhookÖÐÔö¼ÓLintµÄУÑ飬ÕâÀï¿ÉÒԲ鿴֧³ÖµÄgit hooks¡£

lint-staged

ͨ¹ýhusky×¢²áµÄgit hook»á¶Ô²Ö¿âÖеÄÈ«²¿Îļþ¶¼Ö´ÐÐÉèÖõÄnpmÃüÁµ«ÎÒÃǽö½öÐèÒª¶ÔÌá½»µ½stagedÇøµÄÎļþ½øÐд¦ÀíÀ´¼õÉÙУÑéʱ¼ä£¬lint-staged¿ÉÒÔ½áºÏhuskyʵÏÖÕâ¸ö¹¦ÄÜ£¬ÔÚpackage.jsonÖеÄʾÀý£º

ÀàÐͼì²é

JavaScriptÊǷdz£Áé»îµÄ£¬ÕâµÃÒæÓÚËüµÄÈõÀàÐÍÓïÑÔÌØµã£¬µ«Ò²ÊÇÒòΪÕâ¸öÔ­Òò£¬ÎÒÃÇÖ»ÓÐÔÚÔËÐÐʱ²ÅÖªµÀ±äÁ¿µ½µ×ÊÇʲôÀàÐÍ£¬ÎÞ·¨ÔÚ±àÒë½×¶Î×÷³öÈκÎÀàÐÍ´íÎóµÄÌáʾ£¬Í¬Ê±ÓÉÓÚº¯Êý²ÎÊýÀàÐ͵IJ»È·¶¨ÐÔ£¬±àÒëÆ÷µÄ±àÒë½á¹ûºÜ¿ÉÄÜÎÞ·¨±»¸´Ó㬱ÈÈçÏÂÃæµÄÀý×ÓÖУ¬ÔÚÖ´ÐÐadd(1,2)ʱ¶Ôaddº¯ÊýµÄ±àÒë½á¹ûÎÞ·¨Ö±½Ó±»ÏÂÃæµÄadd('1', '2')¸´Ó㬵ڶþ´Îµ÷ÓñØÐëµÃÔÙÖØÐ±àÒëÒ»´Î£¬Õâ¶ÔÐÔÄÜÒ²ÊÇÓкܴóÓ°Ïì¡£

function add(a, b) {
return a + b;
}
add(1, 2);
add('1', '2');

ÀàÐͼì²é¿ÉÒÔÈÃÎÒÃDZàд³ö¸ü¸ßÖÊÁ¿µÄ´úÂ룬¼õÉÙÀàÐÍ´íÎóµÄbug£¬Í¬Ê±Ã÷È·ÁËÀàÐÍÒ²ÈôúÂë¸üºÃά»¤¡£

PropTypes

ReactÔÚ15.5µÄ°æ±¾ºó½«ÀàÐͼì²éReact.PropTypesÒÆ³ýºóʹÓÃprop-types¿â´úÌæ£¬ËüÊÇÒ»ÖÖÔËÐÐʱµÄÀàÐͼì²â»úÖÆ£¬°üº¬Ò»ÕûÌ×ÑéÖ¤Æ÷£¬¿ÉÓÃÓÚÈ·±£×é¼þÊôÐÔ½ÓÊÕµÄÊý¾ÝÊÇÕýÈ·µÄÀàÐÍ¡£

import React, { Component } from 'react';
import PropTypes from 'prop-types';
class App extends Component {
}
App.propTypes = {
title: PropTypes.string.isRequired
}

Flow

ºÍPropTypes²»Í¬£¬FlowÊÇÒ»ÖÖ¾²Ì¬ÀàÐͼì²éÆ÷£¬ÓÉFacebook¿ªÔ´£¬¸³ÓèJSÇ¿ÀàÐ͵ÄÄÜÁ¦£¬ÔÚ±àÒë½×¶Î¾Í¿ÉÒÔ¼ì²â³öÊÇ·ñÓÐÀàÐÍ´íÎ󣬿ÉÒÔ±»ÓÃÓÚÈκÎJavaScriptÏîÄ¿¡£

FlowÖ÷ÒªÓÐÁ½¸ö¹¤×÷·½Ê½£º

ÀàÐÍÍÆ¶Ï£ºÍ¨¹ý±äÁ¿µÄʹÓÃÉÏÏÂÎÄÀ´Íƶϳö±äÁ¿ÀàÐÍ£¬È»ºó¸ù¾ÝÕâÐ©ÍÆ¶ÏÀ´¼ì²éÀàÐÍ¡£

ÀàÐÍ×¢ÊÍ£ºÊÂÏÈ×¢ÊͺÃÎÒÃÇÆÚ´ýµÄÀàÐÍ£¬Flow»á»ùÓÚÕâЩעÊÍÀ´Åжϡ£

function split(str) {
return str.split(' ')
}
split(11);
function square(n: number): number {
return n * n;
}
square("2");

Flow·ç¸ñµÄ´úÂë²»ÄÜÖ±½ÓÔÚJSÔËÐл·¾³ÖÐÖ´ÐУ¬ÐèҪʹÓÃbabel½øÐÐת»»¡£¾ÍĿǰµÄ·¢Õ¹ºÍÉú̬¶øÑÔ£¬FlowÀëTypeScriptµÄ²î¾àÒѾ­Ô½À´Ô½Ò£Ô¶ÁË£¬VueÔÚ2.0°æ±¾¿ªÊ¼Ê¹ÓÃflow.js£¬µ«´Ó3.0ÆðÒѾ­Ìæ»»³ÉÁËTypeScript¡£

TypeScript

TypeScriptÔòÊÇÒ»ÖÖJavaScriptÓïÑԵij¬¼¯£¬Ç¿ÀàÐÍ¡¢Ö§³Ö¾²Ì¬ÀàÐͼì²é£¬¸üÏñÊÇÒ»ÃÅ¡°ÐÂÓïÑÔ¡±¡£DenoÒѾ­Ö§³ÖÖ±½ÓÔËÐÐtcsÁË£¬²»ÐèÒª½øÐÐת»»¡£


interface Person {
firstName: string;
lastName: string;
}
function greeter(person: Person) {
return "Hello, " + person.firstName + " " + person.lastName;
}

2.Îĵµ¹æ·¶

¸ßÖÊÁ¿µÄÏîÄ¿Îĵµ¿ÉÒÔÌá¸ßÍŶÓЭ×÷ЧÂÊ£¬±ãÓÚºóÆÚÓÅ»¯Î¬»¤¡£Î¬»¤ÎĵµºÜÖØÒª£¬µ«ÊÇÒ²ºÜ·±Ëö£¬ÎÒÃǾ­³£»á¿´µ½´úÂëºÍÎĵµÄÏÔ¯±±ÕÞ»¥Ïàì¶Ü£¬ÏÂÃæ½éÉܼ¸ÖÖÎĵµ¹¹½¨¹¤¾ß£¬ËüÃÇ¿ÉÒԺܺõذïÖúÎÒÃǹ¹½¨Îĵµ£¬¶ø¶ÔÓÚReact¡¢VueµÈ×é¼þ¶øÑÔ£¬Ê¹ÓÃMDX¿ÉÒԷdz£±ã½Ý¹¹½¨demo£¬¼«´ó¼õÉÙÈ˹¤±£Ö¤´úÂëºÍÎĵµÒ»ÖÂÐԵŤ×÷£º

JSDoc£º¸ù¾Ý.jsÎļþÖеÄ×¢ÊÍÐÅÏ¢£¬Éú³ÉAPIÎĵµ¡£

Docz£º»ùÓÚMDXµÄ¸ßЧ¡¢ÁãÅäÖõÄÎĵµÉú³É¹¤¾ß£¬Ä¿Ç°½öÖ§³ÖReact¡£

Storybook£º¼¯×é¼þ¿ª·¢¡¢²é¿´¡¢²âÊÔµÄÎĵµ¹¤¾ß£¬Ö§³ÖReact¡¢RN¡¢Vue¡¢Angular¡¢PolymerµÈºÜ¶à¿ò¼Ü£¬·Ç³£Ç¿´ó¡£

react-styleguidist£ººÍStorybookÀàËÆ£¬Éú³ÉReact×é¼þ¿ª·¢»·¾³µÄÎĵµ·þÎñ£¬»ùÓÚwebpackÖ§³ÖHRM¡£

3.Á÷³Ì¹æ·¶

µ±ÍŶÓÔÚ¿ª·¢Ê±£¬Í¨³£»áʹÓð汾¿ØÖÆÏµÍ³À´¹ÜÀíÏîÄ¿£¬³£ÓõÄÓÐsvnºÍgit£¬ÈçºÎºÏ²¢´úÂë¡¢ÈçºÎ·¢²¼°æ±¾¶¼ÐèÒªÏàÓ¦µÄÁ÷³Ì¹æ·¶£¬Õâ¿ÉÒÔÈÃÎÒÃǹæ±ÜºÜ¶àÎÊÌ⣬±ÈÈçºÏ²¢´úÂëºó³öÏÖ´úÂ붪ʧ£¬ÓÖ»òÕß½«±ðÈËδ¾­²âÊԵĴúÂë·¢²¼³öÈ¥µÈµÈ¡£ÏÂÃæÖ÷Òª½éÉܼ¸ÖÖ»ùÓÚgitµÄЭ×÷¿ª·¢Ä£Ê½£º

github-flow

ÒÔ²¿ÊðΪÖÐÐĵĿª·¢Ä£Ê½£¬³ÖÐøÇÒ¸ßËÙ°²È«µØ½øÐв¿Ê𣬾ßÌåÁ÷³ÌÈçÏ£º

master·ÖÖ§Ò»Ö±Êǿɲ¿ÊðµÄ״̬£¬ÕâÒâζ×Ų»ÒªÖ±½ÓÔÚmaster·ÖÖ§ÉϽøÐÐpush²Ù×÷£»

ÿ´Î¿ª·¢¶¼´Ómaster·ÖÖ§´´½¨Ò»¸öеÄÌØÐÔ·ÖÖ§£¬ÃüÃûÐèÒªÓк¬Ò壻

ÔÚÔ¶¶Ë´´½¨¶ÔÓ¦µÄorigin/ÌØÐÔ·ÖÖ§£¬¶¨ÆÚpush£»

¿ª·¢²âÊÔÍê±ÏºóÐèÒªmergeµÄʱºò£¬´´½¨Pull Request½øÐн»Á÷£»

ÆäËû¿ª·¢ÕßreviewÕâ´ÎPull Request£¬È·ÈϺóÓëmaster·ÖÖ§½øÐкϲ¢¡£

Á¢¿Ì²¿ÊðºÏ²¢ºóµÄmaster·ÖÖ§´úÂ룬ɾ³ý¸Ã·ÖÖ§¡£

github-flowµÄ×î´óÌØµã¾ÍÊǼòµ¥£¬Ö»ÓÐÒ»¸ömaster³¤ÆÚ·ÖÖ§£¬µ«ÊÇÓÉÓÚÒª³ÖÐø²¿Ê𣬵±Ò»¸ö²¿Êð»¹Î´Íê³ÉµÄʱºò£¬ÍùÍùÏÂÒ»¸öPull RequestÒѾ­Íê³É£¬Õâ¾Íµ¼ÖÂÔÚ¿ª·¢ËÙ¶ÈÔ½À´Ô½¿ìµÄʱºò£¬±ØÐëÒªÈò¿ÊðËùÐèµÄһϵÁÐÁ÷³Ì¶¼ÊÇ×Ô¶¯»¯µÄ£¬±ÈÈçÓÐ×Ô¶¯»¯²âÊÔ¡¢½ÓÈëCIµÈ¡£

git-flow

ÓÐÁ½¸ö³¤ÆÚ·ÖÖ§masterºÍdevelop£¬ÕâÒâζ×Ų»ÒªÖ±½ÓÔÚÕâÁ½¸ö·ÖÖ§ÉϽøÐÐpush²Ù×÷£¬ËùÓеĿª·¢¶¼ÔÚfeature·ÖÖ§ÉϽøÐУ¬Ïê¼ûÎĵµ¡£

git-flow¹¤×÷Á÷

¹¦ÄÜ¿ª·¢£ºÊ×ÏÈ´Ódevelop·ÖÖ§´´½¨feature·ÖÖ§£¬È»ºóºÍÉÏÃægithub-flowµÄÁ÷³ÌÀàËÆ£¬¿ª·¢²âÊÔÍê±ÏºóÏòdevelop·ÖÖ§·¢ÆðPull Request£¬ÆäËû¿ª·¢ÕßreviewÍê±Ïºó½«´Ë´ÎPRºÏ²¢ÖÁdevelop·ÖÖ§¡£

¹ÜÀíRelease£ºµ±develop·ÖÖ§¿ÉÒÔreleaseµÄʱºò£¬Ê×ÏÈ´´½¨Ò»¸örelease/°æ±¾ºÅ·ÖÖ§£¬È»ºó¶ÔÕâ¸örelease·ÖÖ§´òÉÏtagºóÔٺϲ¢µ½developºÍmasterÖÐÈ¥¡£

hotfix£ºµ±³öÏÖÁ˽ô¼±bugµÄʱºò£¬ÐèÒª¿ªÆô¡°hotfix¡±Á÷³Ì£¬ºÍrelease²»Í¬µÄÊÇ£¬Õâ¸öhotfix·ÖÖ§ÊÇ»ùÓÚmaster´´½¨µÄ£¬ÐÞ¸´bugºóÌá½»µ½Õâ¸öhotfix·ÖÖ§£¬È»ºóÓÖºÍrelease·ÖÖ§µÄ´¦Àí·Ç³£ÀàËÆ£¬¸Ä¶¯»á±»Í¬Ê±ºÏ²¢µ½developºÍmasterÖÐÈ¥£¬×îºóÕâ¸öhotfix·ÖÖ§±»É¾³ýµô¡£

gitlab-flow

github-flowÓÐÒ»¸öÎÊÌ⣬ËüÒªÇómaster·ÖÖ§ºÍÉú²ú»·¾³ÊÇÍêȫһÖ£¬Ò»µ©PRͨ¹ý±»ºÏ²¢µ½ÁËmaster·ÖÖ§£¬¾ÍÒªÁ¢¿Ì²¿Êð·¢²¼µ½Éú³É»·¾³£¬µ«ÊÇÍùÍùÊÜÏÞÓÚ²úÆ··¢²¼Ê±¼ä£¬master·ÖÖ§ºÜ¿ÉÄÜ»áÏÈÓÚÉú²ú»·¾³£¬Õâ¸öʱºò²»ÄÜÒÀ¿¿master·ÖÖ§À´×·×ÙÏßÉϰ汾¡£

git-flowµÄÁ÷³Ì±È½Ï¸´ÔÓ£¬ÐèҪά»¤Á½¸ö³¤ÆÚ·ÖÖ§masterºÍdevelop£¬¿ª·¢¹ý³ÌÒªÒÔdevelop·Ö֧Ϊ׼£¬µ«ÊǺܶ࿪·¢¹¤¾ß½«masterµ±×öĬÈÏ·ÖÖ§£¬¾ÍÐèҪƵ·±Çл»·ÖÖ§¡£git-flowµÄģʽÊÇ»ùÓÚ¡°°æ±¾·¢²¼¡±£¬Õâ¶ÔһЩ³ÖÐø·¢²¼²¿ÊðµÄÏîÄ¿²»Ì«ÊÊÓá£

gitlab-flowÔòÊÇÉÏÃæÁ½¸ö¹¤×÷Á÷µÄ×ۺϣ¬ÍƳöÒ»¸ö¡°ÉÏÓÎÓÅÏÈ¡±µÄ×î´óÔ­Ôò£¬¼´Ö»´æÔÚÒ»¸ömasterÖ÷·ÖÖ§£¬ËüÊÇËùÓзÖÖ§µÄÉÏÓΣ¬Ö»Óкϲ¢µ½masterÉϵĴúÂë²ÅÄÜÓ¦Óõ½ÆäËû·ÖÖ§£¬Ïê¼ûÎĵµ¡£

³ÖÐø·¢²¼

¶ÔÓÚÕâÖÖģʽµÄÏîÄ¿£¬master·ÖÖ§¶ÔÓ¦¿ª·¢»·¾³£¬È»ºóÐèÒªÔÙ´´½¨pre-productionºÍproductionÁ½¸ö·ÖÖ§£¬ËüÃǵÄÉÏÓÎÁ´Â·ÒÀ´ÎÊÇ£ºmaster·ÖÖ§¡ª>pre-production·ÖÖ§¡ª>production·ÖÖ§£¬Ö»Óкϲ¢½øÈëmaster·ÖÖ§µÄ´úÂëÐ޸IJÅÄÜÒÀ´ÎÓ¦Óúϲ¢µ½¡±ÏÂÓΡ±¡£

°æ±¾·¢²¼

ÔÚÕâÖÖģʽÏ£¬Ê×ÏÈ»ùÓÚmaster·ÖÖ§´´½¨Ä³¸ö°æ±¾µÄstable·ÖÖ§£¬È»ºó½«´úÂë¸Ä¶¯ºÏ²¢½ømaster·ÖÖ§£¬µ±ÐèÒª·¢°æ±¾µÄʱºò£¬½«master·Ö֧ʹÓÃcherry-pickºÏ²¢µ½stable·ÖÖ§ÖÐÈ¥£¬È»ºó»ùÓÚstable·ÖÖ§½øÐÐÏîÄ¿µÄ·¢²¼²¿Êð¡£

×Ô¶¯»¯

×Ô¶¯»¯ÊÇǰ¶Ë¹¤³Ì»¯µÄÒ»¸öÖØÒª×é³É²¿·Ö£¬¿ÉÒÔ¼õÉÙÖØ¸´µÄ¹¤×÷£¬Ìá¸ß¹¤×÷ЧÂÊ¡£

1.¹¹½¨

ÔÚǰ¶ËÏîÄ¿¿ª·¢ÖÐÎÒÃÇʹÓÃÁËÄ£¿é»¯µÄ·½°¸£¬ÓпÉÄÜ»¹ÒýÈëÁË×é¼þ»¯µÄ»úÖÆ£¬ÒÀÀµÒ»Ð©¿ª·¢¿ò¼Ü£¬Õâ¸öʱºò¾ÍÐèÒª¶ÔÏîÄ¿½øÐй¹½¨£¬¹¹½¨Ò»°ã¿ÉÒÔ°üÀ¨Õ⼸¸ö²½Ö裺

´úÂëת»»£ºÔÊÐíʹÓøü¸ß¼¶µÄJavaScriptÓï·¨£¬±ÈÈçES6¡¢TypeScriptµÈµÈ£¬Õâ¶Ô´úÂëµÄ¿ª·¢ºÍ¿Éά»¤ÐÔÀ´ËµÊǷdz£Óкô¦µÄ¡£

Ä£¿éºÏ²¢£º°´Ä£¿é»¯¿ª·¢µÄ´úÂëÐèÒª½øÐдò°üºÏ²¢¡£

ÎļþÓÅ»¯£º³£¼ûµÄÓдúÂëѹËõºÍCode Splitting£¬Ê¹ÓÃES6 moduleµÄÄ£¿é»¯»úÖÆµÄ»¹¿ÉÒÔ¿¼Âǹ¹½¨¹¤¾ßµÄTree Shaking¹¦ÄÜ£¬½øÒ»²½¼õÉÙ´úÂëÌå»ý¡£

×Ô¶¯Ë¢Ð£ºÔÚ¿ª·¢¹ý³ÌÖÐÖ§³Öfile watchºÍHMR¶¼ÊÇ¿ÉÒԺܺõØÌáÉý¿ª·¢Ð§ÂÊ¡£

2.²âÊÔ

ÔÚÈí¼þµÄÉúÃüÖÜÆÚÖУ¬²»Í¬µÄ²âÊԽ׶Σ¬Õë¶ÔµÄ²âÊÔÎÊÌâÊDz»Ò»ÑùµÄ£º

µ¥Ôª²âÊÔ£ºÈ·±£Ã¿¸ö×é¼þ/Ä£¿éÕý³£¹¤×÷

¼¯³É²âÊÔ£ºÔÚµ¥Ôª²âÊԵĻù´¡ÉÏ£¬È·±£×é×°³ÉÄ£¿é¡¢×Óϵͳ»òϵͳµÄ¹ý³ÌÖи÷²¿·ÖÕý³£ºÏ×÷

ϵͳ²âÊÔ£ºÔÚ¼¯³É²âÊԵĻù´¡ÉÏ£¬È·±£Õû¸öÓ¦ÓÃÔËÐÐÕý³£

ÑéÊÕ²âÊÔ£ºÒ²³Æ½»¸¶²âÊÔ£¬ÊÇÕë¶ÔÓû§ÐèÇó¡¢ÒµÎñÁ÷³Ì½øÐеÄÕýʽµÄ²âÊÔ£¬ÒÔ±£Ö¤´ïµ½ÑéÊÕ±ê×¼

JavaScript µ¥Ôª²âÊÔ£¬ÎÒÃÇÕæµÄÐèÒªÂ𣿴ð°¸ÊÇÐèÒª½áºÏÏîÄ¿¿´Êµ¼ÊÇé¿ö¡£Èç¹ûÊÇ»ù´¡¿â»òÕß¹«¹²×é¼þÕâÑùµÄÏîÄ¿£¬µ¥Ôª²âÊÔ»¹ÊǺÜÓбØÒªµÄ¡£¶ø¶ÔÓÚÄÇÖÖ¾ÍÉÏÏß¼¸ÌìµÄ»î¶¯Ò³£¬Ð´ÏêϸµÄµ¥Ôª²âÊÔ¿ÉÄÜÕæµÄ»áÓеãÈë²»·ó³ö¡£ÒýÓÃÕâÆªÎÄÕ½áβ´¦ÊÇ˼¿¼£º

¡°Ôõôµ¥Ôª²âÊÔдÆðÀ´ÕâôÂé·³¡±

¡ª¡ªËµÃ÷ÏîĿģ¿éÖ®¼ä´æÔÚñîºÏ¶È¸ß£¬ÒÀÀµÐÔÇ¿µÄÎÊÌâ¡£

¡°ÔõôҪдÕâô³¤µÄ²âÊÔ´úÂë°¡¡±

¡ª¡ªÕâÊÇÒ»ÀÍÓÀÒݵ쬲¢ÇÒÿ´ÎÐèÇó±ä¸üºó£¬Äã¶¼¿Éͨ¹ýµ¥Ôª²âÊÔÀ´ÑéÖ¤£¬Âß¼­´úÂëÊÇ·ñÒÀ¾ÉÕýÈ·¡£

¡°ÎÒµÄÄ£¿éûÎÊÌâµÄ£¬ÊÇÄãµÄÄ£¿é³öÁËÎÊÌ⡱

¡ª¡ª³ÌÐòÖÐÿһÏÄÜÎÒÃǶ¼ÓòâÊÔÀ´ÑéÖ¤µÄËüµÄÕýÈ·ÐÔ£¬¿ìËÙ¶¨Î»³öÏÖÎÊÌâµÄijһ»·¡£

¡°ÉÏ´ÎÐÞ¸´µÄ bug ÔõôÓÖ³öÏÖÁË ¡±

¡ª¡ªµ¥Ôª²âÊÔÄܹ»±ÜÃâ´úÂë³öÏֻع飬±àдÍê³Éºó£¬¿É¿ìËÙÔËÐвâÊÔ¡£

TDD £¨²âÊÔÇý¶¯¿ª·¢Test-Driven Development£©ºÍ BDD £¨ÐÐΪÇý¶¯¿ª·¢Behavior Driven Development£©ÊÇÁ½ÖÖ¿ª·¢Ä£Ê½£¬²¢²»Êǵ¥µ¥Ö¸ÈçºÎ½øÐдúÂë²âÊÔ£¬ËüÃǶ¨ÒåÁËÒ»ÖÖÈí¼þ¿ª·¢Ä£Ê½À´½«Óû§ÐèÇ󡢿ª·¢ÈËÔ±ºÍ²âÊÔÈËÔ±½øÐÐÓÐЧµÄÁªºÏ£¬¼õÉÙÈýÕßÖ®¼äµÄÍѽڡ£TDDÒªÇ󿪷¢ÕßÏÈд²âÊÔÓÃÀý£¬È»ºó¸ù¾Ý²âÊÔÓÃÀýµÄ½á¹ûÔÙÐ´ÕæÕýʵÏÖ¹¦ÄܵĴúÂ룬½ÓÏÂÀ´¼ÌÐøÔËÐвâÊÔÓÃÀý£¬ÔÙ¸ù¾Ý½á¹ûÐÞ¸´´úÂ룬¸Ã¹ý³ÌÖØ¸´¶à´Î£¬Ö±µ½Ã¿¸ö²âÊÔÓÃÀýÔËÐÐÕýÈ·¡£BDDÔòÊǶÔTDDµÄÒ»ÖÖ²¹³ä£¬ÎÒÃÇÎÞ·¨±£Ö¤ÔÚTDDÖеIJâÊÔÓÃÀý¿ÉÒÔÍêÈ«´ïµ½Óû§µÄÆÚÍû£¬ÄÇôBDD¾ÍÒÔÓû§ÆÚÍûΪÒÀ¾Ý£¬´ÓÓû§µÄÐèÇó³ö·¢£¬Ç¿µ÷ϵͳÐÐΪ¡£¾ßÌåÇø±ð¿ÉÒÔÏê¼ûÎÄÕÂThe Difference Between TDD and BDD¡£

ǰ¶ËÈçºÎ×öµ¥Ôª²âÊÔ£¿

²âÊÔ»·¾³

ºÍºó¶Ë²»Í¬£¬Ç°¶ËÓÐÔËÐл·¾³µÄ²îÒìÐÔ£¬ÐèÒª¿¼ÂǼæÈÝÐÔ£¬ÈçºÎÄ£Äâä¯ÀÀÆ÷»·¾³£¬ÈçºÎÖ§³Öµ½BOM APIµÄµ÷Óã¬ÕâЩ¶¼ÊÇÐèÒª¿¼Âǵġ£¿ÉÒÔ¿¼ÂÇÒÔϼ¸ÖÖ²âÊÔ»·¾³µÄ½â¾ö·½°¸£º

ÔËÐл·¾³

ÌØµã

jsdom

node¶ËÖ±½ÓÔËÐУ¬Î±ä¯ÀÀÆ÷»·¾³£¬Ëٶȿ죬ÄÚÖÃBOM¶ÔÏó£¬Ä¿Ç°Ò²ÓÐÁ˶ÔsessionStorage¡¢localStorageºÍcookieµÄÖ§³Ö¡£

puppeteer

ÔÚÕæÊµµÄä¯ÀÀÆ÷ÖÐÔËÐвâÊÔ£¬ºÜ·½±ã£¬µ«ÊÇÔËÐÐËÙ¶È»áÂýÒ»µã¡£

phantomjs

ÌØÎÞÍ·ä¯ÀÀÆ÷£¬ÔÚpuppeteer·¢²¼ºó£¬×÷ÕßÒѾ­Ðû²¼²»Î¬»¤ÁË¡£

²âÊÔ¹¤¾ß

²âÊÔ¿ò¼Ü¾ÍÊÇÔËÐвâÊÔÓÃÀýµÄ¹¤¾ß£¬³£¼ûµÄÓÐMacha¡¢Jasmine¡¢Jest¡¢AVAµÈµÈ¡£

¶ÏÑÔ¿âÖ÷ÒªÌṩÓïÒ廯·½·¨£¬ÓÃÓÚ¶Ô²ÎÓë²âÊÔµÄÖµ×ö¸÷ÖÖ¸÷ÑùµÄÅжϡ£ÕâЩÓïÒ廯·½·¨»á·µ»Ø²âÊԵĽá¹û£¬ÒªÃ´³É¹¦¡¢ÒªÃ´Ê§°Ü¡£NodeÄÚÖöÏÑÔ¿âassert£¬³£¼ûµÄ¶ÏÑԿ⻹ÓÐÓÐchai.js¡¢should.js¡£¶ÏÑÔ¿â¿ÉÒÔÖ§³Ö²»Í¬µÄ¿ª·¢Ä£Ê½£¬±ÈÈçchai.js¾ÍÊÇÒ»¸öBDD/TDDģʽµÄ¶ÏÑÔ¿â¡£

²âÊÔ¸²¸ÇÂʹ¤¾ßÊÇÓÃÓÚͳ¼Æ²âÊÔÓÃÀý¶Ô´úÂëµÄ²âÊÔÇé¿ö£¬Éú³ÉÏàÓ¦µÄ±¨±í£¬ÈçIstanbul(JestÄÚÖü¯³É)¡£

KarmaÊÇÒ»¸ö²âÊÔÆ½Ì¨£¬¿ÉÒÔÔÚ¶àÖÖÕæÊµä¯ÀÀÆ÷£¨e.g Chrome Firefox Safari IEµÈµÈ£©ÖÐÔËÐÐJavaScript´úÂ룬¿ÉÒԺͺܶà²âÊÔ¿ò¼Ü¼¯³É£¬±ÈÈçMocha¡¢JasmineµÈµÈ£¬»¹¿ÉÒÔʹÓÃIstanbul×Ô¶¯Éú³É¸²¸ÇÂʱ¨¸æ¡£

CI/CD

Ê×ÏÈÏÈ¿´Ò»ÕÅͼƬ£¬À´Àí½âAgile(Ãô½Ý¿ª·¢)¡¢CI(³ÖÐø¼¯³É)£¬CD(³ÖÐø½»¸¶/²¿Êð)ºÍDevOps(¿ª·¢ÔËάһÌ廯)º­¸ÇµÄÉúÃüÖÜÆÚ·¶Î§¡£CI/CD²¢²»µÈͬÓÚDevOps£¬ËüÃÇÖ»ÊÇDevOpsµÄ²¿·ÖÁ÷³ÌÖеÄÒ»ÖÖ½â¾ö·½°¸¡£

DevOpsÊÇDevelopmentºÍOperationsµÄ×éºÏ£¬ÊÇÒ»ÖÖ·½·¨ÂÛ£¬ÊÇÒ»×é¹ý³Ì¡¢·½·¨ÓëϵͳµÄͳ³Æ£¬ÓÃÓÚ´Ù½øÓ¦Óÿª·¢¡¢Ó¦ÓÃÔËάºÍÖÊÁ¿±£ÕÏ£¨QA£©²¿ÃÅÖ®¼äµÄ¹µÍ¨¡¢Ð­×÷ÓëÕûºÏ¡£ÒÔÆÚ´òÆÆ´«Í³¿ª·¢ºÍÔËÓªÖ®¼äµÄ±ÚÀݺͺ蹵¡£

¸÷¸öÊõÓﺭ¸ÇµÄÉúÃüÖÜÆÚ·¶Î§

³ÖÐø¼¯³É£¨Continuous Integration£©Öпª·¢ÈËÔ±ÐèҪƵ·±µØÏòÖ÷¸ÉÌá½»´úÂ룬ÕâЩÐÂÌá½»µÄ´úÂëÔÚ×îÖպϲ¢µ½Ö÷¸Éǰ£¬ÐèÒª¾­¹ý±àÒëºÍ×Ô¶¯»¯²âÊÔ£¨Í¨³£Êǵ¥Ôª²âÊÔ£©½øÐÐÑéÖ¤¡£

CIµÄºÃ´¦ÔÚÓÚ¿ÉÒÔ·ÀÖ¹·ÖÖ§Æ«ÀëÖ÷¸ÉÌ«¾Ã£¬ÕâÖÖ³ÖÐø¼¯³É¿ÉÒÔʵÏÖ²úÆ·¿ìËÙµü´ú£¬µ«ÊÇÓÉÓÚҪƵ·±¼¯³É£¬ËùÒÔÐèÒªÖ§³Ö×Ô¶¯»¯¹¹½¨¡¢´úÂë¼ì²éºÍ²âÊÔ£¬ÊµÏÖÕâЩ×Ô¶¯»¯Á÷³ÌÊÇCIµÄºËÐÄ¡£

³ÖÐø¼¯³É

³ÖÐø½»¸¶£¨Continuous Delivery£©Ö¸µÄÊÇ£¬Æµ·±µØ½«Èí¼þµÄа汾£¬½»¸¶¸øÖÊÁ¿ÍŶӻòÕßÓû§£¬ÒÔ¹©ÆÀÉó¡£Èç¹ûÆÀÉóͨ¹ý£¬´úÂë¾Í½øÈëÉú²ú½×¶Î¡£

CDÊÇCIµÄÏÂÒ»²½£¬ËüµÄÄ¿±êÊÇÓµÓÐÒ»¸ö¿ÉËæÊ±²¿Êðµ½Éú²ú»·¾³µÄ´úÂë¿â¡£

³ÖÐø½»¸¶

³ÖÐø²¿ÊðÊdzÖÐø½»¸¶µÄÑÓÉ죬ʵÏÖ×Ô¶¯½«Ó¦Ó÷¢²¼µ½Éú²ú»·¾³¡£

³ÖÐø²¿Êð

¹«Ë¾ÄÚ²¿³£ÓõĽâ¾ö·½°¸ÓУºÀ¶¶ÜDevOpsƽ̨ ¡¢orange-ci¡¢QCI£¬¸÷»¨Èë¸÷ÑÛ£¬ÏêÇé¿ÉÒÔÔĶÁÕâÆªÎÄÕÂCI¹¤¾ßÄļÒÇ¿¡£

ÕâЩCIƽ̨ÊÇÔõÑù½«git²Ö¿âÖеĴúÂë±ä¶¯ºÍ×Ô¶¯»¯¹¹½¨Á÷³ÌÏà¹ØÁªÆðÀ´µÄÄØ£¿´ð°¸¾ÍÊÇWebhook£¬ËüÓëÒì²½±à³ÌÖС°¶©ÔÄ-·¢²¼Ä£ÐÍ¡±·Ç³£ÀàËÆ£¬Ò»¶Ë´¥·¢Ê¼þ£¬Ò»¶Ë¼àÌýÖ´ÐС£

ÔÚweb¿ª·¢¹ý³ÌÖеÄWebhook£¬ÊÇÒ»ÖÖͨ¹ýͨ³£µÄcallback£¬È¥Ôö¼Ó»òÕ߸ıäweb page»òÕßweb appÐÐΪµÄ·½·¨¡£ÕâЩcallback¿ÉÒÔÓɵÚÈý·½Óû§ºÍ¿ª·¢Õßά³Öµ±Ç°£¬Ð޸쬹ÜÀí£¬¶øÕâЩʹÓÃÕßÓëÍøÕ¾»òÕßÓ¦ÓõÄԭʼ¿ª·¢Ã»ÓйØÁª¡£WebhookÕâ¸ö´ÊÊÇÓÉJeff LindsayÔÚ2007ÄêÔÚ¼ÆËã»ú¿ÆÑ§hookÏîÄ¿µÚÒ»´ÎÌá³öµÄ¡£

WebhooksÊÇ¡±user-defined HTTP»Øµ÷¡±¡£ËüÃÇͨ³£ÓÉһЩʼþ´¥·¢£¬ÕâÀï¿ÉÒԲ鿴GitHubÉÏÃæÖ§³ÖµÄEventÀàÐÍ£¬±ÈÈçgit push¡¢forkµÈµÈ£¬Ò²¾ÍÊÇ˵ÕâЩ´úÂëÍÐ¹ÜÆ½Ì¨Ê×ÏÈÒªÖ§³ÖWebhookµÄ¹¦ÄÜ¡£

µ±Ê¼þ·¢Éúʱ£¬Ô´ÍøÕ¾¿ÉÒÔ·¢ÆðÒ»¸öHTTPÇëÇóµ½WebhookÅäÖõÄURL¡£Í¨³£ÕâÀïÅäÖõÄURLÖ¸Ïòij¸öCIϵͳ£¬ÕâÒâζ×ŵ±git²Ö¿âÖС°¶©ÔÄ¡±µÄʼþ·¢Éúʱ£¬CIϵͳ¿ÉÒÔÊÕµ½Í¨Öª¡£

CIϵͳÔÚÊÕµ½Í¨Öªºó¾Í¿ÉÒÔ´¥·¢buildµÈÁ÷³Ì¡£

CI×Ô¶¯»¯¹¹½¨Ö»ÊÇÓ¦ÓÃWebhookµÄÒ»¸ö°¸Àý£¬WebhookµÄÓ¦ÓÃÔ¶²»Ö¹ÕâЩ£¬ÓÉÓÚwebhookʹÓÃHTTPЭÒ飬Òò´Ë¿ÉÒÔÖ±½Ó±»¼¯³Éµ½web service£¬ÓÐʱ»á±»ÓÃÀ´¹¹½¨ÏûÏ¢¶ÓÁзþÎñ£¬ÀýÈçһЩRESTfulµÄÀý×Ó£ºIronMQºÍRestMS¡£

ÎÒÃǵÄÏîÄ¿¹¹½¨ÏÖ×´

½éÉÜÍêÁËǰ¶Ë¹¤³Ì»¯µÄһЩ¸ÅÄîºÍ¼¼Êõºó£¬ÏÂÃæ½áºÏÎÒÃÇÍŶÓÖеľßÌåÏîÄ¿¾ßÌå·ÖÎö¡£

1.ÏÖ×´·ÖÎö

ÕâÊÇĿǰÍŶÓÒÆ¶¯¶Ë»ù´¡¿âµÄÏîÄ¿½á¹¹£ºÖ÷ÒªÓÐ9¸öÄ£¿é£¬ÆäÖÐ3¸öUI×é¼þÒÀÀµ¿ò¼Ü¡£

»ù´¡¿âÏîÄ¿½á¹¹

Ä£¿é»¯

ÎÒÃÇÍŶÓÔÚÒÆ¶¯¶Ë»ù´¡¿âµÄ¿ª·¢ÖУ¬×î³õ²ÉÓõÄÊÇIIFEģʽ¡£´ÓÑϸñÒâÒåÉÏÀ´Ëµ£¬Õâ²¢²»ÊÇÒ»ÖÖ±ê×¼µÄÄ£¿é»¯·½Ê½£¬Ö»ÊÇͨ¹ý±Õ°üʵÏÖÁË˽ÓÐÊý¾Ý£¬½«Êý¾ÝºÍÐÐΪ·â×°µ½Ò»¸öº¯ÊýÄÚ²¿£¬ ͨ¹ý¸øÈ«¾Ö¶ÔÏówindow.MÌí¼ÓÊôÐÔÀ´ÏòÍⱩ¶½Ó¿Ú£¬ÎÒÃÇÎÞ·¨È·ÈÏÿ¸öÄ£¿é¼äµÄÒÀÀµ¹ØÏµ£¬Ä£¿éºÏ²¢Ê±»¹Òª¹Ø×¢ÒÀÀµË³Ðò¡£ÔÚÐµķ½°¸ÖУ¬ÎÒÃÇÒýÈëÁËES6µÄÄ£¿é»¯±ê×¼À´½â¾öÕâ¸öÎÊÌâ¡£

ÖØ¸´¿ª·¢£¬¸´ÖÆÕ³Ìù

ÓÉÓÚÒµÎñÌØµã£¬¶ÔÓÚһЩ¿ìËÙÉÏÏߵĻҳʹÓÃZepto¿â£¬¶ø¶Ô³£×¤Ò³Ãæ½øÐÐÁ˼¼ÊõÉý¼¶£¬Éç½»ÍŶÓʹÓÃÁËPreact¿ò¼Ü£¬Õâµ¼Ö»ù´¡¿âµÄ¿ª·¢ÓÐÁËÁ½¸ö°æ±¾£¬·Ö±ðÔÚ²»Í¬µÄ´úÂë²Ö¿âά»¤£¬µ«Êµ¼ÊÉ϶þÕß90%+µÄ´úÂë¶¼ÊÇÒ»ÑùµÄ£¬½ö½öÊÇÈý¸öUI×é¼þ²»Í¬¡£ÔÚ»ùÓÚTSWµÄͬ¹¹Ö±³öÏîÄ¿ÖУ¬ÓÐЩ»ù´¡¿â·½·¨ÓÖÒªÔÚnode¶ËÖ´ÐУ¬Õâ¸öʱºòÒ²ÊǸ´ÖÆÕ³ÌùÁËÒ»·Ým.js·Åµ½Á˸ÃÏîĿĿ¼ÖС£ÔÚÐµķ½°¸ÖУ¬ÎÒÃÇʹÓòîÒ컯µÄ¹¹½¨ÔÚÒ»·Ý´úÂë²Ö¿âÖзֱ𹹽¨³ö¶à¸ö°æ±¾¡£

×é¼þcssµÄÎÊÌâ

¶ÔÓÚ×é¼þµÄÑùʽ£¬ÎÒÃÇÊÇÓÐרÃŵÄÖØ¹¹×é½øÐпª·¢Î¬»¤µÄ£¬ËûÃÇ×ñÑ­BEM¹æ·¶£¬¿ª·¢×é¼þµÄʱºòµ±×Ö·û´®ÒýÈ룺

var css ='.qui_dialog__mask {position:fixed;top:0; left:0;bottom:0;right:0;}...';
appendToHead(css);

ÕâÖÖģʽ¶ÔCSSµÄ¿ª·¢Î¬»¤ºÜ²»ÓѺã¬ËäÈ»ÎÒÃDz»ÐèÒª¹Ø×¢ÑùʽµÄϸ½Ú£¬µ«»¹ÊÇÿ´ÎÒª°ÑÖØ¹¹·¢¸øÎÒÃǵÄ.cssÎļþÖеÄÑùʽcopy³öÀ´¡£Ð·½°¸ÖУ¬ÎÒÃÇÒýÈëCSS moduleµÄ·½°¸¡£

2.¼¼ÊõÑ¡ÐÍ

Ö÷Á÷¹¹½¨¹¤¾ß

¹¹½¨¹¤¾ßµÄÑ¡Ôñ£¬Ö÷Òª¶Ô±ÈÁËWebpack4¡¢RollupjsºÍParcel£¬ÒòΪ»ù´¡¿âµÄ¹¹½¨ÎļþÖ»ÓÐjs£¬¶øÇÒ´Ó¹¹½¨Ìå»ýÀ´Ëµ£¬rollupjsÊÇÓоø¶ÔÓÅÊÆµÄ£¬ËùÒÔÑ¡ÔñÁËrollupjs¡£

Ö÷Á÷¹¹½¨¹¤¾ß¶Ô±È

CSSÄ£¿é»¯

ÓÉÓÚCSS in JSÐèÒªÒýÈë¶îÍâµÄÒÀÀµ£¬ÔÚ¶Ô±ÈÁËCSS ModuleºÍCSS in JSºó£¬ÎÒÃÇÑ¡ÔñCSS ModuleµÄ·½°¸¡£

CSSÄ£¿é»¯·½°¸¶Ô±È

µ¥Ôª²âÊÔ¿ò¼Ü

µ¥Ôª²âÊÔ¿ò¼ÜÎÒÃÇÑ¡ÔñÁËJest£¬Ö÷ÒªÊÇÒòΪ¿ªÏä¼´Ó㬲»ÐèÒªÔÙÒýÈë¶ÏÑԿ⣬Éú̬ҲºÜºÃ£¬½Ï¶àÓÃÓÚReactÏîÄ¿£¬¶øÇÒ×éÄÚµÄUI×Ô¶¯»¯²âÊÔϵͳÊÇÖ§³ÖJestµÄ£¬ÕâÆªÎÄÕÂMigrating from Mocha to JestÖнéÉÜÁËAirbnbµÄ³¢ÊÔ¡£

µ¥Ôª²âÊÔ¿ò¼Ü¶Ô±È

Lint·½°¸

ÓÉÓÚ½ÓÈëÁËCIϵͳ½øÐÐlint×Ô¶¯»¯¼ì²é£¬ÎªÁ˼õÉÙ¡°ÎÞЧ¡±µÄcommit£¬ÎÒÃÇÑ¡ÔñÁËhusky+lint-stagedÀ´½øÐб¾µØ´úÂëÌύǰµÄlint¡£

Lint·½°¸

¹¤×÷Á÷ºÍCI£¿

¸÷ÖÖ¹¤×÷Á÷ÖУ¬Ê×ÏÈÐèÒªÔÚ¸÷×ԵĿª·¢·ÖÖ§½øÐпª·¢²âÊÔ£¬È»ºó½«´úÂëºÏ²¢µ½×·×ÙÉú³É»·¾³µÄ³¤ÆÚ·ÖÖ§½øÐгÖÐøµØ·¢²¼²¿Êð£¬ÕâÒâζ×ŶÔÕâ¸ö³¤ÆÚ·ÖÖ§ÒªÓÐÍêÉÆµÄ×Ô¶¯»¯²âÊÔÄÜÁ¦£¬ÒòΪ˭Ҳ²»Äܱ£Ö¤mergeµÄ´úÂë¾ÍÒ»¶¨²»»áÓÐÎÊÌ⣬ĿǰÐµķ½°¸ÒýÈëÁ˵¥Ôª²âÊÔ£¬¶ÔUI×é¼þÒýÈëÁË»ùÓÚpuppeteerµÄ½ØÍ¼²âÊÔ£¬µ«Ò»Ð©¹¦ÄÜȱ·¦ÔÚ¸ü¶àÉ豸¡¢¸ü¶àƽ̨ÉϵÄ×Ô¶¯»¯ÑéÖ¤£¬Òò´ËÎÒÃÇÈÏΪÔÚ×Ô¶¯»¯²âÊÔ·½ÃæµÄ½¨É軹²»ÊǷdz£ÍêÉÆ£¬ËùÒÔз½°¸½ÓÈëÁËCI£¬µ«ÊǶԷ¢²¼ÍâÁ´»ù´¡¿âmusic.jsÕâÖÖ»áÖ±½ÓÓ°Ï쵽ȫÁ¿ÒµÎñµÄ²¢Ã»ÓнÓÈ룬»¹ÊÇʹÓÃARS·¢²¼£¬³ý·Ç½ô¼±bug£¬ÆäËûµÄ´úÂë¸ü¸Ä»áÔÚ²âÊÔ»·¾³ÑéÖ¤Ò»¶Îʱ¼ä(Ò»°ã2-3Ìì)ºó²Å»á·¢²¼ÍâÍø¡£

ÎÒÃǵŤ³Ì»¯Êµ¼ù

1.¹¹½¨·½°¸

оɷ½°¸¶Ô±È

Ê×ÏÈ¿ÉÒÔ¿´Ò»ÏÂоɹ¹½¨·½°¸µÄ¶Ô±È£¬ÔÚз½°¸ÖÐÍÆ¹ãʹÓÃES6£¬Ôö¼ÓÁ˶ԴúÂëÖÊÁ¿µÄ¿ØÖÆ£º´úÂë¼ì²é+µ¥Ôª²âÊÔ£¬²¢½ÓÈëÁËCIϵͳ¡£

оɷ½°¸¶Ô±È

´ò°ü·½°¸

ÕâÊÇÎÒÃÇÕûÌåµÄ´ò°ü·½°¸£¬ºËÐÄÊÇÒ»·ÝÔ´Â뿪·¢Î¬»¤£¬Í¨¹ý¹¹½¨¹¤¾ßµÄ²îÒ컯ÅäÖÃʵÏÖ¶àÖÖ°æ±¾µÄ¹¹½¨¡£

´ò°ü·½°¸

¿ª·¢Á÷³Ì

ÕâÊÇÕûÌåµÄ¿ª·¢Á÷³Ì£¬±¾µØ¿ª·¢Ê¹ÓÃpackage.json¹ÜÀíÏîÄ¿ÒÀÀµ£¬¹æ·¶´úÂë¸ñʽ£¬½ÓÈëµ¥Ôª²âÊÔ£»Ìύ֮ǰgit hookÉèÖñ£Ö¤´úÂë¼ì²éºÍ²âÊÔͨ¹ýºó²ÅÄÜÌá½»³É¹¦£»Ê¹ÓÃQCI×Ô¶¯½øÐÐÏîÄ¿µÄ¹¹½¨¡¢¼ì²éºÍ²âÊÔ£¬Í¨¹ýºó½«JSDOCÎĵµÍÆË͵½Îĵµ·þÎñÆ÷£¬²¢·¢²¼npm°ü£¬ÍâÁ´js»¹ÊÇʹÓÃars·¢²¼¡£

¿ª·¢Á÷³Ì

2.UI×é¼þ¿ª·¢ºÍÎĵµ

ÎÒÃÇÑ¡Ôñreact-styleguide×÷ΪUI×é¼þ¿ª·¢µ÷ÊÔ¹¤¾ßÒÔ¼°ÎĵµÉú³ÉÆ÷£¬ÕâÊÇÒ»¸ö×é¼þµÄMDÎļþʾÀý£º

### ×é¼þʽÒýÈë
- ¿ÉÒÔÌáǰ²åÈëdom½á¹¹£¬Èç¹û¸¡²ãÖÐÓÐͼƬµÄ»°»áÏȼÓÔØ£»
- ÊôÐÔÖÐµÄ `visible` ¿ØÖÆ×é¼þÊÇ·ñ¿É¼û¡£
```jsx
import Button from '../../basic/Button/Button'
import QMDialog from './QMDialog';
class QMDialogExample extends React.Component {
constructor(props) {
super(props);
this.state = {visible1: false}
}

render() {
const {visible1} = this.state;
return (
<div>
<Button onClick={() => {
this.setState({
visible1: true
})
}}>»ù±¾Ê¹ÓÃ</Button>
<Button onClick={() => {
this.setState({
visible2: true
})
}}>´øÍ·Í¼µÄ¸¡²ã</Button>
<Button onClick={() => {
this.setState({
visible3: true
})
}}>´«ÈëÒ»¸öreact½Úµã</Button>
<QMDialog
visible={visible1}
title="QQÒôÀÖ"
message="ÕâÊÇÒ»¶ÎÃèÊö"
btn={'ÎÒÖªµÀÁË'}
handleTap={index => {
if(index === -1) {
this.setState({
visible1: false
})
} else {
console.log('ÎÒÖªµÀÁ˰´Å¥±»µã»÷£¬index=', index)
}
}}
/>
</div>
)
}
}
<QMDialogExample />
```

react-styleguide»á¸ù¾Ý×é¼þµÄÔ´ÂëºÍÕâ¸ömdÎļþÉú³ÉÎĵµºÍdemo£¬¿ª·¢µ÷ÊÔ½×¶ÎÖ§³ÖwebpackÅäÖÃHMR£¬·Ç³£·½±ã¡£

demoÎĵµ½ØÍ¼

3.Jestµ¥Ôª²âÊÔ

Jest¿ÉÒÔÉèÖÃÈ«¾ÖµÄSetup£¬»áÔÚËùÓÐtestÖ´ÐÐ֮ǰÔËÐУ¬Ò²¿ÉÒÔÉèÖÃÈ«¾ÖTeardown£¬»áÔÚËùÓÐtestÖ´ÐÐÍê±ÏÖ®ºóÔËÐУ¬±ÈÈçÕâÀï¾Í¿ÉÒÔÉèÖÃһЩ²âÊÔÐèÒªµÄGlobal¶ÔÏó¡¢ÔËÐл·¾³µÈµÈ¡£describe¿ÉÒÔ½«²âÊÔÓÃÀý½øÐзÖ×飬beforeEach¡¢afterEach¡¢beforeAll¡¢afterAllÕâЩ·½·¨¿ÉÒÔ¶¨ÒåÔÚ²âÊÔÓÃÀý֮ǰ»òÕßÖ®ºóÔËÐеķ½·¨¡£

²âÊÔ·½°¸

¸ù¾ÝÉÏÃæ½éÉܵĴò°ü·½°¸ºÍÒµÎñÌØµã£¬»ù´¡¿âÐèÒª·Ö±ðÔËÐÐÔÚnode¶ËºÍä¯ÀÀÆ÷¶Ë£¬Òò´ËÐèÒª¿¼Âǵ½²»Í¬ÔËÐл·¾³ÏµIJâÊÔ½á¹û¡£

ä¯ÀÀÆ÷¶Ë

npmÃüÁî

jest --coverage --config ./config/jest/music.jest.config.js

ÉèÖÃ--coverageÉú³É²âÊÔ¸²¸ÇÂÊ¡£

ÅäÖÃÎļþ(music.jest.config.js)£º

»ùÓÚjsdomÉèÖÃÈ«¾Ö»·¾³£ºjest-environment-jsdom-fourteen£¬Ìṩä¯ÀÀÆ÷¶ËBOM¶ÔÏó¡£

ÉèÖÃcookie²Ù×÷ȨÏÞµÄdomain£ºtestURL: "https://y.qq.com/m/demo.html"£¬½ö¿ÉÒÔ²Ù×÷´ËÓòÃûϵÄcookie¡£

module.exports = {
clearMocks: true,
coverageDirectory: "jest-coverage/coverage-music-node",
preset: null,
rootDir: '../../',
testEnvironment: " jest-environment-jsdom-fourteen",
testMatch: [
"**/tests/music-node/**/*.test.[jt]s(x)",
],
testURL: "https://y.qq.com/m/demo.html",
transformIgnorePatterns: []
};

Node¶Ë

node¶ËºÍä¯ÀÀÆ÷¶ËµÄ²»Í¬ÔÚÓÚÔËÐл·¾³testEnvironment²»Í¬£¬jestÌṩjest-environment-node£¬ÎÒÃÇΪnode¶Ëµ¥¶ÀÅäÖÃÁËmusic-node.jest.config.js¡£

UI×é¼þ

JestÖ§³Ö¶ÔReact AppµÄ²âÊÔ£¬¿ÉÒÔ²ÉÓýØÍ¼²âÊÔ(Snapshot Testing)¡¢Ä£ÄâDOM²Ù×÷(DOM Testing)µÈ·½·¨Ïê¼ûÎĵµ¡£ÔÚ×é¼þÎĵµºÍdemoÕâÒ»Õ½ÚÖÐÎÒÃÇÒѾ­ÓÐÁË×é¼þʾÀý£¬²¢¹¹½¨ÁËÎĵµÒ³£¬¿ÉÒÔÖ±½Ó½ÓÈëÍŶӵÄ×Ô¶¯»¯²âÊÔϵͳ£¬½áºÏʹÓÃpuppeteer½øÐнØÍ¼¶Ô±È¡£

ÏÂÃæÊǶÔQMDialog×é¼þµÄ²âÊÔÓÃÀý£¬Ê×ÏÈ×¼±¸Ò»ÕÅ»ù׼ͼƬ£¬È»ºóд²âÊÔÁ÷³Ì£º´ò¿ªÒ³Ã桪¡ªµã»÷°´Å¥´¥·¢×é¼þ¡ª¡ª½ØÍ¼¶Ô±È¡£screeshotDiff·½·¨µÄʵÏֲο¼ÁËÕâÆªKMÎļþͨ¹ýpuppeteerʵÏÖÒ³Ãæ¼à¿Ø£¬Í¼Æ¬diffºËÐÄËã·¨ÓÉpixelmatch¿âʵÏÖ¡£

const iPhone = devices['iPhone 6'];
await page.emulate(iPhone);
await log("½øÈëÒ³Ãæ");
await page.goto('http:// [host]/reactui/index.html#/QMDialog', {
waitUntil: 'load'
});
await timeout(3000);
let dom = await page.$ ('#QMPreload-container .rsg--preview-35 .button');
await dom.click();
await timeout(200)
let diff = await screenshotDiff({
img: 'https: //y.gtimg.cn/music/common/upload/ t_cm3_photo_publish/1677163.png'
});
if (diff > 10) {
fail();
return;
}
success();

 

ÕâÊÇÒ»´Î²âÊÔÔËÐнá¹û£¬´Ó×óµ½ÓÒÒÀ´ÎÊÇ£º»ù׼ͼ¡¢²âÊÔ½ØÍ¼¡¢diff½á¹ûͼ£¬screeshotDiff¸ù¾ÝµÚÈýÕÅͼƬ·µ»Ø²îÒìµãµÄÕ¼±È£¬ÓÉÓÚQMPreload×é¼þµÄÌØµã£¬¼ÓÔØ½ø¶ÈÊÜÍøÂçÓ°Ï죬ÉèÖÃãÐֵΪ10%£¬¼´Ö»Òª²îÒìÂÊÔÚ10%ÒÔÄھͿÉÒÔÈÏΪÊÇÕý³£µÄ¡£

QMPreload²âÊÔ½á¹û

ºÍÉÏÃæQMPreload²»Í¬£¬¶ÔQMDialog×é¼þµÄÅжÏÔòÊÇÐèÒª²îÒìֵΪ0£¬ÈçÏÂÃæµÚÈýÕÅͼËùʾ£¬Ã»ÓвîÒìµã¡£

QMDialog²âÊÔ½á¹û

mock

ÕâÊÇÎÒÃDzÎÕÕ¹ÙÍøµÄÎĵµ½ÓÈëµÄmockʾÀý£¬ÕâÀïÐèҪעÒâ__mock__µÄĿ¼½á¹¹£¬Ïê¼ûÎĵµ¡£

c.
©À©¤©¤ config
©À©¤©¤ src
©¦ ©À©¤©¤ music
©¦ ©¦ ©À©¤©¤ utils
©¦ ©¦ ©¦ ©À©¤©¤ __mock__
©¦ ©¦ ©¦ ©¸©¤©¤ loadUrl.js
©¦ ©¦ ©¸©¤©¤ loadUrl.js
©À©¤©¤ node_modules
©À©¤©¤ ...
©¸©¤©¤ tests

loadURL·½·¨ÓÃÀ´¶¯Ì¬¼ÓÔØjs£¬Ê¹ÓÃjest.fn().mockImplementation¶ÔloadUrl½øÐÐmock£¬²¢mockÁËwindow.pgvMainºÍwindow.pgvSendClick¡£

export const loadUrl = jest.fn().mockImplementation ((url, callback) => {
if (/ping.js/.test(url)) {
let pvCount = 0;
window.pgvMain = jest.fn( ).mockImplementation( (p1, p2) => {
expect(p1).toBe('');
expect(p2.virtualDomain).toBe('y.qq.com');
if (pvCount === 1) {
expect(p2.ADTAG).toBe('all');
}
pvCount++;
})
window.pgvSendClick = jest.fn().mockImplementation( (p) => {
expect(p.hottag).toEqual (expect.stringContaining('.android'));
});
}
callback();
});
export default loadUrl;

ÒòΪʹÓÃÁËES moduleµÄimport£¬ÐèÒªjest.mock¶ÔÕû¸öÄ£¿é½øÐÐmock¡£¶ÔÓÚmockµÄº¯Êý²ÅÄܵ÷ÓÃtoHaveBeenCalledTimesµÄ¶ÏÑÔ¡£

import tj from '../../src/music/tj';
import loadUrl from '../../src/music/utils/loadUrl'
jest.mock('../../src/music/utils/loadUrl');
describe('¡¾tj.js¡¿µã»÷Éϱ¨', () => {
test('tj.pv tj.sendClick', () => {
expect(typeof window.pgvMain).toBe('undefined');
expect(loadUrl ).toHaveBeenCalledTimes(0);
tj.pv();
expect(loadUrl).toHaveBeenCalledTimes(1);
expect(typeof window.pgvMain ).toBe('function');
expect(window.pgvMain ).toHaveBeenCalledTimes(1);
tj.sendClick();
tj.sendClick('tjtag.click');
window.tj_param = {
ADTAG: 'all'
}
tj.pv();
expect(loadUrl).toHaveBeenCalledTimes(1);
expect(window.pgvSendClick ).toHaveBeenCalledTimes(1);
});
})

²âÊÔ¸²¸ÇÂÊ

ÕâÊÇijһ´ÎµÄ²âÊÔ±¨¸æ£¬ÉÏÃæÓÐÿ¸öÄ£¿éÏêϸµÄ²âÊÔ¸²¸ÇÂÊ¡£ÎªÁ˱ãÓÚ¶Ô¸÷¸öÄ£¿éÁé»î´¦Àí£¬ÎÒÃǽ«Ã¿¸öº¯Êýϸ·Ö²ð³ÉÒ»¸öÎļþ£¬ÈçÏÂÃæµÄsrc/music/typeĿ¼Ïµĸ÷¸öÎļþ¡£

²âÊÔ¸²¸ÇÂÊ-1

²âÊÔ¸²¸ÇÂÊ-2

²âÊÔ¸²¸ÇÂÊ-3

ͨ¹ýµ¥Ôª²âÊÔ·¢ÏֵĴúÂëbug

ÕâЩ¶¼ÊÇÎÒÃÇͨ¹ýµ¥Ôª²âÊÔ·¢ÏÖµÄ֮ǰһЩº¯ÊýµÄbug£¬½ö¾ÙÀýÒ»²¿·Ö£º

²âÊÔÓÃÀý ´íÎóÊä³ö ÕýÈ·Êä³ö
M.type(undefined) "nan" "undefined"
M.isPlainObject (Object.creact({})) false true
Mozilla/5.0 (Linux; U; en-us; KFTT Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.21 Safari/535.19 Silk-Accelerated=true<br />M.os.tablet false false
M.param({a: 1, b: {c: 1}}) "a=1&b=c%3D1" "a=1&b%5Bc%5D=1"

4.һЩTips

ÉùÃ÷pkg.module

ÉùÃ÷pkg.module¿ÉÒÔÈù¹½¨¹¤¾ßÀûÓõ½ES MoudleµÄºÜ¶àÌØÐÔÀ´Ìá¸ß´ò°üÐÔÄÜ£¬±ÈÈçÀûÓÃTree ShakingµÄ»úÖÆ¼õÉÙÎļþÌå»ý£¬ÕâÆªÎÄÕÂpackage.jsonÖеÄModule×Ö¶ÎÊǸÉÂïµÄÓÐÏêϸ½éÉÜ¡£

sideEffects

Tree Shaking¿ÉÒÔÔÚ¹¹½¨µÄʱºòÈ¥³ýÈßÓà´úÂ룬¼õÉÙ´ò°üÌå»ý£¬µ«ÕâÊÇÒ»¸ö·Ç³£Î£ÏÕµÄÐÐΪ£¬ÔÚwebpack4ÖУ¬¿ÉÒÔÔÚpackage.jsonÖÐÃ÷È·ÉùÃ÷¸Ã°ü/Ä£¿éÊÇ·ñ°üº¬sideEffects(¸±×÷ÓÃ)£¬´Ó¶øÖ¸µ¼webpack4×÷³öÕýÈ·µÄÐÐΪ¡£Èç¹ûÔÚpackage.jsonÖÐÉèÖÃÁËsideEffects: false£¬webpack4»á½«import {a} from 'moduleName'ת»»Îªimport a from 'moduleName/a'£¬´Ó¶ø×Ô¶¯ÐÞ¼ôµô²»±ØÒªµÄimport£¬×÷ÓûúÖÆÍ¬babel-plugin-import¡£Õâ¸ö¹¦ÄÜÇײâÊǺÜÓÐЧµÄ

¶ÔÓÚrollupjsÀ´Ëµ£¬ÓÐʱºòTree Shaking²¢²»ÓÐЧ£¬ÕâÊǹÙÍøµÄÒ»¶Î½âÊÍ£¬´óÒâ¾ÍÊǾ²Ì¬´úÂë·ÖÎöºÜÄÑ£¬ÎªÁ˰²È«rollupjs¿ÉÄÜ»áÎÞ·¨Ó¦ÓÃTree Shaking£¬Õâ¸öʱºò½¨Òé×îºÃ»¹ÊÇÃ÷È·importµÄPATH£¬ÕâÀï¿ÉÒÔ½áºÏÊÊÓ¦ÉÏÃæµÄbabel-plugin-import²å¼þ¡£

Tree-Shaking Doesn't Seem to Be Working

²å¼þ

@babel/plugin-transform-runtime

Õâ¸ö²å¼þ¿ÉÒÔ±ÜÃâÿһ¸öjsÎļþ·Ö±ðÒýÈ뽺ˮ´úÂ룬¶øÊÇÕû¸ö¹¹½¨ÎļþÒýÈëÒ»·Ý½ºË®´úÂ룬¼õÉÙ´úÂëÌå»ý¡£

eslint-friendly-formatter

¶ÔeslintµÄ´íÎóÊä³ö½øÐиñʽ»¯£¬·½±ã²é¿´ºÍ¶¨Î»ÎÊÌâ¡£

babel-plugin-transform-react-remove-prop-types

ÓÉÓÚÔËÐÐʱµÄÐÔÄÜÔ­Òò£¬RNÒѾ­ÔÚproductionģʽÏÂÒÆ³ýÁËPropTypes£¬ÎÒÃÇÒýÈëÕâ¸öbabel²å¼þÔÚÉú²úģʽÖÐÒÆ³ý×é¼þÊôÐÔµÄÀàÐÍУÑéÏà¹ØµÄ´úÂë¡£

¡ªnoCon?ict

ÔÚ½«ÍâÁ´jsÓÃrollupjs¹¹½¨³Éumd¹æ·¶µÄʱºò£¬ÎÒÃÇÉèÖÃÁË--noConflict£¬¿ÉÒÔ½â¾öÈ«¾Ö±äÁ¿M³åÍ»µÄÎÊÌ⣬ÀàËÆÓÚjQuery.noConflict()¡£

 

 
   
1942 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]
 
×îÐÂÎÄÕÂ
ÈçºÎÉè¼Æ¸ßÀ©Õ¹µÄÔÚÏßÍøÒ³ÖÆ×÷ƽ̨
electronÈëÃÅÐĵÃ
ʹÓà Electron ¹¹½¨×ÀÃæÓ¦ÓÃ
VUE.JS×é¼þ»¯¿ª·¢Êµ¼ù
ÉîÈëÀí½âJSCore
×îпγÌ
HTML 5 + CSS3 Ô­ÀíÓ뿪·¢Ó¦ÓÃ
Webǰ¶Ë¸ß¼¶¹¤³Ìʦ±Ø±¸¼¼ÄÜʵս
Vue´óÐÍÏîÄ¿¿ª·¢ÊµÕ½
ReactÔ­ÀíÓëʵ¼ù
Vue.js½ø½×Óë°¸Àýʵ¼ù
³É¹¦°¸Àý
Öн»¼¯ÍÅ ¹¹½¨Web×Ô¶¯»¯²âÊÔ¿ò¼Ü
ijָÃûµçÐŹ«Ë¾ Vue.js½ø½×Óë°¸Àý
¹úµçÍ¨ÍøÂç¼¼Êõ HTML5+CSS3 +webǰ¶Ë¿ò
ÒÆ¶¯Í¨ÐÅ ÒÆ¶¯»¥ÁªÍøÓ¦Óÿª·¢Ô­Àí
ijµçÁ¦ÐÐ android¿ª·¢Æ½Ì¨×î¼Ñ