ã€ãŸããããã¯çž®å°/ããŒãžããããã¡ã€ã«ãå ã®ãã¡ã€ã«ã«é¢é£ä»ããæ¹æ³ã§ãã ã¢ã»ã³ããªäžãæŠéç°å¢ã§ã¯ããã¡ã€ã«ã®çž®å°ãšçµåã«å ããŠããœãŒã¹ãã¡ã€ã«ã«é¢ããæ å ±ãå«ãããããŒãã¡ã€ã«ãçæãããŸãã çž®å°ããããã¡ã€ã«ã®ç¹å®ã®å Žæãåç §ãããšãããããŒã§æ€çŽ¢ãè¡ããããœãŒã¹ãã¡ã€ã«ã®è¡ãšæåãèšç®ãããŸãã éçºè ããŒã«ïŒWebKitãã€ããªãŒãã«ããŸãã¯Google Chrome CanaryïŒã¯ããœãŒã¹ãã¡ã€ã«ãæäœããŠãããã®ããã«ããã®ãã¡ã€ã«ãèªåçã«è§£æããééçã«ãã¡ã€ã«ã眮ãæããŸãã å·çæç¹ã§ïŒ å ã®èšäº-ãããTranslã ïŒãFirefoxã¯Source Mapã®ãµããŒãã®éçºããããã¯ããŠããŸãã 詳现ã«ã€ããŠã¯ã MozillaWiki Source Mapãã芧ãã ããã
äŸ-ãœãŒã¹ã³ãŒãå ã®å Žæã®æ£ãã決å®
ãã®äŸã§ã¯ãããã¹ããšãªã¢ãå³ã¯ãªãã¯ããŠãå ã®å ŽæãååŸããéžæããŠãããã¹ããšãªã¢ãã©ãã§ãçªãããšãã§ããŸãã ãã®å Žåãçž®å°ãããã³ãŒãã®è¡ãšæåçªå·ã転éããŠãããããŒãã¡ã€ã«ã«ã¢ããŒã«ãè¡ããããœãŒã¹ãã¡ã€ã«ã®å¯Ÿå¿ããã³ãŒãã衚瀺ãããŸãã ã³ã³ãœãŒã«ã«ã¯ããœãŒã¹ãã¡ã€ã«ã®è¡çªå·ãšã·ã³ãã«çªå·ãããã³ãã®ä»ã®èå³æ·±ãæ å ±ã衚瀺ãããŸãã
å®éã®äœ¿çš
次ã®äŸãèŠãåã«ãChrome CanaryãŸãã¯WebKitã§ãœãŒã¹ããããã¥ãŒãæ¯æ©ã¢ã¯ãã£ãã«ããå¿ èŠããããŸãããã®ããã«ã¯ãããããã£ã§ããœãŒã¹ããããæå¹ã«ãããã¢ã€ãã ãã¢ã¯ãã£ãã«ããŸãïŒã¹ã¯ãªãŒã³ã·ã§ãããåç §ïŒ
ç¶ããŸãããã åã®äŸã¯èå³æ·±ããã®ã§ããããããã¯ã©ã®ããã«äœ¿çšã§ããŸããïŒ ã«ã¹ã¿ãã€ãºããGoogle Chromeãã©ãŠã¶ãŒã§dev.fontdragr.comã«ã¢ã¯ã»ã¹ãããš ãããŒãžäžã®JavaScriptãã³ã³ãã€ã«ãããŠããããåã ã®jsãã¡ã€ã«ãèŠãããšãã§ããããšãããããŸãã ããã¯ãã¹ãŠãããããŒã䜿çšãããããã§ãããå®éã«ã¯ããŒãžäžã®ã³ãŒãã¯ã³ã³ãã€ã«ãããŠããŸãã ãã¹ãŠã®ãšã©ãŒããã°ãšã³ããªããã¬ãŒã¯ãã€ã³ãã¯ãœãŒã¹ã³ãŒãã«ããããããã³ãŒãããããã°ããã®ã«éåžžã«äŸ¿å©ã§ãã ãã®çµæãæ¬çªãµã€ãããã¹ããµã€ããšããŠäœ¿çšã§ããŸãã
äŸ-fontdragr.comã®ã³ã³ãœãŒã«ãèŠã
ãœãŒã¹ããããå¿ èŠãªçç±
ãããã³ã°ã¯ããœãŒã¹ãã¡ã€ã«ãšå§çž®/ããŒãžãããããŒãžã§ã³éã§ã®ã¿æ©èœããããã«ãªããŸããããJavaScriptïŒCoffeeScriptãªã©ïŒã§ã³ã³ãã€ã«ãããèšèªã®ãããã³ã°ãäœæããSASSãLESSãªã©ã®CSSããªããã»ããµãŒããµããŒããããšãã話ããããŸãã
å°æ¥ã¯ããã©ãŠã¶ã§ãã€ãã£ãã«ãµããŒããããŠãããã®ããã«ãã»ãŒãã¹ãŠã®èšèªãç°¡åã«äœ¿çšã§ããŸãã
- CoffeeScript
- ECMAScript 6以é
- SASS / LESSãªã©
- JavaScriptã§ã³ã³ãã€ã«ããã»ãŒãã¹ãŠã®èšèª
Firefoxã³ã³ãœãŒã«ã®å®éšçãã«ãã§CoffeeScriptããããã°ãããã¹ã¯ãªãŒã³ãã£ã¹ãã確èªããŠãã ããã
Google Web ToolkitïŒGWTïŒã¯æè¿ã Source MapsãšGWTã®Ray Cromwellã®ãµããŒããè¿œå ãã Source Mapã®å®éã®åäœã瀺ãåªããã¹ã¯ãªãŒã³ãã£ã¹ããäœæããŸããã
å¥ã®äŸã§ã¯ãGoogle Traceurã©ã€ãã©ãªã䜿çšããŸããããã«ãããES6ïŒECMAScript 6ïŒã§èšè¿°ããES3äºæã³ãŒãã«ã³ã³ãã€ã«ã§ããŸãã Traceurã³ã³ãã€ã©ã¯ããœãŒã¹ããããçæããŸãã ES6ã®æ©èœïŒã¯ã©ã¹ãšç¹æ§ïŒ ã®äœ¿çšäŸã ããã©ãŠã¶ã§ãã€ãã£ãã«ãµããŒããããŠãããã®ããã«èŠãŠãã ããã ãã®äŸã®Textareaã䜿çšãããšãES3ã§ãªã³ã¶ãã©ã€ã§ã³ã³ãã€ã«ãããã¡ã€ã«ããããŒãäœæããES6ã³ãŒããäœæã§ããŸãã
äŸ-ES6ã§ã³ãŒããèšè¿°ããããã«ãããã¬ãŒãèŠãããšãã§ããŸã
ã©ã®ããã«æ©èœããŸããïŒ
ãœãŒã¹ãããããµããŒãããå¯äžã®ã³ã³ãã€ã©/ãããã£ã¯ãµãŒã¯ãã¯ããŒãžã£ãŒã³ã³ãã€ã©ã§ãïŒã³ã³ãã€ã«äžã«ããããŒãçæããæ¹æ³ã«ã€ããŠã¯ã以äžã§èª¬æããŸãïŒã JavaScriptãçž®å°ãããšãããããŒãã¡ã€ã«ãäœæãããŸãã ã¯ããŒãžã£ã³ã³ãã€ã©ã¯ãGoogle Chrome CanaryéçºããŒã«çšã®ç¹å¥ãªã³ã¡ã³ããããã¡ã€ã«ããããŒãå©çšã§ãããã¡ã€ã«ã®æåŸã«è¿œå ããŸããã
//@ sourceMappingURL=/path/to/file.js.map
ãã®ãããªã³ã¡ã³ãã«ããããã©ãŠã¶ã¯ããããŒãã¡ã€ã«ã䜿çšããŠãœãŒã¹ãã¡ã€ã«å ã®é©åãªå Žæãæ€çŽ¢ã§ããŸãã å¥åŠãªã³ã¡ã³ãã䜿çšããèããæ°ã«å ¥ããªãå Žåã¯ãã³ã³ãã€ã«æžã¿ãã¡ã€ã«ã«ç¹å¥ãªããããŒãè¿œå ã§ããŸãã
X-SourceMap: /path/to/file.js.map
ã³ã¡ã³ãã®ããã«ãããã¯ãã®ãã¡ã€ã«ã®ããããŒãæ¢ãå Žæãã¯ã©ã€ã¢ã³ãã«äŒããŸãã ããããŒã䜿çšãããšãåäžè¡ã®ã³ã¡ã³ãããµããŒãããªãèšèªã§ãäœæ¥ã§ããŸãã
ããããŒãã¡ã€ã«ã¯ãããããã£ãæå¹ã§ãã³ã³ãœãŒã«ãéããŠããå Žåã«ã®ã¿ããŠã³ããŒããããŸãã ãã¡ãããããããŒã§æå®ããããã¹ã§äœ¿çšã§ããããã«ããœãŒã¹ãã¡ã€ã«ã«å ¥åããå¿ èŠããããŸãã
ãã¡ã€ã«ããããŒãçæããæ¹æ³ã¯ïŒ
äžèšã®ããã«ãå¿ èŠãªJavaScriptãã¡ã€ã«ã®ããããŒãã¡ã€ã«ãçž®å°ãæ¥çãçæããã«ã¯ã ã¯ããŒãžã£ãŒã³ã³ãã€ã©ãå¿ èŠã§ãã ãããè¡ãã«ã¯ã次ã®ã³ãã³ããå®è¡ããŸãã
java -jar compiler.jar \ --js script.js \ --create_source_map ./script-min.js.map \ --source_map_format=V3 \ --js_output_file script-min.js
--create_source_map
ãã©ã°ã¯
--create_source_map
ããã³
--source_map_format
ã§ãã åŸè ãå¿ èŠã§ãããªããªã ããã©ã«ãã§ã¯ãããããŒã¯V2圢åŒã§äœæãããV3ãå¿ èŠã§ãã
ãœãŒã¹ãããå éšããã€ã¹
ãœãŒã¹ããããããããç解ããã«ã¯ãå°ããªãã¡ã€ã«ããããŒãäŸã«åãããã¢ãã¬ã¹æå®ãã®ä»çµã¿ã詳现ã«åæããŸãã 以äžã¯ã V3ä»æ§ããå°ãå€æŽãããäŸã§ãã
{ version : 3, file: "out.js", sourceRoot : "", sources: ["foo.js", "bar.js"], names: ["src", "maps", "are", "fun"], mappings: "AAgBC,SAAQ,CAAEA" }
ããã¯ãå¿ èŠãªãã¹ãŠã®æ å ±ãå«ãéåžžã®ãªããžã§ã¯ããªãã©ã«ã§ããããšã«æ°ä»ããããããŸããã
- ããããŒããŒãžã§ã³
- æ¬çªçšã®çž®å°/ããŒãžããããã¡ã€ã«ã®åå
-
sourceRoot
䜿çšsourceRoot
ãšããœãŒã¹ãã¡ã€ã«ãžã®ãã¹ã«ãã¬ãã£ãã¯ã¹ãsourceRoot
ã§ããŸãã -
sources
ã«ã¯ãœãŒã¹ãã¡ã€ã«ã®ååãå«ãŸããŸã -
names
ã¯ãçµæã®ãã¡ã€ã«ããã®å€æ°/é¢æ°ã®ãã¹ãŠã®å®éã®ååãå«ãŸããŸã -
mappings
ã¯å¯Ÿå¿ããçž®å°ãããååã§ã
BASE64 VLQãŸãã¯ãœãŒã¹ããããå°ããããæ¹æ³
åœåããã¹ãŠã®äŸåé¢ä¿ã®éåžžã«è©³çŽ°ãªåºåãä»æ§ã«èšèŒãããŠããããããã¡ã€ã«ããããŒã¯çæããããã¡ã€ã«ã®10åã«ãªããŸããã 2çªç®ã®ããŒãžã§ã³ã¯ãã¡ã€ã«ãµã€ãºãååã«åæžãã3çªç®ã®ããŒãžã§ã³ã¯åã³ãã¡ã€ã«ãµã€ãºãååã«åæžããŸããã 133kBã®ãã¡ã€ã«ã®å Žåã300kBã®ãã¡ã€ã«ããããŒãçæãããŸãã è€éãªäŸåé¢ä¿ã远跡ããªãããã©ã®ããã«ããŠãã®ãããªæžå°ãéæããŸãããïŒ
VLQ ïŒå¯å€é·æ°éïŒããã³Base64ãšã³ã³ãŒãã䜿çšããŸãã
mappings
ããããã£ã¯éåžžã«å€§ããªæååã§ãã ãã®è¡å ã§ãã»ãã³ãã³ïŒ;ïŒãçæããããã¡ã€ã«ã®è¡çªå·ãåºåããŸãã çµæã®æååå ã§ãã³ã³ãã䜿çšããŠã³ãŒãã»ã°ã¡ã³ããåºåããŸãã åã»ã°ã¡ã³ãã¯ã1ã4ããŸãã¯5ã€ã®VLQãã£ãŒã«ããè¡šããŸãã ç¶ç¶ããããåå ã§ããé·ããªãå ŽåããããŸãã åã»ã°ã¡ã³ãã¯åã®ã»ã°ã¡ã³ãã«åºã¥ããŠæ§ç¯ãããããããã¡ã€ã«ãµã€ãºãåæžã§ããŸãã
åè¿°ã®ããã«ãåã»ã°ã¡ã³ãã¯1ã4ããŸãã¯5ã€ã®VLQã«ãªããŸãã ãã®å³ã¯ã1ã€ã®ç¶ç¶ããããæã€4ã€ã®VLQã瀺ããŠããŸãã ããããã詳现ã«åæããããããŒããœãŒã¹ãã¡ã€ã«å ã®äœçœ®ãèšç®ããæ¹æ³ã瀺ããŸãããã ã»ã°ã¡ã³ãã¯5ã€ã®ãã®ã§æ§æãããŸãã
- çæããããã¡ã€ã«ã®æåçªå·
- ãœãŒã¹ãã¡ã€ã«
- ãœãŒã¹ãã¡ã€ã«ã®è¡çªå·
- ãœãŒã¹ãã¡ã€ã«ã®æåçªå·
- å ã®ååïŒããå ŽåïŒ
ïŒ ã³ã¡ã³ãperevãïŒèšäºã®ãã®éšåãå®å šã«ç¿»èš³ããããšã¯ã§ããŸããã§ãããå ã®èšäºã®å šæãèªãããšãã§ããŸããæäŒãããå Žåã¯ãæè¬ããŸã ïŒ
XSSIã®æœåšçãªåé¡
ä»æ§ã§ã¯ããœãŒã¹ãããã䜿çšããå Žåã®XSSã®å®è£ ã«é¢ããèããããåé¡ã«ã€ããŠèª¬æããŠããŸãã ããããã¡ã€ã«ã®å é ã«ã
)]}
ããšèšè¿°ãããšããã®jsãã¡ã€ã«ãç¡å¹ã«ãªãããšã©ãŒãçºçããŸãã WebKitéçºããŒã«ã¯æ¢ã«ãã©ããæ¹æ³ãç¥ã£ãŠããŸãã
if (response.slice(0, 3) === ")]}") { response = response.substring(response.indexOf('\n')); }
ã芧ã®ãšãããæåã®3æåã¯åãæšãŠãããä»æ§ã§æå®ãããç¡å¹ãªã³ãŒãã«æºæ ããŠãããã©ããããã§ãã¯ãããŸãããã®å Žåããã¹ãŠã次ã®æ¹è¡æåã«åãæšãŠãããŸãã
ã¢ã¯ã·ã§ã³ã®@sourceURL
ããã³displayName
ïŒ eval
ããã³anonymousé¢æ°
ãããã®2ã€ã®èŠåã¯ããœãŒã¹ãããã®ä»æ§ã«ã¯ãŸã å«ãŸããŠããŸãããã
eval
é¢æ°ãšå¿åé¢æ°ã®åŠçãå€§å¹ ã«ç°¡çŽ åã§ããŸãã
æåã®ãã«ããŒã¯
//@ sourceMappingURL
ã«éåžžã«äŒŒãŠãããå®éã«ä»æ§ïŒV3ïŒã§èšåââãããŠããŸãã ãã®ç¹å¥ãªã³ã¡ã³ããã³ãŒãã«å«ããããšã«ããã
eval
ãä»ããŠå®è¡ãããã³ã³ãœãŒã«ã§äœæ¥ããéã«ããå€ãã®è«çåãäžãã
eval
ãåŒã³åºãããšãã§ããŸãã 以äžã¯ãCoffeeScriptã³ã³ãã€ã©ãŒã䜿çšããç°¡åãªäŸã§ãã
äŸ-çæãããååãevalãä»ããŠæž¡ãããã³ãŒã
å¥ã®ãã«ããŒã䜿çšãããšããã®é¢æ°ã®ã³ã³ããã¹ãã§æå®ããã
displayName
ããããã£ã䜿çšããŠãå¿åé¢æ°ã«ååãä»ããããšãã§ããŸãã ã¢ã¯ã·ã§ã³ã®
displayName
ã確èªããã«ã¯ã ãã®äŸããããã¡ã€ã«ããŸãã
äŸ-displayNameã«ããå¿åé¢æ°ã®ååïŒWebKit NIghtlyã®ã¿ïŒ
ãããã¡ã€ãªã³ã°æã«ã
(anonymous function)
代ããã«çŸããååã衚瀺ãããŸãã ãã ããã»ãšãã©ã®å Žåã
displayName
ã¯Google Chromeã®æçµãã«ãã«ã¯å«ãŸããŸããã ãŸã åžæã¯ãããŸãããããããã£ã®ååãdebugNameã«å€æŽããããšãææ¡ããŠããŸãã
å·çæç¹ã§ã¯ã
eval
ã§äœæãããã³ãŒãã®åœåã¯ãFirefoxãšGoogle Chromeã§ã®ã¿ãµããŒããããŠããŸãã
displayName
ããããã£ã¯ãGoogle Chromeãã€ããªãŒãã«ãã§ã®ã¿äœ¿çšå¯èœã§ãã
泚ã蟌ã
CoffeeScriptã§ã®ãœãŒã¹ãããã®ãµããŒãã«é¢ããéåžžã«é·ãè°è«ããããŸãã
UglifyJSã«ã¯ã ãœãŒã¹ãããã®ãµããŒãã«é¢ãããã±ããããããŸãã
ãã£ã¹ã«ãã·ã§ã³ã«åå ãããœãŒã¹ãããã®ãµããŒãã®å¿ èŠæ§ã«ã€ããŠæèŠãè¿°ã¹ãã°åœ¹ç«ã¡ãŸãã ãã®ãã¯ãããžãŒããµããŒãããããŒã«ãå€ããã°å€ãã»ã©ãäœæ¥ã¯ç°¡åã«ãªãã®ã§ããæ°ã«å ¥ãã®ãªãŒãã³ãœãŒã¹ãããžã§ã¯ãã§ãµããŒããäŸé ŒããŠãã ããã
ãœãŒã¹ããããå®å šã§ã¯ãããŸãã
éåžžã®ãããã°ã«ãœãŒã¹ãããã䜿çšããå Žåã1ã€ã®åé¡ããããŸãã åé¡ã¯ããœãŒã¹ãã¡ã€ã«ã®ã³ã³ããã¹ãã§å®çŸ©ãããåŒæ°ãŸãã¯å€æ°ã®å€ã確èªããããšãããšãã³ã³ããã¹ããäœãè¿ããªãããšã§ãã æ¬åœã«ååšããŸããã çž®å°ã³ãŒãå ã®å¯Ÿå¿ããå€æ°/åŒæ°ã®å€ã確èªãããœãŒã¹ã³ãŒããšäžèŽãããã«ã¯ãäœããã®éãããã³ã°ãå¿ èŠã§ãã
ãã®åé¡ã¯è§£æ±ºããããœãŒã¹ãããã«ååãªæ³šæãæããšãããã«èå³æ·±ãã¢ããªã±ãŒã·ã§ã³ã衚瀺ãããå ŽåããããŸãã
ããŒã«ãšãªãœãŒã¹
- ããã¯ã»ãã£ãããžã§ã©ã«ãã¯ããœãŒã¹ãããã®ãµããŒãã§UglifyJSããã©ãŒã¯ããŸãã
- Paul Irishãç°¡åãªãœãŒã¹ããããã¢ãäœæããŸãã
- ã³ã³ã©ããã¢ãŒãŠã£ã³ã¯ãRubyéçºè åãã®äŸ¿å©ãªãœãŒã¹ãããgemãäœæããŸãã
- evalããŒãã³ã°ãšdisplayNameããããã£ã«ã€ããŠä»ã«èªãã¹ãããš
- ãœãŒã¹ããããäœæããClosure Compilerã®ãœãŒã¹ã³ãŒãã確èªã§ããŸãã
- ããã€ãã®ã¹ã¯ãªãŒã³ã·ã§ãããšGWTãœãŒã¹ãããã®ãµããŒãã«ã€ããŠã®èª¬æ
ãœãŒã¹ãããã¯åŒ·åãªéçºè ããŒã«ã§ãã ããã«ããã補åã³ãŒããå¯èœãªéãå§çž®ãããŸãŸã«ããããšãã§ããŸãããåæã«ãããã°ããããšãã§ããŸãã ãŸããåå¿è ã®éçºè ã¯ãçµéšè±å¯ãªéçºè ãäœæããã³ãŒãã衚瀺ããŠãçž®å°ããã³ãŒãã調ã¹ãªããŠãã³ãŒããæ£ããæ§æããã³äœæããæ¹æ³ãåŠã¶ããšãã§ããŸãã ããã§ãããªãã¯äœãåŸ ã£ãŠããŸããïŒ ãããžã§ã¯ãã®ãœãŒã¹ããããçæããŸãïŒ