LogoLogo
Navigation
Advanced Javascript
Advanced Javascript
  • 😆Attribute Starts With Selector [name^="value"] (ok)
  • 🥹 Tìm hiểu về Map và Set trong javascript (ok)
  • 🫢 The Array.from() method returns an array from any iterable object. (ok)
  • 😍localeCompare() method compares two strings return sort order -1, 1,0 (for before, after, or equal)
  • 😍JavaScript Array some() method returns true (and stops) if the function returns true() (ok)
  • Add key value pair to all objects in array (ok)
  • 🥸Làm một sider tuyệt đẹp "Timed-Cards-Opening"
  • 🥸Scroll animations! How to add a flowing path like the Lusion site with SVG and Javascript (ok)
  • Chia sẽ code plugin tạo thời gian chờ tải cho nút download
  • 😛jQuery 1.9 .live,.delegate,.on is not a function (ok)
  • 😁Importing CSS Breakpoints Into JavaScript (ok)
  • The matchMedia() method returns a MediaQueryList with the results from the query. (ok)
  • Collect nhiều sách pdf (ok)
  • 😁Check device Agent chrome, firefox ... (ok)
  • === START Three.js and TypeScript ===
  • Setup Development Environment (ok)
  • === END Three.js and TypeScript ===
  • === START THREE.JS ===
  • 🥳Fundamentals - three.js manual
    • Light trong Three.js
  • == Start Nguyên tắc cơ bản ===
  • Nguyên tắc cơ bản
  • Thiết kế đáp ứng
  • nguyên thủy
  • 😅Điều chỉnh camera (ok)
  • 😅Điều chỉnh scale
  • 🥲Xử lý màn hình HD-DPI
  • 😃So sánh Mesh với Object3D
  • 😅Trục AxesHelper
  • 😅Tạo GridHelper
  • 😆MeshBasic, MeshLambert, MeshPhong, MeshToon, MeshStandard, MeshPhysical, Shader, RawShader
  • == End Nguyên tắc cơ bản ===
  • 🥰Bài viết mẫu thự hành tọa độ, quay (ok)
  • Giới thiệu HTML5 Canvas
  • Bài 1: Làm quen với môi trường 3D của ThreeJS
  • Bài 2: Dịch chuyển đối tượng 3D - Controls
  • Bài 3: makeup
  • Bài 4: Models loader
  • 😁Những trang học three.js
  • Source Code Example
  • === END THREE.JS ===
  • === START WebGL ===
  • 😇Trang học WebGL && Shador
  • 😅Tìm hiểu về OpenGL ES 2.0
  • Tìm hiểu về WebGL phần 1: thư viện đồ họa web.
  • Tìm hiểu WebGL Phần 2: Đi sâu vào cách code WebGL appication
  • Tìm hiểu WebGL Phần 3: Đi sau vào cách code WebGL appication - các ví dụ
  • Tìm hiểu WebGL Phần 4: Các ví dụ.
  • === END WebGL ===
  • 😃Getting started with systemjs full (ok)
  • Đọc thêm bài này Mô-đun ECMAScript và khả năng tương thích trình duyệt (ok)
  • 😖Thư viện chặn truy cập vào Devtool (ok)
  • === START JAVASCRIPT Vanila ===
  • 😄Làm cách nào để ngăn sự kiện onclick của cha mẹ kích hoạt khi nhấp vào con parent, child ? (ok)
  • 😁Bootstrap 5 - multi item carousel (ok)
  • Three dots ( … ) in JavaScript
  • "... Three Dots" đã thay đổi javascript như thếnào ?
  • Array-like objects, Chuyển đối tượng arguments thành array (ok)
  • 😇Making a short alias for document.querySelectorAll (ok)
  • JavasScript Siblings (ok)
  • JavaScript Modules Full (ok)
  • JavaScript select Element (ok)
  • === END JAVASCRIPT Vanila ===
  • Sử dụng async, await, bất đồng bộ lấy dữ liệu Pagination, sử dụng Deferred 👌 phần 2 (ok)
  • how to use multiple ternary operator in javascript, ?:, ?? (ok)
  • 😅[DATETIMEPICKER] jQuery Plugin Date and Time Picke Full (ok)
  • === START tutorial HYPERAPP ==
  • [HYPERAPP] Hyperapp - JavaScript micro-framework chỉ 1kB (ok)
  • [HYPERAPP] hyperapp-tutorial-step-1 (ok)
  • [HYPERAPP] hyperapp-tutorial-step-2 (ok)
  • [HYPERAPP] hyperapp-tutorial-step-3 (ok)
  • [HYPERAPP] hyperapp-tutorial-step-4 (ok)
  • === END tutorial HYPERAPP ==
  • Free and Open Source Web Builder Framework
  • 😁How to recursively fetch data from paginated API then combine into one array (ok)
  • 😆Create a form with dom with nested tags, Wrapping a set of DOM elements using JavaScript (ok)
  • 😇Array find, Tìm phần tử đầu tiên thỏa mãn điều kiện (ok)
  • 😁Array find, Tìm phần tử cuối cùng thỏa mãn điều kiện (ok)
  • Cách tích hợp bộ lọc select chọn nhanh Tỉnh, Thành & Quận, Huyện, districts, provinces (ok)
  • object with methods, you can simply call a method from the object returned. (ok)
  • Portfolio, Filter, Gallery, Tabmenu (ok)
  • JavaScript chạy bất đồng bộ như thế nào?, Microtask ,Macrotask, queueMicrotask bài viết hay (ok)
  • 😋Learn prototypejs 😒😒😒
  • === START JavaScript chuyên sâu ===
  • [JavaScript chuyên sâu] Higher order function trong JavaScript - phần 1 (ok)
  • [JavaScript chuyên sâu] - Higher order function - phần 2: closure, currying, callback
  • [JavaScript chuyên sâu] - So sánh Constructor Function và Factory Function
  • [JavaScript chuyên sâu] - 5 vai trò của Function: function, object, property, callback, constructor
  • [JavaScript chuyên sâu] : Đồng bộ và bất đồng bộ của JavaScript - phần 1: Callback
  • [JavaScript chuyên sâu]: Từ hàm IIFE tới Module Pattern
    • 😍IIFE=>Immediately Invoked Function Expression=>khởi tạo function & chạy ngay, import, export như nào
  • Tìm hiểu về Higher-Order Functions trong JavaScript
  • === END JavaScript chuyên sâu ===
  • QR-Card (ok)
  • === START DATATABLE ===
  • [DATATABLE] bộ lọc sử dụng các thẻ bên trong td matter.vn (ok)
  • 😁[DATATABLE] JQuery Datatables Editor - Alternative to the official one (ok)
  • Example: Datatables Add Edit Delete with Ajax, PHP & MySQL (ok)
  • [DATATABLE] fixedColumns, DataTable, Left and right fixed columns (ok)
  • [DATATABLE] Sử dụng thư viện dataTables.bootstrap.min.js && dataTables.bootstrap.min.js (ok)
  • [DATATABLE] DataTables.net with DataTableQueryBuilder sample input filter (ok)
  • [DATATABLE] How to use Tabledit plugin with jQuery Datatable in PHP Ajax (ok)
  • [DATATABLE] DataTables Custom Filter Demo (ok)
  • [DATATABLE] Datatable multiple checkbox demo (ok)
  • [DATATABLE] HTML5 export buttons (ok)
  • [DATATABLE] CodePen Home DataTable 2 Card view (ok)
  • [DATATABLE] DataTables - Column Search (ok)
  • [DATATABLE] CodePen Home dataTables conditional row and cell styling (ok)
  • [DATATABLE] DataTables example of styling Excel export(ok)
  • === END DATATABLE ===
  • 😅Bất ngờ về sử dụng Window History full 1 (ok)
  • 😁Bất ngờ về sử dụng Window History full 2, window.history.scrollRestoration,history.replaceState(ok)
  • workingHoursBetweenTimes, tính giờ làm việc, giờ làm thêm (ok)
  • 😅addDataToArray, cộng mảng đối tượng với điều kiện key == (ok)
  • You can get the number of days in a specified month (ok)
  • Lấy giá trị khác nhau đầu tiên, cuối trong một mảng Object (ok)
  • swiperjs.com (ok)
    • Swiper Slider (ok)
  • Một số cách viết ngắn gọn code trong JS phần 1 (ok)
  • Một số cách viết ngắn gọn code trong JS phần 2 (ok)
  • literal javascript, php (ok)
  • Bài toán kinh điển sử dụng three dots lấy tất cả các key của object, key same, plus (ok)
  • convert object to array javascript (ok)
  • ==== Start Google Sheet ====
  • Kintone width Appscript (ok)
  • [GOOGLE-SHEETS] Buttons in Google Sheets
  • [GOOGLE-SHEETS] thực hiện chuyển dữ liệu sang bản khác (ok)
  • [GOOGLE-SHEETS] method getRange (ok)
  • [GOOGLE-SHEETS] method getRange (ok)
  • Bài 1: Khai Báo Biến và Đọc Ghi Ô – Dải Ô (Cell / Range)
  • Bài 2: Các Hàm Lấy Giá Trị và Đặt Giá Trị Dải Ô getRange – getValues – setValues
  • Bài 3: Copy và Di Chuyển Dải Ô Sang Sheet khác
  • Bài 4: Vòng Lặp For
  • Bài 5: Di chuyển dòng từ Sheet này sang Sheet khác
  • [Help] – Chuyển Cột Sang Hàng (bỏ ô trống) (ok)
  • Bài 6: Câu lệnh điều kiện IF (ok)
  • Bài 7: Giới thiệu các Trigger App Script – onEdit onOpen
  • [Help] – Form nhập liệu đơn giản
  • Bài 8: Hộp thoại Dialog / Popup
  • Bài 9: Ghi công thức Google Sheet vào ô
  • Bài 10: Đọc Ghi Mảng (Array) App Script
  • Bài 11: Tạo xác thực dữ liệu phụ thuộc
  • Lấy Email người dùng đang hoạt động trên Google Sheet – getActiveUser
  • Bài 12: Liên kết Google Form – Sheet – Apps Script
  • [Series Email] Bài 1: Gửi Email bằng Apps Script cơ bản
  • [Series Email] Bài 2: Gửi Email Đính Kèm File – Hình Ảnh
  • [Series Email] Bài 3: Gửi Email Cho Danh Sách Nhập Vào Từ Google Sheet
  • Addon Email All in One | Email AI1 | RA MẮT BẢN THỬ NGHIỆM
  • [Series Email] Bài 4: Gửi Email Bcc Cho Danh Sách Nhập Vào Từ Google Sheet
  • [Series Email] Bài 5: Tạo Hộp Thoại Xem Email Trước Khi Gửi
  • [Series Email] Bài 6: Gửi Email Theo Template Cho Sẵn
  • [Series Email] Bài 7: Gửi Email Xác Nhận Điền Form (Email Confirmation)
  • [Series Email] Bài 8: Hẹn Giờ Gửi Email
  • SpreadsheetApp
  • Giới hạn các Service trong Apps Script
  • [CF] Lọc dải ô bao gồm dải ô khác
  • Cách lưu trữ trong Google Apps Script – PropertiesService
  • [CF] Custom Function Google Sheets là gì và Cách ‘cài đặt’
  • [CF] Tìm Ô – Có Giá Trị – Cuối Cùng Trong Cột – Google Sheets
  • [CF] Đếm số lần xuất hiện kí tự trong dải ô Google Sheets
  • [CF] Lọc dải ô không bao gồm
  • ==== End Google Sheet ====
  • [REDUCE] JavaScript Array reduce()
  • Merge object and split array by size, Trộn object và tách array theo size (ok)
  • Đặt điều kiện mới load js (ok)
  • Calculate working days between two dates in Javascript excepts holidays (ok)
  • Remove everything after a certain character remove replace (ok)
  • CodePen Home Image zoom on hover - auto run - view full (ok)
  • ======== Start Slider Revolution =======
  • How to start (ok)
  • Revolution Lightbox tham khảo
  • Mẫu và thực viện để thực hành (ok)
  • Tài liệu Slider Revolution Jquery 2.0 (ok)
  • Tài liệu Slider Revolution Jquery 4.1.2 (ok)
  • ======== End Slider Revolution =======
  • jQuery click / toggle between two functions (ok)
  • [TEXT ANIMATION] làm hiệu ứng chữ dòng trên xuất hiện trước rồi mới đến dòng dưới (ok)
  • Phát hiện phần tử xuất hiện ở màn hình, Detect element appearing on screen, view (ok)
  • what does !function in Javascript mean? (ok)
  • [WEBPACK] Một cách phân biệt khi bundle ra es5 hay es6 một ví dụ sử dụng webpack (ok)
  • Javascript Self Invoking Functions (ok)
  • ====== Start Convert ES5 class to ES6 class ====
  • VS Code tips: Convert ES5 class to ES6 class code action (ok)
  • ====== End Convert ES5 class to ES6 class ====
  • Get Substring between two characters using javascript (ok)
  • add Html Table rows data into JSON array Object (ok)
  • lightGallery, lightgalleryjs, Lightbox (ok)
  • same height (ok)
  • Hình ảnh :(
  • ============ Start serialize =============
  • jQuery serialize() Method (ok)
  • serialize width php mysql (ok)
  • serialize, serializeObject, serializeArray (ok)
  • How to access jQuery serialized data? (ok)
  • ============ End serialize =============
  • Sử dụng addQueryVar để thêm vào đường dẫn ajax (ok)
  • Cách tích hợp captcha style2.track360.xyz (ok)
  • Simple JavaScript Captcha Example (Client Side Captcha)
  • 😍Đoạn mã sử dụng translate.google.com (ok)
  • ========== Start [MultiLang] ===========
  • [MultiLang] MultiLang.js (ok)
  • [MultiLang] Localizing JavaScript apps with jQuery.i18n (ok) (full)
  • [MultiLang] jQuery i18n những điều nên biết (ok)
  • [MultiLang] How to Create a Multilingual Application using JavaScript
  • [MultiLang] Build multiple language website using jQuery and JSON based methods (ok)
  • [MultiLang] Switch Different Languages On The Webpage - jQuery multilang (ok)
  • [MultiLang] jquery-multilang (ok)
  • ========== End [MultiLang] ===========
  • [MINICOLORS] jquery.minicolors (ok)
  • jQuery - addClass ACTIVE--> set timeout --> cycle (ok)(online.vinmec.com)
  • WP Mapbox GL JS Settings key (ok)
  • Xử lý ảnh thiếu thuộc tính title, alt trên style2.track360.xyz (ok)
  • Register your schema (ok)
  • ========= Start Learn Graphql Website =======
  • 1. Query and Mutation types
  • ========= End Learn Graphql Website =======
  • [GRAPHQL] Tạo Database với Mysql (ok)
  • KẾT NỐI VỚI MYSQL – NODEJS – 05
  • 😍Quick start graphql (ok)
  • Hướng dẫn bắt đầu GraphQL với Node.js (Phần 1)
  • Hướng dẫn bắt đầu GraphQL với Node.js (Phần 2)
  • Cách bắt đầu với ứng dụng GraphQL, React, Apollo Client và Apollo Server
  • [Fullstack] Xây dựng forum bằng GraphQL, React, Apollo và Prisma - Part 1 (Application Introduction
  • 😍[Fullstack] Xây dựng forum bằng GraphQL, React, Apollo và Prisma - Part 2 (Backend - Project Setup a
  • [Fullstack] Xây dựng forum bằng GraphQL, React, Apollo và Prisma - Part 3 (Backend - Simple Mutation
  • [Fullstack] Xây dựng forum bằng GraphQL, React, Apollo và Prisma - Part 4 (Backend - Connect to Data
  • 😍Prisma Crud Full
    • 🥰Sử dụng kết hợp prisma.io với wordpress như nào?
    • [ERROR] gặp lỗi TypeError: Do not know how to serialize a BigInt (ok)
    • 😍Migrate MongoDB to MySQL using Prism Key Differences (ok)
  • Setting Up Prisma with MySQL: A Step-by-Step Guid
  • Tìm hiểu GraphQL, Xây dựng 1 GraphQL server với prisma
  • 🥹Đã có bài viết về sqlite, sqlite3 đầy đủ (ok)
  • 😍Querying Sequelize Full link sequelize.org (ok)
  • 😁Sqlite Sequelize Example (ok)
  • 😍CRUD with React and GraphQL Mysql (ok)
  • 😍A GraphQL Sqlite, sequelize Full (ok)
  • GraphQL in practice - Part 1: Xây dựng GraphQL server với Apollo Server, ExpressJS và MongoDB
  • GraphQL in practice - Part 2: Tạo ứng dụng GraphQL với Apollo Client và React
  • GraphQL in practice - Part 2: Tạo ứng dụng GraphQL với Apollo Client và React
  • TÌm hiểu về GraphQL
  • Cùng tìm hiểu về GraphQL
  • Simple Guidance For You In GraphQL
  • [GRAPHQL] Get started with Apollo Server (ok)
  • [GRAPHQL] Schema basics (ok)
  • [GRAPHQL] Subscriptions (ok)
  • [GRAPHQL] Unions and interfaces (ok)
  • Tham khảo: https://www.howtographql.com
  • Tìm hiểu GraphQL: Các khái niệm cơ bản (ok)
  • GraphQL Và Ưu Điểm Nổi Bật So Với Rest API?
  • Xây dựng server GraphQL với NodeJS (ok)
  • Tìm hiểu GraphQL
  • Xây dựng GraphQL server với Node.js
  • Ví dụ Tạo Restfull API - CRUD đơn giản với NodeJS, GraphQL (ok)
  • Sequelize with Node, Express & Mysql and it’s setup (ok)
  • Sequelize in Nodejs Part I
  • Sequelize in Nodejs Part II
  • Videos NodeJS + MySQL Database
  • NodeJS – Lưu trữ dữ liệu trên MySQL với Sequelize
  • Exploring The Node.js With MySQL Example Using Sequelize & Express
  • Tạo model, migration, seeds với Sequelize
  • Sử dụng passport với sequelize và MySQL
  • Tạo model, migration, seeds với Sequelize
  • GraphQL là gì? Bắt đầu với GraphQL
  • Xây dựng API sử dụng Laravel và GraphQL
  • How To Connect To MySql Database Using Sequlize In Express (Node) Application
  • Node.js MySQL Tutorial
  • Node.js Rest APIs example with Express, Sequelize & MySQL
  • Getting Started with Node, Express and Mysql Using Sequelize
  • [GRAPHQL] GraphQL – Công nghệ mới cho web developer
  • GraphQL là gì? Tìm hiểu về GraphQL (ok)
  • [GRAPHQL] Cùng tìm hiểu về GraphQL
  • Điều gì ẩn chứa bên trong $.event???
  • ===== Start Put JavaScript Design Patterns Into Practice (Videos) ========
  • 2.1. The Factory Pattern (ok)
  • 3.1. The Publisher-Subscriber Pattern (ok)
  • 3.2. The Strategy Pattern (ok)
  • Rời phần thử khỏi mảng sử dụng filter (ok)
  • 3.3. The Observer Pattern (ok)
  • 3.4. The Chain of Responsibility Pattern (ok)
  • 3.5. The Mediator Pattern (ok)
  • 3.6. The Iterator Pattern (ok)
  • ===== End Put JavaScript Design Patterns Into Practice (Videos) ========
  • ========== Start RequireJS Tutorial =======
    • Sử dụng RequireJS và AMD để module hóa code JavaScript (ok)
  • 😍Trình duyệt không có require, nhưng Node.js thì có. Với Browserify để trình duyệt cũng có (ok)
  • Sử dụng Bower để quản lý các thư viện code trong Laravel (ok)
  • RequireJS - Environment Setup (ok)
  • RequireJS - Configuration (ok)
  • RequireJS - AMD Modules (ok)
  • RequireJS - Defining Function (cách sử dụng require rất lạ) (ok)
  • RequireJS - Optimizer (ok)
  • ========== End RequireJS Tutorial =======
  • ========== Start jQuery Ui ======
  • Jquery Datepicker select multiple date ranges in one calender, button Reset (ok)
  • Tạo chức năng tự động hoàn tất nhập liệu với thư viện jQuery UI Autocomplete (Phần 1) (ok)
  • Draggable Widget, Droppable Widget (ok)
  • jQuery drag and drop (kéo thả bằng jQuery)
  • jQuery drag full (ok)
  • jQuery drop full (ok)
  • jQuery Resizable full (ok)
  • Tablesorter full (ok)
  • Live search through table rows (ok)
  • Loại bỏ một số cột không tìm kiếm trong Tablesorter (ok)
  • jQuery Sortable full, tablesorter (ok)
  • jQuery Selectable full (ok)
  • jQuery UI Sortable Tutorial - Save Positions With Ajax & PHP & MySQL (ok)
  • jQuery Drag and Drop TODO List with PHP MySQL (ok)
  • ========== End jQuery Ui ======
  • [TUTORIAL] TRÍCH XUẤT THÔNG TIN TỪ WEBSITE VỚI HTML AGLITITY PACK
  • ======== Start handlebars js =======
  • Sử dụng handlebars js
  • Handlebars nhỏ nhưng có võ
  • ======== End handlebars js =======
  • ==== Start JavaScript Tutorial ====
  • JavaScript Introduction
  • What is JavaScript
  • JavaScript Essentials
  • JavaScript Variables
  • JavaScript Operators
  • JavaScript Conditionals
  • JavaScript Loops
  • JavaScript Built-in Types
  • JavaScript Objects
  • JS Advanced Objects
  • JavaScript Arrays
  • JavaScript Functions
  • JavaScript Function Objects
  • JavaScript JSON
  • JavaScript Regular Expressions
  • Bôi màu cho một ký tự đặc biệt và chuỗi @EsportsArcadia Regular Expression (ok)
  • JavaScript Reference
  • ==== End JavaScript Tutorial ====
  • 🧐===== Start JavaScript Design Patterns ==
  • JavaScript Design Patterns
  • JavaScript Design Patterns – Explained with Examples
  • Js design pattern doFactory master (ok)
  • Chapter 5: jQuery Patterns
  • JavaScript Design Patterns (ok)
  • Abstract Factory (ok)
  • Builder (ok)
  • Factory Method (ok)
  • Prototype (ok)
  • Singleton (ok)
  • Adapter ( ok)
  • Bridge (ok)
  • Composite (ok)
  • Decorator (ok)
  • Facade (ok)
  • Flyweight (ok)
  • Proxy (ok)
  • Chain of Responsibility (ok)
  • Command (ok)
  • Interpreter (ok)
  • Iterator (ok)
  • Mediator (ok)
  • Memento (ok)
  • Observer (ok)
  • State (ok)
  • Strategy (ok)
  • Template Method (ok)
  • Visitor (ok)
  • ===== End JavaScript Design Patterns ==
  • ======== Start Backbone.js Tutorial Videos ======
  • Backbone.js Tutorial - 1 - Installation.mp4 (ok)
  • Backbone.js Tutorial - 2 - Introduction to Models (ok)
  • Backbone.js Tutorial - 3 - Model Attributes (ok)
  • Backbone.js Tutorial - 4 - Model Change Events ( ok)
  • Backbone.js Tutorial - 6 - Introduction to Views (ok)
  • Backbone.js Tutorial - 7 - (Views) Differerence between el and $el (ok)
  • Backbone.js Tutorial - 8 - (Views) Creating New HTML Elements (ok)
  • Backbone.js Tutorial - 9 - (Views) Using the Render Function (ok)
  • Backbone.js Tutorial - 10 - (Views) Events (ok)
  • Backbone.js Tutorial - 11 - Introduction to Collections (ok)
  • Backbone.js Tutorial - 12 - (Collections) Adding and Removing Elements (ok)
  • Backbone.js Tutorial - 13 - (Collections) Modifying Elements
  • Backbone.js Tutorial - 14 - (Collections) Events (ok)
  • ======== End Backbone.js Tutorial Videos ======
  • ====== Start Learn backbone.js tutorial from scratch for beginners =====
  • Backbone :)
  • 1. Learn backbone.js tutorial from scratch(Part 2) Features and Working Principle of backbone.js
  • 2. Learn backbone.js tutorial from scratch for beginners(Part 4) About el and $el in Backbone.js
  • 3. Learn backbone.js tutorial from scratch for beginners(Part 5) Underscore Templates in Backbone.js
  • 4. Learn backbone.js tutorial from scratch for beginners (Part 7) Delegate Events in backbone.js
  • 5. Learn backbone.js tutorial from scratch for beginners(Part 8) Introduction of models in backbone.
  • 6. Learn backbone.js tutorial from scratch for beginners(Part 9) Pass Model data to backbone.js View
  • 7. Learn backbone.js tutorial from scratch for beginners(Part 10) Model data to underscore.js templ
  • 8. Learn backbone.js tutorial from scratch for beginners(Part 11) Head back to underscore.js symbol
  • 9. Learn backbone.js tutorial from scratch for beginners(Part 12) Model Events in backbone.js
  • 10. Learn backbone.js tutorial from scratch for beginners(Part 13) Model Validation in backbone.js
  • 11. Learn backbone.js tutorial from scratch for beginners(Part 14) Model Change Events in backbone.j
  • 12. Learn backbone.js tutorial from scratch for beginners(Part 15) More Model Events and listenTo ev
  • 13. Learn backbone.js tutorial from scratch for beginners(Part 16) Model Inheritance in backbone.js
  • 14. Learn backbone.js tutorial from scratch for beginners(Part 17) Collection in backbone js
  • 15. Learn backbone.js tutorial from scratch for beginners(Part 18) Collection Events in backbone.js
  • 16. Learn backbone.js tutorial from scratch for beginners(Part 19) Collection to underscore.js templ
  • 17. Learn backbone.js tutorial from scratch for beginners(Part 20) Underscore js Methods in backbone
  • 18. Learn backbone.js tutorial from scratch for beginners(Part 21) Routing in backbone.js
  • 19. Learn backbone.js tutorial from scratch for beginners(Part 22) Parameterized Routing in backbone
  • 20. Learn backbone.js tutorial from scratch for beginners(Part 23) Handlebars templates in backb
  • ====== End Learn backbone.js tutorial from scratch for beginners =====
  • Giới thiệu Backbone.js (ok)
  • Backbone.localStorage thay thế Backbone.sync lưu vào window.localStorage thay vì vào máy chủ (ok)
  • Một ví dụ full LocalStorage với BackBoneJS (ok)
  • ========== Start Backbonejs Php Mysql =============
  • Full code backbonejs php mysql (ok)
  • Giao diện html để thực hành từ đầu (ok)
  • Xây dựng giao diện (ok)
  • Thực hiện chức năng crud add (ok)
  • Phân tích để tạo giao diên http://localhost/gulp/#crud/new 1.0
  • Phân tích để tạo giao diên http://localhost/gulp/#crud/new 1.1
  • Phân tích để tạo giao diên http://localhost/create/#crud/index 2.0
  • Chức năng thêm dữ liệu http://localhost/create/#crud/new (ok)
  • Lấy dữ liệu ra trang http://localhost/create/#crud/index (ok)
  • Chức năng cập nhật dữ liệu http://localhost/create/#crud/1/edit (ok)
  • ========== End Backbonejs Php Mysql =============
  • JQuery-Template (ok)
  • Learning JavaScript Design Patterns P.1 (ok)
  • Learning JavaScript Design Patterns P.2 (ok)
  • Learning JavaScript Design Patterns P.3 (ok)
  • Singleton design pattern PHP (ok)
  • Singleton Pattern javascript (ok)
  • Factory Pattern (ok)
  • Decorator Pattern (ok)
  • Creational Pattern (ok)
  • Constructor Pattern (ok)
  • Singleton Pattern (ok)
  • Module Pattern (ok)
  • Factory pattern (ok)
  • Built-in Object Factory (ok)
  • Iterator (ok)
  • Bridge Pattern (ok)
  • Composite Pattern (ok)
  • Một số Design Patterns có thể sử dụng trong Javascript – Phần 1 (ok)
  • Chém gió về JavaScript Design Pattern - Part 1(ok)
  • Chém Gió Về JavaScript Design Pattern Phần 2
  • Chém gió về JavaScript Design Pattern - Part 3
  • 4 Design Patterns trong Javascript mà bạn nên biết
  • Design Pattern trong JavaScript (ok)
  • Lebab chuyển mã ES5 của bạn thành ES6 / ES7. Nó hoàn toàn ngược lại với những gì Babel làm (ok)
  • Turn your ES5 code into readable ES6 (ok)
  • Thuộc tính :selected quá tuyệt cho sự lựa chọn (ok)
  • jQuery I want to add an active class to the linked ID of an anchor tag style2.track360.xyz (ok)
  • Keep URL unaffected when anchor link is clicked (ok)
  • [UI SLIDER] Ui slider with text box input (ok)
  • [SELECT2] version Select2 3.5.3 nhìn trực quan hơn (ok)
  • [SELECT2] keypress select2, enter key press keycode yp.vn (ok)
  • [SELECT2] Select2 Bootstrap Theme (ok)
  • [SELECT2] tags (ok)
  • [SELECT2] tokenSeparators (ok)
  • [SELECT2] click change value (ok)
  • [SELECT2] jQuery $.ajax options (ok)
  • [SELECT2] Full Options (ok)
  • [SELECT2] value placeholder (ok)
  • [SELECT2] Can thiệp vào templateResult (ok)
  • [SELECT2] làm lá cờ gắn trước text kiểu kool ngầu (ok)
  • [SELECT2] cam thiệp vào templateSelection (ok)
  • [SELECT2] thêm thẻ bọc vào lựa chọn ví dụ thẻ <strong/> (ok)
  • [SELECT2] opening when a result is selected (ok)
  • [SELECT2] Full Adapters hay (ok)
  • [SELECT2] Kiểu dữ liệu trả về cho giao diện dùng html & json (ok)
  • [SELECT2] sử dụng ngôn ngữ, i18n, language (ok)
  • [SELECT2] dropdownParent (ok)
  • [SELECT2] Hiểu submit trong javascript và nâng cấp sử dụng select 2, autocomplate (ok)
  • [SELECT2] Common problems Select2 does not function properly when I use it inside a Bootstrap modal
  • [SELECT2] Full Events (ok)
  • [SELECT2] lấy dữ liệu của wp, wordpress để thực hành (ok)
  • [JSONPLACEHOLDER SELECT2] Full Sử dụng website jsonplaceholder.typicode.com để thực hành (ok)
  • Sử dụng fetch trên console.log để get api test (ok)
  • jQuery.naturalWidth / jQuery.naturalHeight images natural Width Height Native Width (ok)
  • [SUBMIT ] form submit jquery (ok)
  • Tạo file package.json bằng lệnh (ok)
  • [TYPESCRIPT] tạo file tsconfig.json bằng lệnh (ok)
  • [TYPESCRIPT] cài đặt package chạy trực tiếp ts, tsx, ts-node (ok)
  • Object for Three Dots, Array for Three Dots (ok)
  • Cách giải thích Private Constructors & Singletons quá tuyệt (ok)
  • [TYPESCRIPT] Một số scripts hay được sử dụng trong typescripts (ok)
  • [TYPESCRIPT] A practical guide to TypeScript decorators exmaple (ok)
  • Object.getOwnPropertyDescriptor() (ok)
  • JavaScript — Property Descriptor && PropertyDescriptor (ok)
  • [TYPESCRIPT] Employing “Namespaces” in TypeScript to encapsulate your data
  • 😅[TYPESCRIPT] Một ví dụ sử dụng TypeScript Namespaces, xuất file use on browser (ok)
  • [NODEJS] object hóa một file trong javascript Nodejs - require, exports and module.exports
  • [TYPECRIPT] Omit type when extending an interface Cách loại trừ các thuộc tính khỏi giao diện (ok)
  • How TO - List Grid View (ok)
  • Javascript module, import, export, dễ ẹc, nhưng có thể bạn vẫn chưa biết
  • [BABEL] Giải thích gói babel (ok)
  • Cấu hình Webpack và Babel 7 cho React (ok)
  • ----------------- Start Kế thừa Prototype ngang và dọc -------------------
  • Kế thừa Prototype ngang và dọc
  • class, super, constructor (ok)
  • Kế thừa ngang giữa function (ok)
  • Ví dụ về kế thừa prototype ngang theo function constructor. Liên quan đến hàm call(), sẽ có bài chi
  • Kế thừa ngang giữa 2 object
  • Muốn tạo một class, object có tên k hác khi console.log?? (ok)
  • Ví dụ về Function constructor và object instance (ok)
  • Tất cả đều từ Function
  • ----------------- End Kế thừa Prototype ngang và dọc -----------
  • Easy Responsive Tabs to Accordion (ok)Demos
  • [ERROR] unable to read package/javascript (ok)
  • ------------Start Json-----------------
  • Cách để truyền dữ liệu dạng boolean trong Postman (ok)
  • ------------ End Json-----------------
  • ---------- start JSONP ---------------------
  • Cross-Domain Ajax Requests
  • 1. JSONP (JSON with padding)
  • 2. CORSCross-origin resource sharing (CORS) là một cơ chế đặc biệt cho phép resource đặt tại một do
  • 3. Proxy
  • JSONP là gì và tại sao nó được tạo ra? (ok)
  • 4. Javascript – Tạo script động và kĩ thuật JSONP (ok)
  • ----------- End JSONP --------------
  • Destructuring Assignment in ES6
  • Cơ chế bất đồng bộ trong javascript (ok)
  • jQuery.inArray()
  • website check call stack (ok)
  • Bài 6: Template Literals trong ES6 (ok)
  • ES6 Arrow Functions (ok)
  • Lập trình TypeScript (ok)
  • Uncaught ReferenceError: exports is not defined in filed generated by Typescript (ok)
  • Cách hoạt động của các module loader? (ok) một ví dụ kinh điển :)
  • RequireJS Cho Người Mới Bắt Đầu (ok) quá tuyệt
  • Tiny loaders tương tự REQUIREJS (Ok)
  • Javascript Module Loader – From the basic (ok)
  • ES6 Modules and CommonJS (Oke) Một ví dụ quý hơn vàng :(((
  • CommonJS là một module pattern hỗ trợ cho tất cả các phiên bản Node.js. Với CommonJS, JavaScript obj
  • ------------------------Start webpack ----------------------
  • [WEBPACK] Làm một ví dụ compile scss, sass bằng WEBPACK full (ok)
  • Webpack từ A đến Á: Webpack watch mode (ok)
  • Webpack từ A đến Á: Webpack dev server (ok)
  • Webpack từ A đến Á: Webpack output hash digest (ok)
  • Webpack từ A đến Á: Webpack multiple entry points (ok)
  • Webpack từ A đến Á: Webpack multiple file types per entry (ok)
  • Webpack từ A đến Á: Webpack import export module (ok)
  • Webpack từ A đến Á: Webpack source map (ok)
  • Webpack từ A đến Á: Webpack import jQuery (ok)
  • Webpack từ A đến Á: Webpack import jQuery - Bootstrap (ok)
  • Webpack từ A đến Á: Webpack import jQuery - Materialize
  • Webpack từ A đến Á: Code Splitting (ok)
  • Webpack từ A đến Á: Code Splitting (ok)
  • Webpack từ A đến Á: Webpack resolve alias - extensions
  • Config alias chuẩn trong webpack (ok)
  • Webpack từ A đến Á: Webpack Babel Loader (ok)
  • Webpack từ A đến Á: Webpack Eslint Loader (ok)
  • Webpack từ A đến Á: Webpack Url Loader (ok)
  • Webpack từ A đến Á: Webpack File Loader (ok)
  • Webpack từ A đến Á: Webpack Style Loader (ok)
  • Webpack từ A đến Á: Webpack Sass Loader (ok)
  • Webpack từ A đến Á: Html Webpack Plugin (ok)
  • Option chunks Html Webpack Plugin (ok)
  • Webpack từ A đến Á: Clean Webpack Plugin (ok)
  • What is the difference between @babel/core and babel-core? (ok)
  • [WEBPACK] 2. Webpack : Khởi Tạo Project (nghiepuit)
  • [WEBPACK] 3. Webpack : Apply Babel Cho Project (nghiepuit)
  • [WEBPACK] 4. Webpack : CSS Loader (nghiepuit)
  • plugin @babel/plugin-proposal-class-properties
  • [WEBPACK] 5. Webpack : Tạo Project ReactJS (
  • [WEBPACK] 7. Webpack : File Loader - Tích Hợp Bootstrap
  • [WEBPACK] 8. Webpack : Tích Hợp Jquery, React, Redux Devtools (nghiepuit)
  • [WEBPACK] 9. Webpack : Vendor Caching
  • [WEBPACK] 10. Webpack : CommonsChunkPlugin
  • [WEBPACK] 10. Webpack : CommonsChunkPlugin (ok)
  • [WEBPACK] Webpack series (ep3) - code splitting - chia code trong webpack (ok)
  • Compile SASS with Webpack into a CSS file (ok)
  • [WEBPACK] 11. Webpack : Optimize Khi Bundle template (ok)
  • [WEBPACK] 12. Webpack : Clean Project (ok)
  • [WEBPACK] 12+. Webpack : webpack-dev-server
  • [WEBPACK] Plugin HtmlWebpackPlugin (ok)
  • HashRouter vs BrowserRouter
  • [WEBPACK] Webpack giúp kết nối các module lại với nhau ( (ok)
  • [WEBPACK] Chú ý: @babel/preset-env dùng cho những gói cũ thay vì khai báo mới babel-preset-env (ok)
  • [WEBPACK]
  • [WEBPACK] webpack-dev-server (ok)
  • [WEBPACK] liên kết với trang Webpack (ok)
  • [WEBPACK] Webpack output hash digest (ok)
  • [WEBPACK] Webpack multiple file types per entry
  • [WEBPACK] Webpack import export module (ok)
  • [WEBPACK] Webpack source map (ok)
  • Simple use jQuery with TypeScript (ok)
  • [WEBPACK] Webpack import jQuery (ok)
  • [WEBPACK] Webpack import jQuery - Bootstrap (ok)
  • [WEBPACK] Webpack import jQuery - Materialize
  • [WEBPACK] Webpack từ A đến Á: Code Splitting
  • [WEBPACK] Webpack từ A đến Á: Webpack resolve alias - extensions
  • [WEBPACK] Config alias chuẩn trong webpack
  • [WEBPACK] Webpack từ A đến Á: Webpack Babel Loader
  • [WEBPACK] Webpack từ A đến Á: Webpack Eslint Loader
  • [WEBPACK] Webpack từ A đến Á: Webpack Url Loader (ok)
  • [WEBPACK] Webpack từ A đến Á: Webpack File Loader
  • [WEBPACK] Webpack từ A đến Á: Webpack Style Loader (ok)
  • [WEBPACK] Webpack từ A đến Á: Webpack Css Loader
  • [WEBPACK] Webpack từ A đến Á: Webpack Sass Loader
  • [WEBPACK] [SPITEST] Teach you how to use webpack to generate css sprites
  • Page learn webpack good
  • Remove unused CSS styles from Bootstrap using PurgeCSS (ok)
  • [WEBPACK] Webpack cho người mới bắt đầu (ok)
  • [WEBPACK] cấu hình output (ok)
  • [WEBPACK] Dùng webpack để sử dụng từ khóa import, export (ok)
  • [WEBPACK] Từ cơ bản đến nâng cao
  • [WEBPACK] Tăng Tốc Độ và Tối Ưu Hoá Website Bằng CSS Sprites (ok)
  • ------------------------ End webpack ----------------------
  • How to convert unordered list into nicely styled <select> dropdown using jquery? (ok)
  • 😆Lazy loading images using event handlers 1
  • 😄Layload ajax && background 2
  • jQuery Lazy 3
  • jQuery lazyload 4
  • Config lazySizesConfig lazysizes.min.js lazysizes(ok)
  • Lazy loading images using event handlers (ok)
  • GIỚI THIỆU THƯ VIỆN LAZYSIZES.JS ĐỂ LAZY LOAD ẢNH (PHẦN 1)
  • GIỚI THIỆU THƯ VIỆN LAZYSIZES.JS ĐỂ LAZY LOAD ẢNH (PHẦN 2)
  • GIỚI THIỆU THƯ VIỆN LAZYSIZES.JS ĐỂ LAZY LOAD ẢNH (PHẦN 3)
  • Native lazy-loading for the web (ok)
  • Tầm quan trọng của thuộc tính sizes, srcset trong thẻ img (ok)
  • Thực hành lazysizes.min.js
  • Check image img exits vieclam123.vn (ok)
  • Nestable - Drag & drop hierarchical list with mouse and touch compatibility (ok)
  • Cấu hình tawk chat web500.vn ( ok)
  • Cùng tìm hiểu plugin Jquery Validation
  • Tìm hiểu về Jquery Validation (Phần 1) (ok)
  • Tìm hiểu về Jquery Validation (Phần 2) (ok)
  • Tìm hiểu về hộp thoại Sweet alert 2
  • Multi-table,Multi table (ok)
  • SweetAlert2 getHtmlContainer (ok)
  • AJAX request preConfirm (ok)
  • sử dụng php kết hợp Sweetalert2 (ok)
  • Một ví dụ tuyệt vời Ajax SweetAlert for Live Data Deleting Rows in with PHP~MySQL~Ajax (ok)
  • SweetAlert makes popup messages easy and pretty (page learn) (kiể cũ)
  • sweetalert bản chuẩn (ok)
  • AJAX requests (ok)
  • sweetalert2 bản chuẩn (ok) cái này dùng hay hơn sweetalert (ok)
  • Toast (ok)
  • Email (ok)
  • jQuery trigger() Method
  • jQuery one() Method (ok)
Powered by GitBook

Navigation

  • Lionel

@Copyright 2023

On this page
  • Hai cách load module ngoài trình duyệt dễ nhất :)
  • Hoặc
  • ECMAScript modules and browser compatibility
  • ECMAScript modules
  • ECMAScript modules in the browsers
  • ECMAScript modules as a baseline
  • Dynamic imports
  • Intermediate browsers
  • Detecting support for dynamic imports
  • Vite’s legacy plugin
  • Module preload
  • Pragmatic compatibility with old browsers
  • How frameworks employ ECMAScript modules
  • Cutting the mustard with ECMAScript modules
  • Using new ECMAScript syntax safely: The optional chaining operator
  • The future

Đọc thêm bài này Mô-đun ECMAScript và khả năng tương thích trình duyệt (ok)

https://molily.de/ecmascript-modules/

Hai cách load module ngoài trình duyệt dễ nhất :)

C:\Users\Administrator\Desktop\amd-dependencies\test.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script type="module">
    // Wrap code in a function to prevent a top-level await.
    (async () => {
      // The next line raises a SyntaxError in intermediate browsers.
      const { helloWorld } = await import('./helloWorld.js');
      // The next line in only executed if the browser supports
      // dynamic imports. It is never executed in intermediate browsers.
      helloWorld();
    })();
  </script>
</head>
<body>
</body>
</html>

Hoặc

C:\Users\Administrator\Desktop\amd-dependencies\test.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script type="module" src="index.js"></script>
</head>
<body>
</body>
</html>

C:\Users\Administrator\Desktop\amd-dependencies\index.js

import { helloWorld } from './helloWorld.js';
helloWorld();

C:\Users\Administrator\Desktop\amd-dependencies\helloWorld.js

export const helloWorld = () => {
  console.log('Hello world 123!');
};

ECMAScript modules and browser compatibility

How do we ship modern JavaScript in a compatible way?

April 21, 2023

One of the biggest changes in JavaScript in the last decade was the switch from loosely-connected scripts to ECMAScript modules (ESM). This affected both client-side and server-side JavaScript code.

JavaScript programmers today take it for granted that they can pull a library dependency into client-side or server-side JavaScript code with npm install or other package managers that build on the npm registry. A decade ago, this crucial infrastructure was still in its infancy.

ECMAScript modules

In 2015, ECMAScript 6 standardized a declarative syntax for JavaScript files to import and export values.

index.js:

import { helloWorld } from './helloWorld.js';

helloWorld();

helloWorld.js:

export const helloWorld = () => {
  console.log('Hello world!');
};

Node.js experimentally supported ECMAScript modules in version 8.5.0 (September 2017). Since version 14 (April 2020), the implementation is no longer experimental. Since version 15.3.0 (November 2020), it is considered stable.

ECMAScript modules in the browsers

However, browsers did not support ECMAScript modules natively yet. They did not understand the import/export syntax yet. So the bundlers produced JavaScript files without ECMAScript module syntax.

Webpack used its own mechanism for splitting code into chunks and loading them dynamically. Rollup relies on the module loaders RequireJS or SystemJS to be present at runtime.

<script type="module">
  // This is ECMAScript module code and module rules apply.
  // This code is evaluated in Strict Mode.
  // import and export may be used here.
  import { helloWorld } from './helloWorld.js';
  helloWorld();
</script>
<!--
The execution of the external module script is deferred.
That is, it is executed when the document is ready.
-->
<script type="module" src="externalModuleScript.js"></script>
<script nomodule src="scriptForOldBrowsers.js"></script>

This allows web developers to ship two different versions of their code:

  • One modern build with native ECMAScript modules for new browsers.

  • One legacy build, backwards-compatible with old browsers that lack support for ECMAScript modules.

Today, 95.69 % of all browsers worldwide fully support <script type="module">, according to Can I Use. The remaining 4.31 % have no support. Bear in mind that these values are global means. In your user base, in your audiences, the values may be lower or higher.

ECMAScript modules as a baseline

The switch to ECMAScript modules for client-side code seems small at first sight. We do not need a module loader like SystemJS any longer and the shipped production code is more closer to the written code. This is it, or not?

To support older browsers, transpiling ECMAScript 6+ code to ECMAScript 5 using Babel is a common practice. For our modern browser build, there is no need to. The targeted browsers fully support ECMAScript 6 and even some features of ECMAScript 7 (2016) and 8 (2017). We can skip the transpilation completely if we stick to supported syntax features. We can also skip certain feature detection and omit polyfills for supported APIs.

The resulting modern build is smaller and faster. It is a clear win to ship ECMAScript module code to browsers that support it. But it requires developers to compile and embed two builds: the ECMAScript modules build and the legacy build for browsers without ECMAScript module support. Since the code of the two builds may differ considerably, developers need to test and debug both.

Dynamic imports

There is one missing piece in the puzzle: We still want to split the bundle into smaller chunks and load them lazily when the page actually needs the JavaScript code. Static imports load code eagerly. Bundlers like Webpack and Rollup would emit one gigantic JavaScript file even when an individual page just needs a tiny fraction of JavaScript.

<button>Say hello!</button>
<script type="module">
document.querySelector('button').addEventListener(
  'click',
  async () => {
    // Load code dynamically when the user interacts
    const { helloWorld } = await import('./helloWorld.js');
    helloWorld();
  }
);
</script>

Dynamic imports are supported by all major browser engines since Chrome 63 (December 2017), Safari 11.1 (April 2018) and Firefox 67 (May 2019). Edge 79 (January 2020) was the last browser to support them, when Microsoft switched from EdgeHTML to Chromium and the Blink engine.

Compare this to the support for <script type="module">: Chrome 61 (September 2017) / Edge 79 (January 2020), Safari 11 (September 2017) and Firefox 60 (May 2018).

Intermediate browsers

There is a small range of browser versions that do support ECMAScript modules but not dynamic imports: Chrome 61 to 62, Firefox 60 to 66, Edge 16 to 78 and Safari 10.3 to 11.0.

Luckily, these browser versions are hardly relevant in 2023. Only few users are stuck on old versions of Chrome, new Edge and Firefox. These “evergreen” browsers are updated automatically to a new major version every month. Safari does not update that often, but the version range 11 (September 2017) to 11.1 (April 2018) is tiny.

How should we deal with these intermediate browsers? We have two options:

  1. Serve them the modern build, but do not use native dynamic imports. Use a module loader like SystemJS for importing code dynamically.

  2. Serve them the legacy build without ECMAScript module code and without dynamic imports. Use a module loader like SystemJS for dynamic imports.

Because of the small market share of intermediate browsers, most projects use native dynamic imports and put intermediate browsers into one bucket with old browsers.

Shifting the baseline to browsers that support dynamic imports gives us even more freedom for what is possible in the modern build.

Detecting support for dynamic imports

But how do we serve the legacy build to intermediate browser? The combination of <script type="module"> and <script nomodule> allows us to create a conditional loader: If the browser supports ECMAScript modules, load the modern build, otherwise load the legacy build.

Unfortunately, there is no simple conditional loader for scripts using dynamic imports. This feature cannot be detected easily. The reason is that import is a reserved word in ECMAScript. Reserved words cannot be used in expressions where an identifier is expected.

If an intermediate browser parses a script with import('…'), it fails with a syntax error. When the parsing fails, the browser cannot execute the code.

<script type="module">
// Wrap code in a function to prevent a top-level await.
(async () => {
  // The next line raises a SyntaxError in intermediate browsers.
  const { helloWorld } = await import('./helloWorld.js');
  // The next line in only executed if the browser supports
  // dynamic imports. It is never executed in intermediate browsers.
  helloWorld();
})();
</script>

Luckily, the syntax error that prevents execution already hints at a possible solution. To detect support for dynamic imports – we perform a dynamic import! If the browser executes the imported code and the code after the import() call, it is a new browser. If the browser does not execute the code, it is an intermediate browser.

We use dynamic imports to load the bundle that in turn uses dynamic imports. This guarantees us that only capable browsers execute the code. All other browsers are served the legacy bundle.

<script type="module">
// Try to load bundle for modern browsers.
import('./bundle-with-dynamic-imports.js');
// Set a global flag that the browser supports dynamic imports.
window.__browserSupportsDynamicImports = true;
</script>
<script type="module">
// This script is executed in browsers with ECMAScript module support.
// If we cannot find the flag, the browser must be intermediate!
if (!window.__browserSupportsDynamicImports) {
  // Load the legacy build.
  const script = document.createElement('script');
  script.src = './legacy-build.js';
  document.head.appendChild(script);
}
</script>
<!-- Legacy build for browsers without ECMAScript module support. -->
<script nomodule src="./legacy-build.js"></script>

Vite’s legacy plugin

  1. The modern build with an entry script and chunks for modern browsers that support ECMAScript module and dynamic imports.

  2. The legacy build with an entry script and chunks for legacy browsers. The code is transpiled with Babel.

The actual cross-browser Vite embed code is much more sophisticated: Vite detects support for import.meta.url, dynamic imports and async generators in one script. If these three features are supported, it sets the flag __vite_is_modern_browser. If this flag is not set, it first loads the legacy polyfill which contains SystemJS and, well, polyfills. Using SystemJS, it then loads the legacy entry. (This is the equivalent to legacy-build.js in the example above.)

Module preload

If you use dynamic imports frequently in your code base or have several entry points that share library code, bundlers like Rollup will create many small chunks. An individual page will load numerous small JavaScript files even if there is little JavaScript interactivity.

This is not necessarily a performance penalty since HTTP/2 multiplexing can request and receive many resources in parallel. Once these small chunks with reused library code are cached in the browser, subsequent pages have an excellent loading performance.

But often the dependency graph is a chain: a.js imports b.js, b.js imports c.js, for example. If there are other lazy-loaded modules pointing to b.js and c.js, the code does not end up in one chunk, but in three chunks.

When a page embeds a.js, a request waterfall happens. The browser downloads a.js, b.js and c.js subsequently, not in parallel. It downloads a.js, finds the import of b.js, downloads b.js, finds the import of c.js, downloads c.js. Finally, the browser is able to execute a.js after all dependencies have been loaded in sequence.

This improves the cold boot performance while using many small chunks with the minimal amount of JavaScript necessary for a certain page.

Pragmatic compatibility with old browsers

Vite is an example for a mature build tool that helps you ship ECMAScript modules. It supports old as well as intermediate browsers and optimizes the performance for modern browsers. This blog post cannot get into all details of Vite’s strategy.

For your project, you need to decide which browser capabilities are required and which browsers you can support easily.

For example, I am currently working on a JavaScript library for a client. The library does not actively support old browsers without ECMAScript module support, it does so passively. With little effort, old browsers get a basic functionality. We have a pragmatic approach:

  1. These polyfills and transformations typically affect the legacy bundle only since the baseline for the modern build is already quite high.

  2. There is ECMAScript syntax that cannot be transpiled and there are browser APIs that cannot be polyfilled with reasonable effort.

    • If we do not strictly need these capabilities, we do not use them. We check browser support before using a JavaScript feature to avoid raising the bar for no important reason.

How frameworks employ ECMAScript modules

When all major browser engines implemented support for <script type="module"> in 2018, JavaScript programmers and projects started to switch.

How is the situation today? What is the strategy of popular build tools and frameworks?

Here is a quick survey:

  • Vite: ECMAScript modules per default. Option to support older browsers with @vitejs/plugin-legacy (see above).

  • create-vue@3: Uses Vite and has the same defaults, supports @vitejs/plugin-legacy.

  • create-react-app: Does not use ECMAScript modules. Uses Babel and supports polyfills.

  • Astro: Does not use ECMAScript modules. But the astro-island custom element uses dynamic imports without feature detection or fallback. So the minimal required browser needs to support both customElements.define() and dynamic imports.

This overview merely describes, but does not judge the different approaches. While backwards compatibility is a virtue, each framework and site author need to decide on the minimum browser requirements and how to support browsers that do not meet them.

Cutting the mustard with ECMAScript modules

This technique absolved developers from writing convoluted, backwards-compatible JavaScript. It made the JavaScript simpler and more robust since it did not have to deal with every eventuality.

Not all frameworks use Progressive Enhancement or Graceful Degradation. Not all frameworks have a strategy for browsers that do not meet the minimum requirements. For some frameworks, the site is just empty or broken in these browsers.

It is hard to even find out the minimum requirements of popular frameworks today. Only few state them explicitly. Most tacitly use JavaScript APIs or ECMAScript features introduced recently without realizing that this raises the bar of entry.

Using new ECMAScript syntax safely: The optional chaining operator

const user = { name: 'Robin' };
// The user might have an address or not
console.log(user.address?.street);

Technically, optional chaining is “syntactic sugar”: a shorter, more readable way to write a logic that was already possible before. Syntactic sugar can easily be transpiled into older syntax with broader support:

const user = { name: 'Robin' };
// The user might have an address or not
const street = user.address ? user.address.street : undefined;
console.log(street);

Historically, optional chaining is a relatively new addition to ECMAScript. It was introduced in ECMAScript 11, published in June 2020. The major browser engines already shipped support in February or March 2020 when the corresponding proposal was finished.

The real-life impact of our technical decisions really hit home to me once again: my Mom had trouble volunteering and participating in her local community because somebody shipped the optional chaining operator in their production JavaScript.

If you use new syntax features, do so consciously and mind the consequences. New syntax raises the bar and may thwart previous efforts to support older browsers.

Or we detect the browser support by using optional chaining and setting a flag. If the browser parses the code and sets the flag, we load the modern build that may use optional chaining right away.

We did similar with window.__browserSupportsDynamicImports above. As we have learned, Vite checks for multiple syntax features and sets __vite_is_modern_browser. Let us integrate two syntax checks into one script that sets window.__isModernBrowser:

<!-- Litmus test that uses modern syntax and sets a flag. -->
<script type="module">
// Try to use optional chaining. This code does nothing on
// new browsers and causes a syntax error on old browsers.
window.__testingOptionalChaining?.test;
// Load modern build with dynamic import. It is safe to use
// dynamic imports and optional chaining in the build.
import('./modern-build.js');
// Set a global flag that the browser passed the litmus test.
window.__isModernBrowser = true;
</script>
<script type="module">
// This script is executed in browsers with ECMAScript module
// support. If the flag is not set, the browser did not pass
// the litmus test.
if (!window.__isModernBrowser) {
  // Load the legacy build.
  const script = document.createElement('script');
  script.src = './legacy-build.js';
  document.head.appendChild(script);
}
</script>
<!-- Legacy build for browsers without ECMAScript module support. -->
<script nomodule src="./legacy-build.js"></script>

The future

The ECMAScript standard and browser APIs keep evolving. Many innovations make it easier to deliver small, fast, custom-fit JavaScript to the browser.

Even if we take ECMAScript modules, dynamic imports and potentially more features as a baseline for our JavaScript, we constantly need to think about browser compatibility. The nature of the web has not changed. We always have to deal with diverse browsers with hugely different capabilities.

Therefore we still need Progressive Enhancement and Graceful Degradation. If we use the latest JavaScript features and want to support slightly older browsers, we still need two builds. We will still need transpilation, feature detects and polyfills in the future.

PreviousGetting started with systemjs full (ok)NextThư viện chặn truy cập vào Devtool (ok)

Last updated 1 year ago

In client-side JavaScript, an early module format was Asynchronous Module Definition (AMD). It was used together with pioneer loaders like RequireJS or and bundlers like r.js. In server-side JavaScript runtimes, the CommonJS module specification predated Node.js but Node.js made it made popular from 2009 on.

It took fierce discussions to agree on , like specifying "type": "module" in package.json, handling .js, .mjs and .cjs files. The ecosystem-wide migration from CommonJS to ECMAScript modules is far from finished. It still keeps Node authors busy and causes headaches.

For client-side JavaScript, authors quickly adopted ECMAScript modules when writing their code. Transpilers like and bundlers like and understood ECMAScript modules early. The bundlers used the declarative imports and exports to understand the module dependency tree and to optimize the output bundles (“tree shaking”).

In January 2016, to introduce a new script type – module scripts. In these scripts, the familiar import and export syntax can be used.

For backwards-compatibility, in January 2017. Browsers with module support ignore these scripts. Old browser do not recognize the attribute, simply ignore it and execute the script as usual.

Since May 2018, all major browser engines – Chrome 61 / Edge 79, Safari 11, Firefox 60 – .

The crucial point is that ECMAScript module support may serve as a litmus test for several ECMAScript features and JavaScript APIs. The ECMAScript modules build is only downloaded and executed by the mentioned browsers. and may treat them as a baseline for the modern browser build.

Enter dynamic imports. In addition to static, declarative import statements, ECMAScript 11 (2020) introduces . import() is a function that expects the URL of the script and returns a promise:

This structure of the snippet above is adapted from the . With @vitejs/plugin-legacy, Vite compiles two builds:

Vite also deals with a nasty problem of Safari 10.1, released in March 2017. This browser has impartial support for ECMAScript modules. It supports <script type="module"> but not <script nomodule> and therefore executes both code. Vite includes a . Fortunately, this problem has been fixed in Safari 11.

Depending on the network bandwidth and latency (round-trip time), this is a performance nightmare. To mitigate this problem, Vite analyzes the module graph and adds elements to the page. So when the page embeds a.js with <script type="module" src="a.js">, Vite will add <link rel="modulepreload"> for b.js and c.js. The browser then requests and downloads a.js, b.js and c.js in parallel, utilizing the full available bandwidth.

There is ECMAScript syntax that can be transpiled easily and there are browser APIs that can be polyfilled easily. We make sure to include these polyfills and configure Babel to . See also the targets and polyfills.

If these capabilities are highly beneficial, we use them in browsers which support them, guarded by feature detection. We make sure that older browsers do not throw parsing or runtime errors. We write .

Angular CLI: ECMAScript module build only. . Angular uses dynamic imports for route-level code splitting. (Angular 16 allows to use Vite as dev server, but the production build works the same.)

Next.js: Does not use ECMAScript modules. Uses nomodule to load polyfills though. Allows to .

Nuxt.js: Does not use ECMAScript modules. One build per default. Allows to .

Sveltekit: Uses dynamic imports without feature detection or fallback. Sveltekit uses Vite under the hood, but .

Remix: ECMAScript modules and dynamic imports only. On purpose, . Remix supports older browser by not serving them JavaScript, falling back to server-side logic.

Back in 2012, developers at the BBC used Progressive Enhancement to deliver a robust site to all browsers. The core experience in plain HTML worked without JavaScript. The developers guarded the JavaScript with feature detects so it only executed in browsers that “”, that is, meet a certain mark.

Since 2018, several . As you can see in the list above, several frameworks are applying this approach.

Unfortunately, developers often raise the bar unintentionally. For example, I like the . It helps to write more robust code.

By the way – ECMAScript 11 is the same edition that introduced . But browsers started to support dynamic imports much earlier than optional chaining.

Today, optional chaining . 6.67 % of all used browsers do not support it. Some of them will execute the modern build but will not support optional chaining.

Recently, Jim Nielsen described in his blog post what happens when new JavaScript syntax is used without caution:

To use the optional chaining operator safely, we can apply the knowledge from .

We can either – both in the modern and the legacy build.

There are several upcoming features that will make ECMAScript modules in the browser more powerful. is one of them. Since March 2023, all major browser engine support import maps. With imports maps, you do not necessarily need a traditional package manager and a module bundler to import third-party dependencies.

Luckily, there is a . Note that it is highly complex since it fetches, parses and rewrites the module code right in the browser before executing it.

SystemJS
how Node handles ECMAScript modules
Babel
Rollup
Webpack
the HTML specification was extended
the nomodule attribute for script was introduced
support native ECMAScript modules
We know what they are capable of
dynamic, programmatic import calls
legacy plugin for the Vite build tool
workaround that prevents Safari 10.1 from executing nomodule scripts
<link rel="modulepreload">
perform the right transformations to support a certain list of browsers
Vite legacy plugin options
robust JavaScript
Angular only supports most recent browsers
configure Babel and load polyfills
build and serve a modern and a legacy build
@vitejs/plugin-legacy currently does not work with Sveltekit
Remix runs in browsers that support ECMAScript modules
cut the mustard
developers have been proposing ECMAScript modules as a new way to cut the mustard
optional chaining operator
dynamic imports described above
is supported by 93.33 % browsers worldwide, according to Can I Use
The Optional Chaining Operator, “Modern” Browsers, and My Mom
detecting support for dynamic imports
transpile it to more robust syntax using Babel with @babel/preset-env
Import maps
shim for import maps