Comparison of Javascript Bundlers
Total Page:16
File Type:pdf, Size:1020Kb
Sonja Laurila Comparison of JavaScript Bundlers Metropolia University of Applied Sciences Bachelor of Engineering ICT Engineer Bachelor’s Thesis 06.10.2020 Abstract Author Sonja Laurila Title Comparison of JavaScript Bundlers Number of Pages 36 pages + 6 appendices Date 06.10.2020 Degree Bachelor of Engineering Degree Programme ICT Engineer Professional Major Software Engineering Instructors Juha Kämäri, Lecturer The objective of this thesis was to provide a thorough overview of the ideology of bundlers and then create a comparison of four different bundlers selected by their popularity. The study first focused on building a solid understanding of the history of modular JavaScript and how the need for a tool such as bundler arose, how the bundling process goes and what kind of optimization steps the bundling process includes. Next, four different bundlers were configured to bundle a simple React web application. After that a set of test runs was performed to get comparable results of the bundling speed and the resulting bundle size. The bundlers were evaluated from both technical and usability perspectives. As a result, a good understanding of the bundling process and the different bundlers and their characteristics was gained to be able to make better informed decisions when selecting a bundler for a certain use case. As a summary, Parcel would be great for beginners and getting the development environment up and running quickly. Parcel also offers extremely quick rebuild times due to caching. Webpack offers the best flexibility, quick rebuild times and good chunk splitting options. Rollup will most probably result in the smallest bundle size due to its advanced tree shaking capabilities. As to Browserify, it would probably be good to keep it on the server-side JavaScript, if the user is not already familiar with it. Keywords Bundler, bundling, Webpack, Browserify, Rollup, Parcel Abstract Tekijä Sonja Laurila Otsikko JavaScript bundlerien vertailu Sivumäärä 36 sivua + 6 liitettä Aika 06.10.2020 Tutkinto Insinööri21.8.2017 (AMK) Tutkinto-ohjelma Tieto- ja viestintätekniikka Ammatillinen pääaine Ohjelmistotuotanto Ohjaajat Juha Kämäri, Lehtori Työn tavoitteena oli luoda kattava kokonaiskuva koodin koontityökalujen (bundlerien) ideologiasta ja laatia vertailu, jossa vertaillaan neljää suosituinta koontityökalua. Opinnäytetyö keskittyy ensin rakentamaan syvällisen ymmärryksen modulaarisen JavaScriptin historiasta ja siitä, kuinka tarve koontityökalun kaltaiselle työkalulle heräsi. Mitä koontiprosessin aikana tapahtuu ja minkälaisia optimointivaiheita koontiprosessi sisältää. Konseptin ymmärtämisen jälkeen neljä eri koontityökalua konfiguroitiin niin, että niillä voitiin koota yksinkertainen React-sovellus. Konfiguroinnin jälkeen ajettiin testiajoja, jotta saatiin vertailukelpoisia tuloksia koontityökalujen nopeudesta ja tuloksena saadun kootun tiedoston koosta. Koontityökaluja arvioitiin sekä teknisestä, että käytettävyyden näkökulmasta. Lopputuloksena saatiin hyvä käsitys koontiprosessista ja eri koontityökaluista sekä niiden eroista, jotta voidaan tulevaisuudessa tehdä parempia päätöksiä valittaessa koontityökalua tiettyyn käyttötapaukseen. Yhteenvetona Parcel olisi hyvä aloittelijoille ja kehitysympäristön käynnistämiseen nopeasti sekä sen välimuistin käytön vuoksi tarvittaessa erittäin nopeita uudelleenkoontiaikoja. Webpack on kaikista joustavin ja tarjoaa myös nopeat koontiajat. Rollup todennäköisesti saavuttaa pienimmän kootun koodin koon, koska sillä on erinomaiset ”puunravistus”-kyvyt (tree shaking). Browserify on ehkä hyvä pitää serveripuolen JavaScriptissä, ellei käyttäjä sitten ole jo entuudestaan perehtynyt siihen. Avainsanat Bundler, bundlaus, Webpack, Browserify, Rollup, Parcel, koodin koontityökalu Contents List of Abbreviations 1 Introduction 1 2 JavaScript Bundling 2 2.1 Modules and Closures 2 2.1.1 Closure 3 2.1.2 Global Module Object with IIFE 3 2.1.3 CommonJS 4 2.1.4 Asynchronous Module Definition (AMD) 4 2.1.5 Universal Module Definition (UMD) 5 2.1.6 ES6 modules 5 2.2 Module Loaders 6 2.3 Bundlers 7 2.3.1 Bundling Process 8 2.3.2 Optimizing Bundles 9 3 Different Bundlers 12 3.1 Webpack 13 3.2 Browserify 14 3.3 Rollup 15 3.4 Parcel 15 4 Creating Simple Web Application for Comparison Basis 16 4.1 Creating Package.json File 16 4.2 Creating Simple React Application 17 5 Configuring and Bundling Projects with Different Bundlers 19 5.1 Webpack 19 5.2 Browserify 22 5.3 Rollup 24 5.4 Parcel 27 6 Bundler Comparison 29 7 Conclusions 35 References 36 Appendices Appendix 1. Small React application’s source code Appendix 2. Package.json and webpack.config.js when bundling with Webpack Appendix 3. Package.json when bundling with Browserify Appendix 4. Package.json and rollup.config.js when bundling with Rollup Appendix 5. Package.json when bundling with Parcel Appendix 6. Explanations for bundler features in Table 2 List of Abbreviations CLI Command Line Interface. Interface which one can use to run a software from the command line. DOM Document Object Model. HTML or XML tree structure interface. ES6 ECMAScript 6. Scripting-language specification standardized by Ecma International in ECMA-262. HTML Hypertext Markup Language. The standard mark-up language for files designed to be displayed in a browser. IIFE Immediately Invoked Function Expression. JavaScript function that runs immediately after it has been defined. JSX JavaScript XML. Syntax extension for JavaScript, used in React and resembling XML. npm Node Package Manager. Software registry and command line interface for node packages to share and borrow open-source node packages to and from other developers. 1 1 Introduction To run JavaScript in the browser, HTML files contain script tags, which contain JavaScript. In a case of larger applications, one typically wants to split the code into multiple JavaScript files, also known as modules, which would then lead into multiple script tags in the HTML file. The struggle here is to have the files in the correct order, because otherwise, the code does not run correctly and may lead into bugs and application crashing. Also, one should make sure that in the multiple files, the global variables and function names do not overlap each other, since if they are global in the file, they would be global also on the application level, which could cause overriding and mal-functioning. Bundlers can be used to automate handling the imports and taking care of how the modules work together. This thesis focuses on explaining the bundling need and process and comparing the features of the four most popular bundlers: Webpack, Browserify, Rollup and Parcel. During the thesis project, a small React frontend application was bundled with all four bundlers to get hands-on experience on what was it like to configure and use the different bundlers and what kind of features and characteristics they have. Currently there is widely spread inertia for using Webpack, which might lead into making misinformed decisions on which bundling tool to use and furthermore to unoptimized production bundles. The goal of the thesis is to find and understand the key differences between different bundlers and which bundler fits best in a certain use case and to learn how to configure them. The topic was chosen due to the author’s personal interest and identification of personal lack of knowledge and understanding. 2 2 JavaScript Bundling To deeply understand the need behind bundling, one needs to understand the need for JavaScript modules and the expansion of web development from little inline scripts on a HTML file into the modern web applications that are developed today. 2.1 Modules and Closures JavaScript works on a HTML file, inside a script tag. One can start by writing inline scripts between the tags, but when the application grows, the script tag expands and the code is not reusable, but the coder shall copy and paste it to be able to use it on another page of the application. It is necessary to move it into its own file, to be able to reuse it on another page. The file then expands, and it is needed to divide into multiple files. An example of a typical old-school HTML with an inline script tag is shown below. Important parts have been highlighted in green. <!DOCTYPE html> <html lang="en"> <head> <title>Application title</title> </head> <body> <button id="btn" onclick="clickFunction()">Click me!</button> <script type="text/javascript"> function clickFunction(){ alert('Hello you!') } </script> </body> </html> It is common for a coder to want to add external node packages later to make coding easier and then the situation with the script tags can already be quite complicated, because the script tags must be in the correct order in the HTML file. Also, the global namespace gets polluted by all the globally defined functions and variables. The maintainability of the code is on a poor level and the coder must do duplicate work when implementing new changes. An example of a HTML file with external libraries can be seen below. In this case there were scripts for adding React and ReactDOM and a button component, which can be assumed to internally use React and ReactDOM. Important parts have been highlighted green. 3 <!DOCTYPE html> <html lang="en"> <head> <title>Application title</title> </head> <body> <div id="btn"></div> <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src="button.js"></script> </body> </html> As