Skip to content

JavaScript Libraries

JavaScript libraries are pre-written code collections that provide encapsulated specific functionalities, simplifying development and improving efficiency. In modern JavaScript development, using libraries wisely can greatly reduce repetitive work and improve code quality.

What is a JavaScript Library

A JavaScript library is a set of pre-written JavaScript code that encapsulates specific functionality for developers to reuse in projects. Libraries typically solve problems in specific domains, such as DOM manipulation, animation effects, data processing, etc.

Library Characteristics

  1. Single Purpose: Focuses on solving specific problems
  2. Reusability: Can be used across multiple projects
  3. Encapsulation: Hides implementation details, provides simple interfaces
  4. Standardization: Follows industry standards and best practices
  5. Community Support: Usually maintained by active communities

Common JavaScript Libraries

1. Lodash - Utility Library

Lodash is a modern JavaScript utility library that provides processing methods for arrays, objects, strings, and other data types.

javascript
// Install: npm install lodash
// Import
const _ = require('lodash');

// Array operations
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// Chunk
console.log(_.chunk(numbers, 3)); 
// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]

// Unique
const duplicates = [1, 2, 2, 3, 3, 4, 5, 5];
console.log(_.uniq(duplicates)); // [1, 2, 3, 4, 5]

// Difference
const array1 = [1, 2, 3];
const array2 = [2, 3, 4];
console.log(_.difference(array1, array2)); // [1]

// Intersection
console.log(_.intersection(array1, array2)); // [2, 3]

// Union
console.log(_.union(array1, array2)); // [1, 2, 3, 4]

// Object operations
const users = [
  { name: "John", age: 25, active: true },
  { name: "Jane", age: 30, active: false },
  { name: "Bob", age: 35, active: true }
];

// Filter
console.log(_.filter(users, { active: true }));

// Find
console.log(_.find(users, { age: 30 })); // { name: "Jane", age: 30, active: false }

// Group by
console.log(_.groupBy(users, "active"));

// Sort
console.log(_.orderBy(users, ["age"], ["desc"]));

// Deep clone
const original = { 
  name: "John", 
  profile: { 
    age: 25, 
    hobbies: ["reading", "swimming"] 
  } 
};

const cloned = _.cloneDeep(original);
cloned.profile.age = 26;
console.log(original.profile.age); // 25
console.log(cloned.profile.age); // 26

// Debounce
const debouncedFunction = _.debounce(() => {
  console.log("Debounced function executed");
}, 300);

// Throttle
const throttledFunction = _.throttle(() => {
  console.log("Throttled function executed");
}, 1000);

// String operations
console.log(_.camelCase("hello world")); // "helloWorld"
console.log(_.kebabCase("hello world")); // "hello-world"
console.log(_.startCase("hello world")); // "Hello World"
console.log(_.capitalize("hello world")); // "Hello world"

2. Day.js / Moment.js - Date Libraries

Day.js is a lightweight date handling library (Moment.js alternative).

javascript
// Install: npm install dayjs
const dayjs = require('dayjs');

// Create date
const now = dayjs();
const specificDate = dayjs("2024-01-15");
const fromString = dayjs("2024-01-15 10:30:00");

// Format date
console.log(now.format("YYYY-MM-DD")); // "2024-01-15"
console.log(now.format("YYYY/MM/DD HH:mm:ss")); // "2024/01/15 10:30:00"

// Date calculation
console.log(now.add(7, "day").format("YYYY-MM-DD")); // 7 days later
console.log(now.subtract(1, "month").format("YYYY-MM-DD")); // 1 month ago
console.log(now.startOf("month").format("YYYY-MM-DD")); // Start of month
console.log(now.endOf("month").format("YYYY-MM-DD")); // End of month

// Date comparison
const date1 = dayjs("2024-01-15");
const date2 = dayjs("2024-01-20");

console.log(date1.isBefore(date2)); // true
console.log(date1.isAfter(date2)); // false
console.log(date1.isSame(date2, "year")); // true

// Date difference
console.log(date2.diff(date1, "day")); // 5
console.log(date2.diff(date1, "hour")); // 120

// Relative time (requires plugin)
// const relativeTime = require('dayjs/plugin/relativeTime');
// dayjs.extend(relativeTime);
// console.log(dayjs().subtract(1, "hour").fromNow()); // "1 hour ago"

3. Axios - HTTP Client Library

Axios is a Promise-based HTTP client for browsers and Node.js.

javascript
// Install: npm install axios
const axios = require('axios');

// Basic GET request
axios.get('https://api.github.com/users/octocat')
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error(error);
  });

// GET with parameters
axios.get('https://api.github.com/search/repositories', {
  params: {
    q: 'javascript',
    sort: 'stars',
    order: 'desc'
  }
}).then(response => {
  console.log(response.data.items);
});

// POST request
axios.post('https://jsonplaceholder.typicode.com/posts', {
  title: 'foo',
  body: 'bar',
  userId: 1
}).then(response => {
  console.log(response.data);
});

// Concurrent requests
Promise.all([
  axios.get('https://api.github.com/users/octocat'),
  axios.get('https://api.github.com/users/torvalds')
]).then(([octocat, torvalds]) => {
  console.log('Octocat:', octocat.data.name);
  console.log('Torvalds:', torvalds.data.name);
});

// Create instance
const api = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 5000,
  headers: {
    'Authorization': 'Bearer your-token',
    'Content-Type': 'application/json'
  }
});

// Request interceptor
api.interceptors.request.use(
  config => {
    console.log('Sending request:', config.url);
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

// Response interceptor
api.interceptors.response.use(
  response => {
    console.log('Received response:', response.status);
    return response;
  },
  error => {
    if (error.response && error.response.status === 401) {
      console.log('Unauthorized, please login again');
    }
    return Promise.reject(error);
  }
);

4. D3.js - Data Visualization Library

D3.js is a powerful data visualization library for creating dynamic, interactive data charts.

javascript
// Basic D3.js bar chart example
// Include: <script src="https://d3js.org/d3.v7.min.js"></script>

// Prepare data
const data = [
    { name: "Apple", value: 30 },
    { name: "Banana", value: 20 },
    { name: "Orange", value: 25 },
    { name: "Grape", value: 15 },
    { name: "Strawberry", value: 10 }
];

// Set chart dimensions and margins
const margin = { top: 20, right: 30, bottom: 40, left: 40 };
const width = 500 - margin.left - margin.right;
const height = 300 - margin.top - margin.bottom;

// Create SVG container
const svg = d3.select("#chart")
    .append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", `translate(${margin.left},${margin.top})`);

// Set scales
const x = d3.scaleBand()
    .domain(data.map(d => d.name))
    .range([0, width])
    .padding(0.1);

const y = d3.scaleLinear()
    .domain([0, d3.max(data, d => d.value)])
    .range([height, 0]);

// Create bars
svg.selectAll(".bar")
    .data(data)
    .enter()
    .append("rect")
    .attr("class", "bar")
    .attr("x", d => x(d.name))
    .attr("width", x.bandwidth())
    .attr("y", d => y(d.value))
    .attr("height", d => height - y(d.value));

// Add axes
svg.append("g")
    .attr("transform", `translate(0,${height})`)
    .call(d3.axisBottom(x));

svg.append("g")
    .call(d3.axisLeft(y));

5. Three.js - 3D Graphics Library

Three.js is a WebGL-based 3D graphics library for creating and displaying 3D content in browsers.

javascript
// Basic Three.js example
// Include: <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>

// Create scene
const scene = new THREE.Scene();

// Create camera
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;

// Create renderer
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// Create cube
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// Create light
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(1, 1, 1).normalize();
scene.add(light);

// Animation loop
function animate() {
    requestAnimationFrame(animate);

    // Rotate cube
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;

    renderer.render(scene, camera);
}

animate();

// Window resize handling
window.addEventListener('resize', () => {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
});

Library Selection and Usage

Selection Criteria

javascript
// Library evaluation criteria
const libraryEvaluationCriteria = {
  // 1. Functionality
  features: [
    "Does it meet project requirements",
    "Is functionality complete",
    "How extensible is it"
  ],
  
  // 2. Performance
  performance: [
    "Load speed",
    "Runtime efficiency",
    "Memory usage"
  ],
  
  // 3. Stability
  stability: [
    "Version update frequency",
    "Bug fix speed",
    "Long-term maintenance"
  ],
  
  // 4. Community Support
  community: [
    "Documentation quality",
    "Community activity",
    "Third-party resources"
  ],
  
  // 5. Learning Curve
  learningCurve: [
    "Is API design intuitive",
    "Is documentation clear",
    "Are examples abundant"
  ],
  
  // 6. Size
  size: [
    "File size",
    "Supports tree shaking",
    "On-demand loading"
  ]
};

On-demand Loading

javascript
// Lodash on-demand loading
// Install: npm install lodash
const chunk = require('lodash/chunk');
const uniq = require('lodash/uniq');
const debounce = require('lodash/debounce');

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(chunk(numbers, 3)); // [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
console.log(uniq([1, 2, 2, 3, 3, 4])); // [1, 2, 3, 4]

// Debounce function
const debouncedSearch = debounce((query) => {
  console.log("Search:", query);
}, 300);

// D3.js on-demand loading
// Install: npm install d3-selection d3-scale d3-axis
// import { select } from 'd3-selection';
// import { scaleLinear, scaleBand } from 'd3-scale';
// import { axisBottom, axisLeft } from 'd3-axis';

Custom Utility Library

Creating Your Own Library

javascript
// utils.js - Custom utility library
class CustomUtils {
  // Array utilities
  static array = {
    // Chunk array
    chunk(array, size) {
      const chunks = [];
      for (let i = 0; i < array.length; i += size) {
        chunks.push(array.slice(i, i + size));
      }
      return chunks;
    },
    
    // Unique array
    unique(array) {
      return [...new Set(array)];
    },
    
    // Array difference
    difference(array, ...values) {
      const flatValues = values.flat();
      return array.filter(item => !flatValues.includes(item));
    },
    
    // Array intersection
    intersection(array, ...values) {
      const flatValues = values.flat();
      return array.filter(item => flatValues.includes(item));
    },
    
    // Shuffle array
    shuffle(array) {
      const result = [...array];
      for (let i = result.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [result[i], result[j]] = [result[j], result[i]];
      }
      return result;
    }
  };
  
  // Object utilities
  static object = {
    // Deep clone
    deepClone(obj) {
      if (obj === null || typeof obj !== "object") return obj;
      if (obj instanceof Date) return new Date(obj);
      if (obj instanceof Array) return obj.map(item => this.deepClone(item));
      if (obj instanceof Object) {
        const clonedObj = {};
        for (const key in obj) {
          if (obj.hasOwnProperty(key)) {
            clonedObj[key] = this.deepClone(obj[key]);
          }
        }
        return clonedObj;
      }
    },
    
    // Object map
    map(obj, fn) {
      const result = {};
      for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
          result[key] = fn(obj[key], key);
        }
      }
      return result;
    },
    
    // Object filter
    filter(obj, fn) {
      const result = {};
      for (const key in obj) {
        if (obj.hasOwnProperty(key) && fn(obj[key], key)) {
          result[key] = obj[key];
        }
      }
      return result;
    }
  };
  
  // String utilities
  static string = {
    // Camel case
    camelCase(str) {
      return str.replace(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : '');
    },
    
    // Kebab case
    kebabCase(str) {
      return str.replace(/([A-Z])/g, '-$1')
               .replace(/[-_\s]+/g, '-')
               .toLowerCase();
    },
    
    // Capitalize
    capitalize(str) {
      return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
    },
    
    // Format string
    format(str, ...args) {
      return str.replace(/{(\d+)}/g, (match, index) => {
        return typeof args[index] !== 'undefined' ? args[index] : match;
      });
    }
  };
  
  // Number utilities
  static number = {
    // Precise addition
    add(a, b, precision = 10) {
      return parseFloat((a + b).toFixed(precision));
    },
    
    // Format number
    format(num, options = {}) {
      const {
        decimals = 2,
        thousandSeparator = ",",
        decimalSeparator = "."
      } = options;
      
      const fixed = num.toFixed(decimals);
      const [integer, decimal] = fixed.split(".");
      
      const formattedInteger = integer.replace(
        /\B(?=(\d{3})+(?!\d))/g,
        thousandSeparator
      );
      
      return decimal 
        ? formattedInteger + decimalSeparator + decimal
        : formattedInteger;
    }
  };
  
  // Function utilities
  static function = {
    // Debounce
    debounce(func, wait, immediate = false) {
      let timeout;
      return function executedFunction(...args) {
        const later = () => {
          timeout = null;
          if (!immediate) func.apply(this, args);
        };
        const callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(this, args);
      };
    },
    
    // Throttle
    throttle(func, limit) {
      let inThrottle;
      return function() {
        const args = arguments;
        const context = this;
        if (!inThrottle) {
          func.apply(context, args);
          inThrottle = true;
          setTimeout(() => inThrottle = false, limit);
        }
      };
    },
    
    // Memoize
    memoize(func, resolver) {
      const memoized = function(...args) {
        const key = resolver ? resolver.apply(this, args) : args[0];
        if (memoized.cache.has(key)) {
          return memoized.cache.get(key);
        }
        const result = func.apply(this, args);
        memoized.cache.set(key, result);
        return result;
      };
      memoized.cache = new Map();
      return memoized;
    }
  };
  
  // Date utilities
  static date = {
    // Format date
    format(date, format = "YYYY-MM-DD") {
      const d = new Date(date);
      const year = d.getFullYear();
      const month = String(d.getMonth() + 1).padStart(2, "0");
      const day = String(d.getDate()).padStart(2, "0");
      const hours = String(d.getHours()).padStart(2, "0");
      const minutes = String(d.getMinutes()).padStart(2, "0");
      const seconds = String(d.getSeconds()).padStart(2, "0");
      
      return format
        .replace("YYYY", year)
        .replace("MM", month)
        .replace("DD", day)
        .replace("HH", hours)
        .replace("mm", minutes)
        .replace("ss", seconds);
    },
    
    // Days between two dates
    daysBetween(date1, date2) {
      const oneDay = 24 * 60 * 60 * 1000;
      const firstDate = new Date(date1);
      const secondDate = new Date(date2);
      return Math.round(Math.abs((firstDate - secondDate) / oneDay));
    },
    
    // Relative time
    relativeTime(date) {
      const now = new Date();
      const target = new Date(date);
      const diffInSeconds = Math.floor((now - target) / 1000);
      
      if (diffInSeconds < 60) {
        return "just now";
      } else if (diffInSeconds < 3600) {
        return `${Math.floor(diffInSeconds / 60)} minutes ago`;
      } else if (diffInSeconds < 86400) {
        return `${Math.floor(diffInSeconds / 3600)} hours ago`;
      } else if (diffInSeconds < 2592000) {
        return `${Math.floor(diffInSeconds / 86400)} days ago`;
      } else {
        return this.format(date);
      }
    }
  };
}

// Usage examples
console.log(CustomUtils.array.chunk([1, 2, 3, 4, 5, 6, 7, 8], 3));
console.log(CustomUtils.array.unique([1, 2, 2, 3, 3, 4]));
console.log(CustomUtils.object.deepClone({ a: 1, b: { c: 2 } }));
console.log(CustomUtils.string.camelCase("hello-world"));
console.log(CustomUtils.number.format(1234567.89));
console.log(CustomUtils.date.format(new Date(), "YYYY/MM/DD HH:mm:ss"));

Library Management and Optimization

Package Management

json
{
  "name": "my-project",
  "version": "1.0.0",
  "description": "My JavaScript project",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js",
    "build": "webpack --mode production",
    "test": "jest"
  },
  "dependencies": {
    "axios": "^1.6.0",
    "lodash": "^4.17.21"
  },
  "devDependencies": {
    "webpack": "^5.89.0",
    "webpack-cli": "^5.1.4",
    "jest": "^29.7.0"
  },
  "engines": {
    "node": ">=14.0.0"
  }
}

Performance Optimization

javascript
// Tree Shaking configuration (webpack.config.js)
module.exports = {
  mode: 'production',
  optimization: {
    usedExports: true,
    sideEffects: false
  }
};

// Code splitting - Dynamic imports
async function loadLodash() {
  const { chunk } = await import('lodash/chunk');
  return chunk([1, 2, 3, 4, 5], 2);
}

// Preload
const importantLibrary = import('important-library');

// Lazy loading
document.getElementById('button').addEventListener('click', async () => {
  const { default: Chart } = await import('chart.js');
  // Use chart library
});

// Bundle analysis
// Install: npm install --save-dev webpack-bundle-analyzer
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
  plugins: [
    new BundleAnalyzerPlugin()
  ]
};

Practical Examples

Comprehensive Utility Library

javascript
// comprehensive-utils.js
class ComprehensiveUtils {
  // HTTP utilities
  static http = {
    async request(url, options = {}) {
      const defaultOptions = {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json'
        }
      };
      
      const config = { ...defaultOptions, ...options };
      
      try {
        const response = await fetch(url, config);
        
        if (!response.ok) {
          throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }
        
        const contentType = response.headers.get('content-type');
        if (contentType && contentType.includes('application/json')) {
          return await response.json();
        }
        
        return await response.text();
      } catch (error) {
        throw new Error(`Request failed: ${error.message}`);
      }
    },
    
    get(url, options = {}) {
      return this.request(url, { ...options, method: 'GET' });
    },
    
    post(url, data, options = {}) {
      return this.request(url, {
        ...options,
        method: 'POST',
        body: JSON.stringify(data)
      });
    }
  };
  
  // Storage utilities
  static storage = {
    local: {
      set(key, value) {
        try {
          localStorage.setItem(key, JSON.stringify(value));
          return true;
        } catch (error) {
          console.error('Local storage set failed:', error);
          return false;
        }
      },
      
      get(key, defaultValue = null) {
        try {
          const item = localStorage.getItem(key);
          return item ? JSON.parse(item) : defaultValue;
        } catch (error) {
          console.error('Local storage get failed:', error);
          return defaultValue;
        }
      },
      
      remove(key) {
        try {
          localStorage.removeItem(key);
          return true;
        } catch (error) {
          console.error('Local storage remove failed:', error);
          return false;
        }
      }
    }
  };
  
  // Validation utilities
  static validation = {
    isEmail(email) {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      return emailRegex.test(email);
    },
    
    isUrl(url) {
      try {
        new URL(url);
        return true;
      } catch {
        return false;
      }
    },
    
    isNumber(value) {
      return !isNaN(parseFloat(value)) && isFinite(value);
    }
  };
  
  // Format utilities
  static format = {
    currency(amount, currency = "USD", locale = "en-US") {
      return new Intl.NumberFormat(locale, {
        style: "currency",
        currency: currency
      }).format(amount);
    },
    
    bytes(bytes) {
      if (bytes === 0) return "0 Bytes";
      
      const k = 1024;
      const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
      const i = Math.floor(Math.log(bytes) / Math.log(k));
      
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
    }
  };
  
  // Device detection
  static device = {
    isMobile() {
      return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
    },
    
    isIOS() {
      return /iPad|iPhone|iPod/.test(navigator.userAgent);
    },
    
    isAndroid() {
      return /Android/.test(navigator.userAgent);
    }
  };
}

// Usage examples
ComprehensiveUtils.storage.local.set('user', { name: 'John', age: 25 });
console.log(ComprehensiveUtils.storage.local.get('user'));

console.log(ComprehensiveUtils.validation.isEmail('test@example.com')); // true
console.log(ComprehensiveUtils.format.currency(1234.56)); // "$1,234.56"
console.log(ComprehensiveUtils.format.bytes(1024)); // "1 KB"
console.log(ComprehensiveUtils.device.isMobile());

Summary

Key points of JavaScript libraries:

  1. Basic Concepts: Pre-written code collections that solve specific problems
  2. Common Libraries: Lodash, Day.js, Axios, D3.js, Three.js, etc.
  3. Selection Criteria: Functionality, performance, stability, community support, etc.
  4. Usage Methods: npm installation, on-demand loading, Tree Shaking optimization
  5. Custom Libraries: Create your own utility library to meet specific needs
  6. Management Optimization: Package management, performance optimization, code splitting
  7. Practical Applications: Comprehensive utility libraries, project scaffolding, etc.

Using JavaScript libraries wisely can greatly improve development efficiency, but be careful not to over-rely on them. Choose appropriate libraries based on project requirements. In the next chapter, we will learn about JavaScript learning resources.

Content is for learning and research only.