javascript
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
On this page
  • Javascript module, import, export, dễ ẹc, nhưng có thể bạn vẫn chưa biết
  • 1. Module là gì?
  • 2. Tại sao cần module?
  • 3. Module những năm về trước
  • 4. Module không phải là...
  • 5. Module trong CommonJS - NodeJS
  • 6. Module trong ES6
  • 7. Khác nhau giữa ES6's module và CommonJS's module (Quan trọng)
  • 8. Kết luận
  • 9. Nguồn và bài viết hay liên quan

Was this helpful?

Javascript module, import, export, dễ ẹc, nhưng có thể bạn vẫn chưa biết

https://kysumattien.com/javascript-module-history/?fbclid=IwAR1eBQCcRLZxITwJZUcotImIhWTHnBlp9ptjpGwB2oD8egOGf9C40jJkWAE

PreviousHow TO - List Grid View (ok)Next[BABEL] Giải thích gói babel (ok)

Last updated 4 years ago

Was this helpful?

Javascript module, import, export, dễ ẹc, nhưng có thể bạn vẫn chưa biết

Thiên Bùi2020-09-22

Javascript module, import, export, dễ ẹc, nhưng có thể bạn vẫn chưa biết

Chắc hẳn chúng ta đã quá quen với cú pháp import và export trong javascript, sử dụng nó một cách thuần thục (hoặc chưa), và mặc định đây là điều hiển nhiên trong thế giới javascript.

Nhưng mấy ai biết được rằng, để có được những import, export kia, bản thân javascript đã phải nỗ lực không ngừng tiến hóa mới có khái niệm module tiện dụng như thế này cho anh em chúng ta dùng.

Bài viết hôm nay mình sẽ cùng các bạn đi qua khái niệm module (đọc là "mo dzù ồl nha các bạn :D) trong JavaCript. Module là gì, tại sao module quan trọng, quá trình hình thành của javascript module và nhiều vấn đề hay ho khác.

Trong bài viết đôi chỗ sẽ có những khái niệm, diễn giải khá hàn lâm nhưng chỉ cần chúng ta chịu khó đọc chậm và suy nghĩ kỹ càng thì sẽ nắm bắt được ý đồ đang diễn giải. Chúc các bạn gặt hái được nhiều kiến thức bổ ích nhé. Chúng ta bắt đầu thôi.

Nếu bạn đã quá quen thuộc với concept module, CommonJS module, hay ES6 module, bạn có thể bỏ qua các section đầu, nơi mình giới thiệu chi tiết về module cho các bạn mới và nhảy tới section 7. Khác nhau giữa ES6's module và CommonJS's module (Quan trọng)

1. Module là gì?

Một module là một tập hợp, một gói, một packet, chứa data - ví dụ các biến lưu giữ state,..., các hàm (function hoặc method) lấy dữ liệu, thao tác, thay đổi giá trị, các biến state đó nhằm phục vụ một chức năng nhất định. Để dễ hình dung thì các library, npm package ta dùng hằng ngày nhìn chung chính là các module.

Cơ bản một web app tổng thể sẽ có nhiều thành phần, nhiều chức năng kết hợp lại với nhau. Mỗi chức năng, thành phần riêng biệt đó thường sẽ được xem là mỗi module khác nhau.

Module có tính stateful: nghĩa là nó lưu giữ, duy trì một số data, object instance,... xuyên suốt quá trình khởi tạo và sử dụng module đó. Kèm theo đó là các function, method dùng để access, update các data, object instance (hay còn có thể gọi là state information) kia. Đó là lý do gọi module có tính stateful.

Ví dụ như package Swiper.js. Khi import và sử dụng package này, chúng ta sẽ đi khởi tạo một object instance bằng cách:

var mySwiper = new Swiper('.swiper-container', {
  speed: 400,
  spaceBetween: 100,
});

Công việc này tạo ra một object instance tồn tại và duy trì bên trong moudle Swiper này.

Tất nhiên, để làm cho swiper (banner, slider, ...) này hoạt động, kéo chạy sang trái, sang phải, animation các thứ, ta sẽ cần các method tương ứng, thay đổi trạng thái của instance object mySwiper kia, ví dụ:

mySwiper.slideNext();

Với các biến và các function bên trong module, sẽ có các phần được che dấu (private), chỉ dùng nội bộ trong module đó. Ngoài ra, các phần data, function còn lại sẽ được public ra cho người dùng sử dụng (ví dụ các function, API các npm package cho phép chúng ta sử dụng hay ở với ví dụ swiper.js thì chính là method slideNext()).

2. Tại sao cần module?

Tính đóng gói - một trong số các đặc tính cơ bản của lập trình hướng đối tượng (OOP) mà chúng ta nghe ra rả hằng ngày, từ lúc đi học, đi phỏng vấn, đến lúc đi làm. Tác dụng và tầm quan trọng của tính đóng gói này thật ra còn quan trọng hơn nhiều, được dùng hằng ngày chứ không chỉ đơn thuần có ích trong thế giới OOP.

Tính đóng gói cho phép chúng ta đóng gói (tất nhiên :))) các data và functions liên quan với nhau thành một khối, một gói, để phục vụ một chức năng nhất định.

Module có quan trọng và hữu dụng không?

Có. Thật ra bạn đang dùng module hằng ngày, hàng giờ. Chính việc viết các file js riêng biệt ví dụ search.js, urlHelpers.js, chính là bạn đang áp dụng triết lý của tính đóng gói nói riêng và module nói chung.

Hay như khi làm việc với ReactJS, ta thường tách nhỏ các component ra thành các folder riêng biệt. Ví dụ: SearchBar Component. Folder sẽ có file css style, dumb component thực hiện chức năng render, smart component thực hiện call api, get data,... Mọi thứ kết hợp với nhau, và được đóng gói thành <SearchBar /> component mà chúng ta dùng để import ở nơi khác.

Bằng cách tạo ra module, quyết định phần nào là private, phần nào là public, giúp che dấu thông tin code, chỉ cho phép người dùng thao tác với các phần thông tin, function public.

Việc đóng gói các biến, function vào một module, rồi đến lúc sử dụng, chúng ta import vào dưới một cái tên khác cũng đem lại lợi ích lớn đó là tránh việc các khai báo biến, hàm bị trùng lặp hay vô tình bị ghi đè lên nhau, thứ mà chúng ta sẽ dễ dàng mắc phải khi làm việc với global scope.

Cuối cùng, tựu chung các lợi ích trên giúp ích rất nhiều trong việc cấu trúc, hệ thống source code, giúp ích cho việc phát triển, scale up hay đơn giản là dễ dàng maintainable trong tương lai. Module quá tuyệt vời đúng không các bạn!?

3. Module những năm về trước

Module tuyệt vời là vậy, nó gần như đóng vai trò rất lớn trong mọi ngôn ngữ lập trình. Ấy vậy mà, có một sự thật vô cùng khủng khiếp, đó là: những năm trước khi xuất hiện bước ngoặt ES6, thì cơ bản, native javascript không có concept về module. Developer phải tự động não, tìm trick, và manually tạo ra module bằng cách:

Sử dụng IIFE (Immediately Invoked Function Expression)

var Student = (function defineStudent() {
  var records = [
    { id: 14, name: 'Kyle', grade: 86 },
    { id: 73, name: 'Suzy', grade: 87 },
    { id: 112, name: 'Frank', grade: 75 },
    { id: 6, name: 'Sarah', grade: 91 },
  ];

  var publicAPI = {
    getName,
  };

  return publicAPI;

  // ************************

  function getName(studentID) {
    var student = records.find(student => student.id == studentID);
    return student.name;
  }
})();

Student.getName(73); // Suzy

Bằng cách sử dụng IIFE, chúng ta vừa khai báo vừa chạy ngay lập tức hàm defineStuden, hàm này trả ra một object chứa proptery trỏ tới hàm getName.

Xét lại định nghĩa về một module. Hàm defineStudent có chứa biến biến state là records và phương thức getName để thao tác với biến state đó (cụ thể ở đây là get ra tên của student có id tương ứng). Như vậy , đây chính là một module.

Mọi thứ sau đó được gán ngược lại cho biến Student. Student giờ đây trở thành một instance của module. Khi gọi Student.getName(73), lợi dụng tính chất của closure (getName vẫn có khả năng lấy được data từ records, mặc dù hàm defineStudent đã chạy rồi), chúng ta đã có khả năng lấy được thông tin về tên của student có id là 73. Tuyệt vời!

Nói theo ngôn ngữ bậc cao loài người, chúng ta có thể phát biểu rằng: Đây là module Student, nhiệm vụ của module này là khởi tạo danh sách các sinh viên, và cho phép chúng ta tra cứu thông tin về tên của sinh viên.

Một số lưu ý:

Trong ví dụ trên, data records đang được hard-code trong lúc khởi tạo module để đơn giản hóa quá trình giải thích cho các bạn hiểu. Nhưng trong các module thực tế, data này sẽ được khởi tạo (hoặc load) từ database, APIs,... sau đó được load vào module instance bằng một phương thức cụ thể, ví dụ setListStudents.

Nhớ lại kiến thức về lexical scope, bằng cách khai báo các biến và method bên trong hàm defineStudent, mọi thứ đã được che dấu một cách mặc định, rằng mọi người ở scope bên ngoài sẽ không có khả năng tùy ý thay đổi giá trị các biến, hàm trong module của chúng ta. Họ chỉ có thể thực hiện một số action nhất định mà chúng ta cho phép (bằng cách return ra method tương ứng) mà thôi.

Với ví dụ trên, module của chúng ta chỉ có một instance duy nhất là Student, pattern này còn được biết đến với cái tên là Singleton. Nhưng nếu ta cần nhiều hơn một instance thì sao?

Sử dụng Module Factory

// factory function, not singleton IIFE
function defineStudent() {
  var records = [
    { id: 14, name: 'Kyle', grade: 86 },
    { id: 73, name: 'Suzy', grade: 87 },
    { id: 112, name: 'Frank', grade: 75 },
    { id: 6, name: 'Sarah', grade: 91 },
  ];

  var publicAPI = {
    getName,
  };

  return publicAPI;

  // ************************

  function getName(studentID) {
    var student = records.find(student => student.id == studentID);
    return student.name;
  }
}

var firstInstance = defineStudent();
var secondInstance = defineStudent();
firstInstance.getName(73); // Suzy
...

Tới đây, bạn đã dần dần thấy khái niệm và cách tạo ra module dần dần quen thuộc và không còn khó khăn đúng không nào!?

4. Module không phải là...

Đến thời điểm này, chúng ta đã nhận ra module sẽ được tạo ra bằng cách wrap mọi thứ bên trong một scope, một function hay một object nhất định, tuy nhiên... các cách làm sau đây không được xem là một module đúng nghĩa:

Namespaces (Stateless Grouping)

Nếu chúng ta gom nhóm một số function với nhau mà không có data (stateless), thì đây không được xem là một module mà được gọi là namespace

// namespace, not module
var Utils = {
  cancelEvt(evt) {
    evt.preventDefault();
    evt.stopPropagation();
    evt.stopImmediatePropagation();
  },
  wait(ms) {
    return new Promise(function c(res) {
      setTimeout(res, ms);
    });
  },
  isValidEmail(email) {
    return /[^@]+@[^@.]+\.[^@.]+/.test(email);
  },
};

Data Structures (Stateful Grouping)

Nếu chúng ta chỉ gom nhóm một set các giá trị state và function cùng nhau, nhưng không limit phần nào là public, phần nào là private (thông qua việc invoke hàm và return ra value như ví dụ trước), thì đây cũng không được xem là một module. Vì nó không có tính che dấu thông tin.

// data structure, not module
var Student = {
  records: [
    { id: 14, name: 'Kyle', grade: 86 },
    { id: 73, name: 'Suzy', grade: 87 },
    { id: 112, name: 'Frank', grade: 75 },
    { id: 6, name: 'Sarah', grade: 91 },
  ],
  getName(studentID) {
    var student = this.records.find(student => student.id == studentID);
    return student.name;
  },
};

Student.getName(73);
// Suzy

5. Module trong CommonJS - NodeJS

NodeJs ra đời nhằm biến JS có thể sử dụng được ở tầng back-end. Và cũng như bao ngôn ngữ lập khác thời bấy giờ - vốn có concept về module, NodeJS phải tìm cách implement module bên trong nó bằng cách sử dụng library CommonJs's module.

Với module trong CommonJS hay NodeJS, các module có đặc tính file-based, tức là mỗi một file js là một module.

Xét ví dụ về NodeJS module sau:

var records = [
  { id: 14, name: 'Kyle', grade: 86 },
  { id: 73, name: 'Suzy', grade: 87 },
  { id: 112, name: 'Frank', grade: 75 },
  { id: 6, name: 'Sarah', grade: 91 },
];

function getName(studentID) {
  var student = records.find(student => student.id == studentID);
  return student.name;
}

module.exports.getName = getName;

Đây chính là một module trong NodeJS.

Mặc cho records và getName được khai báo ở top-level scope, các biến và hàm này vẫn đảm bảo mặc định private và chỉ nằm trong module này, tức là không nằm trong globals scope (ví dụ như ở browser thì các biến và function nằm ở global scope sẽ được truy vấn bằng window.xyz). Vì sao lại như vậy?

Vì mặc định một file js được viết trong NodeJS trước khi được xử lý sẽ được bao bọc bởi một hàm wrapper. Với ví dụ trên, mọi thứ sẽ trở thành như sau:

function Module(module, require, __dirname,...) {
  var records = [
    { id: 14, name: 'Kyle', grade: 86 },
    { id: 73, name: 'Suzy', grade: 87 },
    { id: 112, name: 'Frank', grade: 75 },
    { id: 6, name: 'Sarah', grade: 91 },
  ];

  function getName(studentID) {
    var student = records.find(student => student.id == studentID);
    return student.name;
  }
  module.exports.getName = getName;
}

Node sau đó mới invoke Module và nhờ vậy, chúng ta có thể hiêu tại sao mọi thứ bên trong Module trở nên private với thế giới bên ngoài.

Sau đó, developer chúng ta sẽ chọn ra những public API muốn export ra thế giới bên ngoài bằng cách export một cách tường minh

module.exports.getName = getName;

hoặc export dưới dạng một object:

module.exports = {
  getName,
};

Ở module hoặc file js khác, muốn sử dụng CommonJS module vừa khởi tạo phía trên, chúng ta sử dụng phương thức require

var Student = require('/path/to/student.js');

Student.getName(73);
// Suzy

Một lưu ý vô cùng quan trọng ở đây là: CommonJS modules có tính singleton. Không cần biết bạn require một module bao nhiêu lần, gán bằng bao nhiêu tên biến, thì mọi thứ đều đang trỏ về chung một module instance.

Ví dụ:

var Student1 = require('/path/to/student.js');
var Student2 = require('/path/to/student.js');

Student1.getStudent(73).changeName('Thien');

Ví dụ module Student lúc trước của chúng ta có thêm phương thức changeName giúp thay đổi tên của một studen, thì với đặc tính singleton, khi Student1 thay đổi name của student có id = 73 thành 'Thien', thì student tương ứng trong Student2 cũng sẽ change theo. Nói cách khác, theo đặc tính của singleton, hai biến Student1 và Student2 thực chất đang trỏ tới cùng một instance.

6. Module trong ES6

Như vậy, thoạt đầu từ cú pháp IFFE để tạo ra module, rồi đến CommonJS, và còn nhiều thư viện khác nữa (AMD, UMD, ...). Rõ ràng, module đóng một vai trò vô cùng quan trọng trong cộng đồng dev JavaScript. Và cuối cùng, JavaSciprt native module đã xúât hiện hay còn được biết với cái tên ES Module

Về cơ bản, ES Module (ESM) có khá nhiều điểm tương đồng với CommonJS. ESM cũng có tính chất file-based (mỗi file js là một module), có luôn singleton, và mọi thứ by default sẽ được xem là private tức chỉ có thể access được bên trong module đó. Tuy nhiên có một khác biệt nhỏ đó là: ESM files mặc định chạy trong strict mode.

Tiếp đến, thay vì sử dụng module.exports giống như CommonJS, ESM sử dụng keyword export, đồng thời sử dụng keyword import thay vì method require như CommonJS.

var records = [
  { id: 14, name: 'Kyle', grade: 86 },
  { id: 73, name: 'Suzy', grade: 87 },
  { id: 112, name: 'Frank', grade: 75 },
  { id: 6, name: 'Sarah', grade: 91 },
];

function getName(studentID) {
  var student = records.find(student => student.id == studentID);
  return student.name;
}

export { getName };

Ngoài cách export một object như trên, ESM còn cho phép chúng ta thoải mái sử dụng cú pháp export cho từng biến hay function cụ thể (named export):

// awesome-library.js
export const PI = 3.1415926;

export function sum(...args) {
  log('sum', args);
  return args.reduce((num, tot) => tot + num);
}

export function mult(...args) {
  log('mult', args);
  return args.reduce((num, tot) => tot * num);
}

// private function
function log(...msg) {
  console.log(...msg);
}

Một biến thể nữa là default export.

export default function getName(studentID) {
  // ..
}

Khác với named export, một module chỉ có duy nhất một default export. Nếu người dùng không chỉ rõ phần nào cần import, mà chỉ import mopdule một cách chung chung, thì phần export default này sẽ được import.

Các biến thể import:

Named import

Sử dụng "named import", chúng ta sẽ import những thứ cần thiết, tránh import cả module.

import { sum, mult } from './lib.js';

console.log(sum(1, 2, 3, 4));
console.log(mult(1, 2, 3, 4));

Alias thành một cái tên khác

Bằng cách sử dụng keyword as, chúng ta có thể import và gán một cái tên khác cho phần api vừa được import.

import { sum as addAll, mult as multiplyAll } from './lib.js';

console.log(addAll(1, 2, 3, 4));
console.log(multiplyAll(1, 2, 3, 4));

default import

Như đã nhắc đến phía trên, nếu module có export default, thì khi đứng ở module khác chúng ta có thể import phần default đó như sau:

import getName from "/path/to/students.js";

getName(73);

Mix vừa default import vừa named import

import { default as getName, /* .. others .. */ }
   from "/path/to/students.js";

getName(73);

Namespace import

Cuối cùng, bạn có thể sử dụng dấu * để import toàn bộ mọi thứ được export bên trong một module, bao gồm cả default và named export, gom chúng thành một name space - một biến xài chung như sau:

import * as Student from "/path/to/students.js";

Student.getName(73);

7. Khác nhau giữa ES6's module và CommonJS's module (Quan trọng)

Tới phần quan trọng nhất rồi. Ở section này, chúng ta sẽ cùng nhau tìm hiểu về một số khác biệt giữa CommonJS module và ES module. Chúng rất thú vị và có thể nhiều dev trong số chúng ta vẫn chưa biết tới.

Mọi điểm khác nhau giữa ES module và CommonJS module có thể được tóm gọn bằng một câu như sau: ES6 Module là Static và CommonJS Module là Dynamic. Cụ thể, NodeJS chạy ở server, vì thế mọi thứ import, export sẽ diễn ra ở Runtime, ngược lại ESM diễn ra ở Parse time - trước khi code chạy (ví dụ với trường hợp sử dụng transpiler Babel hay bundler như Webpack).

Từ điểm khác biệt cốt lõi đó sẽ kéo theo các điểm khác nhau giữa ESM và CommonJS module như:

Tôi có thể đặt import, export ở đâu?

ESM: Bắt buộc phải ở top-level scope, hay nói cách khác: không được nằm trong các câu lệnh rẽ nhánh if, else, trong các funtcion con,...

// valid
import foo from 'foo';

//invalid 
if (false) {
  import bar from 'bar';
}

// invalid
setTimeout(function () {
  export let num = 14;
})

Lý do như đã nói phía trên, ESM chỉ hoạt động ở quá trình Parse Time, tổng hợp code, trước khi code chạy. Nhìn chung, mọi thứ import và export phải được biết trước, không cho phép dynamic import hay export dựa theo một điều kiện nhất định trong suốt quá trình chạy code.

CommonJS: Bạn có thể đặt require/module.exports anywhere

if (Math.random() > 0.1) {
  exports.foobar = 7;
} else {
  require('lib.js');
}

Với CommonJS module, mọi thứ xoay quanh object, mọi thứ diễn ra ở Runtime. exports, require nhìn chung cũng chỉ là add, get value từ một object, bạn có đặt ở bất kỳ logic, bất kỳ scope nào tùy thích.

Khi nào có thể sử dụng được các giá trị import?

ESM: Dùng trước cả khi import:

// valid
console.log('this is ok', foo);
import foo from 'foo';

Một lần nữa, vì import, export trong ESM diễn ra ở quá trình parse code, nên các cú pháp import có thể được hoisted giống như khi khai báo var, khiến cho đoạn code trên hoàn toàn hợp lệ.

CommonJS: Với CommonJS, bạn không thể refer tới một giá trị trước khi nó được require.

//throws an error
console.log('oh no an error', foo); // ReferenceError
const foo = require('./foo');

Ở đây, việc thực hiện gọi require để import một module chỉ đơn thuần là chạy một hàm, không hề có hoisting ở đây, dẫn đến lỗi ReferenceError

Chúng ta có thể import bằng cách nào?

ESM: String literal, túm lại giá trị import phải là string

// valid
import foo from 'foo';

//invalid 
import foo from 'f' + 'oo';
import foo from `template-string`;
import foo from 6;
import foo from {};

CommonJS: Như đã nhắc ở section trên khi nói về CommonJS, require là một method, không phải là native syntax như import. Chính vì việc nó là một hàm bình thường, chúng ta có thể pass vào logic import tùy thích.

require(hasDoneSomething ?
  'left-pad' :
  Math.random() * Date.now() / 2 + 7 + '.js'
);

Variable binding

ESM: Với import và export trong ESM, variables sẽ được bind mặc định.

// foo.js
export let foo = 4;
export function incFoo() { foo += 1; }
//main.js
import { foo, incFoo } from './foo.js';
console.log(foo); // 4
incFoo();
console.log(foo); // 5

Như chúng ta thấy từ kết quả console.log. Mỗi lần chạy hàm incFoo(), biến foo cũng được tăng lên, như vậy mặc định đã có quá trình bind variable.

CommonJS: Với CommonJS, mọi thứ... có chút phức tạp hơn, cùng xem xét kỹ đoạn code dưới đây:

// lib.js
var foo = 4;
module.exports = { foo, bar: 7, incFoo, incBar };
function incFoo() { foo += 1; }
function incBar() { module.exports.bar += 1; };

// main.js
var instance = require('./lib');
console.log(instance.foo, instance.bar); // 4, 7
instance.incFoo();
instance.incBar();
console.log(instance.foo, instance.bar); // 4, 8

Với CommonJS thì không có cơ chế variable binding mặc định kia. Tức là, biến foo được export ở dòng thứ 2 kia chỉ đơn giản nhận giá trị là 4 (key là foo, value là 4). Khi gọi incFoo(), biến foo ở dòng thứ nhất được tăng lên, nhưng foo trong object exports thì không.

Để tăng được biến đếm khi sử dụng CommonJS module, trong hàm incBar, ta phải trỏ trực tiếp tới giá property bar trong object exports, cụ thể là module.exports.bar

8. Kết luận

Bài viết hôm nay khá dài, cám ơn các bạn đã đón đọc. Chúc các bạn học tốt và nắm được các vấn đề chủ chốt về Module trong JavaScript.

Mến chào các bạn, hẹn gặp lại các bạn trong các post tiếp theo.

9. Nguồn và bài viết hay liên quan

Các concept, diễn giải, ví dụ trong bài viết được mình tìm tòi và tổng hợp từ nhiều nguồn, các bạn có thể đọc tài liệu, xem video gốc, hoặc thậm chí đào sâu hơn về Module Pattern thông qua các tài liệu dưới đây:

Để sử dụng được nhiều instance trong CommonJS module, các bạn có thể tham khảo bài viết .

- Tác giả: Craig Bucker

Video youtube:

You Don't Know JS Yet:

Tác giả: Addy Osmani

sau
Understanding ES6 Modules
Modules: ES2015 vs. CommonJS (English)
Chapter 8: The Module Pattern
The Module Pattern - Learning JavaScript Design Patterns
Javascript module, import, export, dễ ẹc, nhưng có thể bạn vẫn chưa biết
Thiên Bùi
Thiên Bùi