SlideShare a Scribd company logo
Menguak Misteri Module Bundler
Halo, saya Riza!
Menguak Misteri Module Bundler
@rizafahmi22
#livecampid
Agenda
Demo aplikasi
Menulis JS yang lebih modular
Menggunakan Module Bundler
🍀
Vanilla
Leaderboard
https://vanilla-leaderboard.web.app
🍀
Vanilla
Leaderboard
🍀
Vanilla
Leaderboard
confetti-js
🍀
Vanilla
Leaderboard
lil-uuid
🍀
Vanilla
Leaderboard
xStore
🍀
Vanilla
Leaderboard
dayjs
🍀
Vanilla
Leaderboard
workbox
6 requests hanya untuk JS 😱
Vendors
Menguak Misteri Module Bundler
#!/usr/bin/env bash
set -e
deps=(
"gh/lil-js/uuid@0.1.1/uuid.min.js"
"gh/florian/xStore@2.0.4/src/xStore.min.js"
"npm/confetti-js@0.0.18/dist/index.min.js"
"npm/dayjs@1.8.21/dayjs.min.js"
"npm/dayjs@1.8.21/plugin/relativeTime.js"
)
for i in "${deps[@]}"
do
curl "https://cdn.jsdelivr.net/${i}" -L
echo ";"
done $ ./buildVendors.sh > vendors.js
✅ Concatenation
✅ Minification
Solusi yang bagus
di 2008
Solusi yang bagus
Solusi yang lebih baik
• Proses update dependencies yang lebih
mudah
• Tidak khawatir terhadap dependencies of
dependencies
• Urutan dari import tidak menjadi masalah
JavaScript Modules
function add(a, b) {
return a + b;
}
function sub(a, b) {
return a - b;
}
function mul(a, b) {
return a * b;
}
function div(a, b) {
return a / b;
}
basic_calc.js
advance_calc.js
function squared(a) {
return mul(a, a);
}
calc.html
<script src="js/basic_calc.js"></script>
<script src=“js/advance_calc.js"></script>
<script>
console.log(squared(4));
console.log(add(3, 4));
console.log(mul(3, 5));
</script>
Semuanya jadi global 😢
Bungkus Menjadi Fungsi
let BasicCalc = function() {
return {
add: function(a, b) {
return a + b;
},
sub: function(a, b) {
return a - b;
},
mul: function(a, b) {
return a * b;
},
div: function(a, b) {
return a / b;
}
};
};
basic_calc.js
advance_calc.js
let AdvanceCalc = function() {
return {
squared: function squared(a) {
return BasicCalc().mul(a, a);
}
};
};
calc.html
Ok, tapi jadi aneh 🤔
<script src="js/basic_calc.js"></script>
<script src=“js/advance_calc.js"></script>
<script>
console.log(AdvanceCalc().squared(4));
console.log(BasicCalc().add(3, 4));
console.log(BasicCalc().mul(3, 5));
</script>
iifeImmediately Invoked Function Expression
let add = function (a, b) {
return a + b;
}
console.log(add(1, 2));
let add = (function (a, b) {
return a + b;
})(1, 2);
console.log(add);
let BasicCalc = function() {
return {
add: function(a, b) {
return a + b;
},
sub: function(a, b) {
return a - b;
},
mul: function(a, b) {
return a * b;
},
div: function(a, b) {
return a / b;
}
};
};
basic_calc.js
basic_calc.js
let BasicCalc = (function() {
return {
add: function(a, b) {
return a + b;
},
sub: function(a, b) {
return a - b;
},
mul: function(a, b) {
return a * b;
},
div: function(a, b) {
return a / b;
}
};
})();
advance_calc.js
let AdvanceCalc = function() {
return {
squared: function squared(a) {
return BasicCalc().mul(a, a);
}
};
};
advance_calc.js
let AdvanceCalc = (function() {
return {
squared: function squared(a) {
return BasicCalc.mul(a, a);
}
};
})();
calc.html
<script src="js/basic_calc.js"></script>
<script src=“js/advance_calc.js"></script>
<script>
console.log(AdvanceCalc().squared(4));
console.log(BasicCalc().add(3, 4));
console.log(BasicCalc().mul(3, 5));
</script>
calc.html
<script src="js/basic_calc.js"></script>
<script src="js/advance_calc.js"></script>
<script>
console.log(AdvanceCalc.squared(4));
console.log(BasicCalc.add(3, 4));
console.log(BasicCalc.mul(3, 5));
</script>
Suatu saat kita butuh sistem
modulasi yang dapat digunakan di
aplikasi atau proyek berbeda
Module System
• Sintaksis yang lebih sederhana untuk
import/export
• Bisa dengan mudah mendefinisikan modul
di file terpisah
• Bisa saling import
Must have!
Module System
• Menghindari name collision
• Import modul secara async
• Bisa di browser atau di server via
node.js
Nice to have!
JS Module System
Module System
• Globals
• CommonJS
• Asynchronous Module Definition (AMD)
• Universal Module Definition (UMD)
• ES2015 Module (ESM)
• Lainnya…
globals
var $, jQuery;
$ = jQuery = (() => {
return { /* ... */ }
})();
// usage
$('.btn-success').remove();
Globals
• Naming collisions 👎
• Urutan import harus diperhatikan 👎
• Tidak bisa import sebagian modul yang
dibutuhkan 👎
• Hanya bisa menggunakan pustaka dari CDN 👎
CommonJS
// calc.js
const calc = {
/* ... */
}
module.exports = calc;
// app.js
const calc = require('./calc.js');
calc.add(1, 3);
// other_app.js
const { add } = require('./calc.js');
calc.add(1, 3);
CommonJS
• Tidak terjadi naming collision 👍
• Pustaka banyak tersedia via npm 👍
• Dapat digunakan di server via Node.js 👍
• Belum bisa untuk di browser 👎
• Hanya bisa import secara synchronous 👎
Asynchronous Module Definition
// lib.js
define('yayQuery', ['yayQueryUI'], function(yayQueryUI) {
// returns the exported value
return function() {
// ...
};
});
// app.js
// define path
requirejs.config({
baseUrl: 'js/lib/',
paths: {
yayquery: 'yayquery-1.1.1'
}
});
define(['yayquery'], function($) {
// this is executed only when yayquery and it's deps are loaded
});
Require.JS/AMD
• Async module 👍
• Bisa berjalan di browser dan server 👍
• Kode boilerplate cukup banyak 👎
Universal Module Definition
(function(root, factory) {
if (typeof exports === 'object') {
// CommonJS
module.exports = factory(require('dep'));
} else if (typeof define === 'function' && define.amd) {
// AMD
define(['dep'], function(dep) {
return (root.returnExportsGlobal = factory(dep));
});
} else {
// Globals
root.myModule = factory(root.dep);
}
})(this, function(dep) {
// Your actual module
return {};
});
Universal Module Definition
• Semua jenis modul bisa digunakan 👍
• Kode pembungkus cukup kompleks,
sepertinya sulit ditulis manual 👎
ES2015 Modules
// calc.js
const add = (a, b) => a + b;
const sub = (a, b) => a - b;
const mul = (a, b) => a * b;
const div = (a, b) => a / b;
export { add, sub, mul, div };
// app.js
import { add } from './calc.js';
console.log(add(1, 3));
ES2015 Modules
<html>
<body>
<!-- ... -->
<script type="module">
import { add } from ‘./basic_calc.js';
console.log(add(1, 3));
</script>
</body>
</html>
ES2015 Modules
• Secara sintaksis mirip dengan CommonJS
• (Hampir) menjadi format baku 👍
• (Hampir) dapat berjalan di browser dan
server 👍
Mari Kita Coba
const BasicCalc = require('./basic_calc.js');
function squared(a) {
return BasicCalc.mul(a, a);
}
CommonJS
ESM
import { mul } from './basic_calc.js';
function squared(a) {
return mul(a, a);
}
Module Bundler
Alat bantu untuk melakukan
bundle JavaScript modules menjadi satu
file dan dan dapat dijalankan di
browser.
Fitur Penting Lainnya
• Sistem modulasi belum sepenuhnya
didukung oleh browser
• Menangani dependencies dan hubungan
dengan dependencies lain
• Dapat pula digunakan untuk gambar, CSS
dan aset lainnya.
Fitur Tambahan
• Menjalankan development server
• Tree shaking
• Membuat source map otomatis
• Code splitting
Konsep Umum Bundler
• Entry point: file utama yang akan dicek
oleh bundler
• Output: File akhir yang akan digunakan
• Loaders: Algoritma parsing yang ingin
digunakan seperti babel, typescript,
dll.
• Plugins: Fitur tambahan yang dibutuhkan.
Menguak Misteri Module Bundler
$ npm install webpack webpack-cli
basic_calc.js
function add(a, b) {
return a + b;
}
function mul(a, b) {
return a * b;
}
export { add, mul };
advance_calc.js
import { mul } from './basic_calc.js';
function squared(a) {
return mul(a, a);
}
export { squared };
import { add, mul } from './basic_calc.js';
import { squared } from './advance_calc.js';
console.log(add(1, 3));
console.log(mul(2, 4));
console.log(squared(4));
main.js
$ npx webpack js/main.js
const modules = {
'basic_calc.js': function(exports, require) {
exports.add = function(a, b) {
return a + b;
};
exports.mul = function(a, b) {
return a * b;
};
},
'advance_calc.js': function(exports, require) {
const mul = require('basic_calc.js').mul;
exports.squared = function(a) {
return mul(a, a);
};
},
'main.js': function(exports, require) {
const add = require('basic_calc.js').add;
const mul = require('basic_calc.js').mul;
const squared = require('advance_calc.js').squared;
console.log(add(1, 3));
console.log(mul(2, 4));
console.log(squared(4));
}
};
webpackStart({
modules,
entry: 'app.js'
});
Ilustrasi Webpack
🍀 Leaderboard
$ npm install confetti-js dayjs lil-uuid xStore
module.exports = {
entry: ['./js/app.js'],
output: {
path: __dirname + '/dist',
filename: 'bundle.webpack.js'
},
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
}
// plugins: []
}; webpack.config.js
module.exports = {
entry: ['./js/app.js'],
output: {
path: __dirname + '/dist',
filename: 'bundle.webpack.js'
},
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
}
// plugins: []
}; webpack.config.js
Entry point
module.exports = {
entry: ['./js/app.js'],
output: {
path: __dirname + '/dist',
filename: 'bundle.webpack.js'
},
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
}
// plugins: []
}; webpack.config.js
Output
module.exports = {
entry: ['./js/app.js'],
output: {
path: __dirname + '/dist',
filename: 'bundle.webpack.js'
},
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
}
// plugins: []
}; webpack.config.js
Loaders
module.exports = {
entry: ['./js/app.js'],
output: {
path: __dirname + '/dist',
filename: 'bundle.webpack.js'
},
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
}
// plugins: []
}; webpack.config.js
$ npx webpack --config webpack.config.js
<html lang="en">
<body>
…
<script src=“dist/bundle.webpack.js"></script>
</body>
</html>
Gaya Webpack
• Menggunakan module map
• Menggunakan fungsi untuk membungkus
setiap modul
rollup.js
$ npm install rollup rollup-plugin-babel
basic_calc.js
function add(a, b) {
return a + b;
}
function mul(a, b) {
return a * b;
}
export { add, mul };
advance_calc.js
import { mul } from './basic_calc.js';
function squared(a) {
return mul(a, a);
}
export { squared };
import { add, mul } from './basic_calc.js';
import { squared } from './advance_calc.js';
console.log(add(1, 3));
console.log(mul(2, 4));
console.log(squared(4));
main.js
import babel from 'rollup-plugin-babel';
export default {
input: 'js/main.js',
output: {
file: 'dist/bundle.rollup.js',
format: 'iife'
},
plugins: [
babel()
]
};
rollup.config.js
import babel from 'rollup-plugin-babel';
export default {
input: 'js/main.js',
output: {
file: 'dist/bundle.rollup.js',
format: 'iife'
},
plugins: [
babel()
]
};
rollup.config.js
Entry Point
import babel from 'rollup-plugin-babel';
export default {
input: 'js/main.js',
output: {
file: 'dist/bundle.rollup.js',
format: 'iife'
},
plugins: [
babel()
]
};
Output
rollup.config.js
import babel from 'rollup-plugin-babel';
export default {
input: 'js/main.js',
output: {
file: 'dist/bundle.rollup.js',
format: 'iife'
},
plugins: [
babel()
]
};
rollup.config.js
Loaders & Plugins
$ npx rollup -c
function basic_calc$add(a, b) {
return a + b;
}
function basic_calc$mul(a, b) {
return a * b;
}
function advance_calc$squared(a) {
return basic_calc$mul(a, a);
}
console.log(basic_calc$add(1, 3));
console.log(basic_calc$mul(2, 4));
console.log(advance_calc$squared(4));
Ilustrasi Rollup
🍀 Leaderboard
$ npm install confetti-js dayjs lil-uuid xStore
$ npm install rollup-plugin-commonjs rollup-plugin-node-resolve rollup-plugin-uglify
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import babel from 'rollup-plugin-babel';
import { uglify } from 'rollup-plugin-uglify';
export default {
input: 'js/app.js',
output: {
file: 'dist/bundle.rollup.js',
format: 'iife',
globals: {
'dayjs/plugin/relativeTime': 'relativeTime',
dayjs: 'dayjs',
xStore: 'xStore',
lil: 'lil-uuid',
ConfettiGenerator: 'confetti-js'
}
},
plugins: [
resolve(),
commonjs(),
babel({ exclude: 'node_modules/*' }),
uglify()
]
}; rollup.config.js
$ npx rollup -c
<html lang="en">
<body>
…
<script src=“dist/bundle.rollup.js”></script>
</body>
</html>
Gaya Rollup
• Menghasilkan bundle yang lebih rata dan
sederhana
• Tidak menggunakan fungsi pembungkus
🍀
Vanilla
Leaderboard
https://vanilla-leaderboard.web.app
🍀
Vanilla
Leaderboard
https://github.com/rizafahmi/vanilla-leaderboard
Kesimpulan
Kesimpulan
• Module bundler adalah alat bantu untuk
membungkus JavaScript agar dimengerti
browser
• Bundler dibutuhkan agar aplikasi lebih
modular dan dapat menggunakan sintaksis
JavaScript modern
• Menggunakan concatenation dan minification
cukup untuk aplikasi sederhana
@rizafahmi22
#livecampid

More Related Content

PDF
Comprendre la programmation fonctionnelle, Blend Web Mix le 02/11/2016
PDF
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
PDF
An introduction to functional programming with Go [redux]
PPTX
OpenResty/Lua 70+ Advanced Programming Skills and Optimization tips
KEY
PDF
Hyrje openmp
ODP
C++14 reflections
PDF
이승재, 강성훈, 내가 만든 언어의 개발환경을 Visual Studio Code로 빠르고 쉽게 구축하기 #2, NDC2017
Comprendre la programmation fonctionnelle, Blend Web Mix le 02/11/2016
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
An introduction to functional programming with Go [redux]
OpenResty/Lua 70+ Advanced Programming Skills and Optimization tips
Hyrje openmp
C++14 reflections
이승재, 강성훈, 내가 만든 언어의 개발환경을 Visual Studio Code로 빠르고 쉽게 구축하기 #2, NDC2017

What's hot (19)

DOCX
matrix operation using operator overloading
PDF
Boost.勉強会#4 Boost.Proto
PDF
JQuery
PDF
ECMAScript 6 im Produktivbetrieb
PDF
Writeup ctf online idsecconf 2017
PDF
Monads
PPTX
Peggy optimist
PDF
Virapix-ClassDiagram
DOCX
program data rawat inap sederhana
ODP
Антон Полухин. C++17
PDF
Java script.trend(spec)
PDF
数式を構文解析した話
DOCX
โปรแกรมย่อยและฟังก์ชันมาตรฐาน
PDF
ECMAscript 2015 aka ES6 : à la découverte du nouveau javascript
PDF
I will be callback/JS同步與非同步
PDF
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
PPTX
Алексей Кутумов, C++ без исключений, часть 3
PDF
Laporan ai modul 3-if b 2014-14102055-deprilana ego prakasa
matrix operation using operator overloading
Boost.勉強会#4 Boost.Proto
JQuery
ECMAScript 6 im Produktivbetrieb
Writeup ctf online idsecconf 2017
Monads
Peggy optimist
Virapix-ClassDiagram
program data rawat inap sederhana
Антон Полухин. C++17
Java script.trend(spec)
数式を構文解析した話
โปรแกรมย่อยและฟังก์ชันมาตรฐาน
ECMAscript 2015 aka ES6 : à la découverte du nouveau javascript
I will be callback/JS同步與非同步
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Алексей Кутумов, C++ без исключений, часть 3
Laporan ai modul 3-if b 2014-14102055-deprilana ego prakasa
Ad

More from Riza Fahmi (20)

PDF
Membangun Aplikasi Web dengan Elixir dan Phoenix
PDF
Berbagai Pilihan Karir Developer
PDF
Web dan Progressive Web Apps di 2020
PDF
Remote Working/Learning
PDF
How to learn programming
PDF
Rapid App Development with AWS Amplify
PDF
Beberapa Web API Menarik
PDF
MVP development from software developer perspective
PDF
Ekosistem JavaScript di Indonesia
PDF
Perkenalan ReasonML
PDF
How I Generate Idea
PDF
Strategi Presentasi Untuk Developer Workshop Slide
PDF
Lesson Learned from Prolific Developers
PDF
Clean Code JavaScript
PDF
The Future of AI
PDF
Chrome Dev Summit 2018 - Personal Take Aways
PDF
Essentials and Impactful Features of ES6
PDF
Modern Static Site with GatsbyJS
PDF
Introduction to ReasonML
PDF
Machine learning with py torch
Membangun Aplikasi Web dengan Elixir dan Phoenix
Berbagai Pilihan Karir Developer
Web dan Progressive Web Apps di 2020
Remote Working/Learning
How to learn programming
Rapid App Development with AWS Amplify
Beberapa Web API Menarik
MVP development from software developer perspective
Ekosistem JavaScript di Indonesia
Perkenalan ReasonML
How I Generate Idea
Strategi Presentasi Untuk Developer Workshop Slide
Lesson Learned from Prolific Developers
Clean Code JavaScript
The Future of AI
Chrome Dev Summit 2018 - Personal Take Aways
Essentials and Impactful Features of ES6
Modern Static Site with GatsbyJS
Introduction to ReasonML
Machine learning with py torch
Ad

Menguak Misteri Module Bundler