{"id":1080,"date":"2017-10-17T17:23:03","date_gmt":"2017-10-17T17:23:03","guid":{"rendered":"http:\/\/www.codedread.com\/blog\/?p=1080"},"modified":"2017-10-18T07:04:37","modified_gmt":"2017-10-18T07:04:37","slug":"the-dawn-of-modern-javascript","status":"publish","type":"post","link":"https:\/\/www.codedread.com\/blog\/archives\/2017\/10\/17\/the-dawn-of-modern-javascript\/","title":{"rendered":"The Dawn of Modern JavaScript"},"content":{"rendered":"<p><a href=\"http:\/\/caniuse.com\/#search=modules\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/codedread.com\/clipart\/javascript.svgz\" width=\"100\" height=\"100\" style=\"float:right\" alt=\"JavaScript logo\"\/><\/a><\/p>\n<p>The last piece heralding the dawn of modern JavaScript (sometimes thought of as ES6, but we're past that now) arrived last month when two browsers (Chrome and Safari) shipped support for <a href=\"https:\/\/hacks.mozilla.org\/2015\/08\/es6-in-depth-modules\/\">ES6 modules<\/a> natively without developer flags.  It's now possible to write all this stuff (modules, classes, arrow functions, const\/let variables, Promises) using just your code and not relying on <a href=\"https:\/\/en.wikipedia.org\/wiki\/transpiler\">transpilers<\/a>!<\/p>\n<p><!--more--><\/p>\n<p>I've been using <a href=\"https:\/\/github.com\/google\/traceur-compiler\">Traceur<\/a> on a hobby project for a couple years now but I had put development on hold for a few months.  Traceur is the transpiler-that-lost (development community declared <a href=\"https:\/\/babeljs.io\/\">Babel<\/a> the winner and Traceur hasn't had a commit in over a year).<\/p>\n<p>Picking the project up again in October 2017 and doing some debugging, I was mystified when my code was instantiating two instances of what should have been a singleton JavaScript service.  Here is what my main HTML file looked like:<code><br \/>\n&#160;&#160;&#60;script src=\"traceur.js\"&#62;&#60;\/script&#62;<br \/>\n&#160;&#160;&#60;script&#62;<br \/>\n&#160;&#160;&#160;&#160;var options = new traceur.util.Options();<br \/>\n&#160;&#160;&#160;&#160;new traceur.WebPageTranscoder(document.location.href, options).run();<br \/>\n&#160;&#160;&#60;\/script&#62;<br \/>\n&#160;&#160;&#60;script type=\"module\" src=\"main.js\"&#62;&#60;\/script&#62;<br \/>\n<\/code><\/p>\n<p>The first script loads the main Traceur library, the second script does the transpilation of any scripts of type \"module\" in the page.  Browsers that do not understand ES6 modules ignore the main.js script element (up until September, this was every shipping browser).<\/p>\n<p>Of course what was happening was that Chrome 61 was also loading in the main.js ES6 module itself (in addition to doing the transpilation).  Thus, I was seeing two copies of things running in the browser.<\/p>\n<h2 id=\"nomodule\">The nomodule Attribute<\/h2>\n<p>The trick is to use <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTML\/Element\/script#attr-nomodule\">the nomodule attribute<\/a> on script elements that we want the browser to ignore if they understand what an ES6 module is:<code><br \/>\n&#160;&#160;&#60;script <b style=\"color:blue\">nomodule<\/b> src=\"traceur.js\"&#62;&#60;\/script&#62;<br \/>\n&#160;&#160;&#60;script <b style=\"color:blue\">nomodule<\/b>&#62;<br \/>\n&#160;&#160;&#160;&#160;var options = new traceur.util.Options();<br \/>\n&#160;&#160;&#160;&#160;new traceur.WebPageTranscoder(document.location.href, options).run();<br \/>\n&#160;&#160;&#60;\/script&#62;<br \/>\n&#160;&#160;&#60;script type=\"module\" src=\"main.js\"&#62;&#60;\/script&#62;<br \/>\n<\/code><\/p>\n<p>Now Firefox and Edge will be able to load the page with or without ES6 module support enabled via developer settings.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The last piece heralding the dawn of modern JavaScript (sometimes thought of as ES6, but we&#8217;re past that now) arrived last month when two browsers (Chrome and Safari) shipped support for ES6 modules natively without developer flags. It&#8217;s now possible to write all this stuff (modules, classes, arrow functions, const\/let variables, Promises) using just your [&#8230;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[199,35,38,44,25,11,28],"tags":[],"class_list":["post-1080","post","type-post","status-publish","format-standard","hentry","category-chrome","category-firefox","category-javascript","category-safari","category-software","category-technology","category-web"],"_links":{"self":[{"href":"https:\/\/www.codedread.com\/blog\/wp-json\/wp\/v2\/posts\/1080","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codedread.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.codedread.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.codedread.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codedread.com\/blog\/wp-json\/wp\/v2\/comments?post=1080"}],"version-history":[{"count":13,"href":"https:\/\/www.codedread.com\/blog\/wp-json\/wp\/v2\/posts\/1080\/revisions"}],"predecessor-version":[{"id":1097,"href":"https:\/\/www.codedread.com\/blog\/wp-json\/wp\/v2\/posts\/1080\/revisions\/1097"}],"wp:attachment":[{"href":"https:\/\/www.codedread.com\/blog\/wp-json\/wp\/v2\/media?parent=1080"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.codedread.com\/blog\/wp-json\/wp\/v2\/categories?post=1080"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.codedread.com\/blog\/wp-json\/wp\/v2\/tags?post=1080"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}