@sanjeed5/esbuild
This rule provides comprehensive best practices for using esbuild, focusing on performance, code organization, and security in build configurations and development workflows.
prpm install @sanjeed5/esbuild0 total downloads
š Full Prompt Content
# esbuild Best Practices
This document outlines best practices for using esbuild as a JavaScript bundler. It covers various aspects, including code organization, performance optimization, security considerations, and common pitfalls to avoid.
## Library Information:
- Name: esbuild
- Tags: build-tool, javascript, bundler, performance
## 1. Code Organization and Structure
### 1.1. Directory Structure Best Practices
- **Source Code Directory (`src`):** House all your source code within a `src` directory. This promotes a clear separation of concerns between your source and build artifacts.
- **Configuration Files (`config` or `.config`):** Store esbuild configuration files (e.g., `esbuild.config.js`, `build.js`) in a dedicated `config` or `.config` directory. This makes it easy to identify and manage build-related settings.
- **Assets Directory (`assets`):** Place static assets like images, fonts, and other non-code files in an `assets` directory. This keeps them separate from your code and simplifies asset management.
- **Output Directory (`dist` or `build`):** esbuild commonly uses `dist` or `build` directories for storing the bundled output. Configure esbuild to output to one of these standard directories.
Example:
project-root/
āāā src/
ā āāā components/
ā ā āāā MyComponent.tsx
ā ā āāā ...
ā āāā utils/
ā ā āāā helpers.ts
ā ā āāā ...
ā āāā index.tsx
ā āāā ...
āāā config/
ā āāā esbuild.config.js
ā āāā ...
āāā assets/
ā āāā images/
ā ā āāā logo.png
ā ā āāā ...
ā āāā fonts/
ā ā āāā OpenSans.woff2
ā ā āāā ...
āāā dist/
ā āāā bundle.js
ā āāā styles.css
ā āāā ...
āāā package.json
āāā tsconfig.json
āāā ...
### 1.2. File Naming Conventions
- **Consistent Case:** Use either camelCase or PascalCase for JavaScript/TypeScript files, but consistently within your project. PascalCase is generally preferred for React components.
- **Descriptive Names:** Choose names that clearly reflect the file's purpose (e.g., `userProfile.tsx`, `apiClient.ts`).
- **Module-Specific Names:** If a file exports a single primary entity (e.g., a React component), use the same name for the file (e.g., `MyComponent.tsx` exports `MyComponent`).
- **CSS Modules:** Use `.module.css` or `.module.scss` for CSS Modules to scope styles locally to a component.
- **Configuration Files:** use `esbuild.config.js` or `build.js` for esbuild's configuration to make it easily identifiable.
### 1.3. Module Organization Best Practices
- **Feature-Based Modules:** Organize code by feature or functionality. Each feature should have its own directory containing all related code (components, utils, styles, etc.).
- **Reusable Modules:** Extract reusable code into separate modules (e.g., utility functions, API clients). Place these modules in a `utils` or `services` directory.
- **Avoid Circular Dependencies:** Circular dependencies can lead to unexpected behavior and bundling issues. Use tools like `madge` to detect and eliminate them.
- **Explicit Exports:** Be explicit about what you export from each module using `export` statements. This improves code clarity and tree-shaking.
### 1.4. Component Architecture Recommendations
- **Component-Based Architecture:** Adopt a component-based architecture (e.g., using React, Vue, or Svelte). This promotes code reusability, testability, and maintainability.
- **Atomic Design:** Consider using the Atomic Design methodology to structure components into atoms, molecules, organisms, templates, and pages.
- **Separation of Concerns:** Separate presentation logic (UI) from business logic (data fetching, state management). Use techniques like custom hooks to extract and reuse business logic.
### 1.5. Code Splitting Strategies
- **Dynamic Imports:** Use dynamic imports (`import()`) to load code on demand. This can significantly reduce the initial bundle size and improve page load performance. esbuild supports dynamic imports out of the box.
- **Route-Based Splitting:** Split your application into separate bundles for each route or page. This ensures that users only download the code they need for the current page.
- **Vendor Splitting:** Separate vendor libraries (e.g., React, Lodash) into a separate bundle. This allows browsers to cache vendor code separately from your application code.
- **Entry Points:** Create multiple entry points for distinct parts of your application (e.g. a landing page vs. an admin panel). esbuild will bundle these into separate output files.
## 2. Common Patterns and Anti-patterns
### 2.1. Design Patterns
- **Module Pattern:** Use the module pattern to encapsulate code and create private variables and functions.
- **Factory Pattern:** Use factory functions to create objects or components. This allows you to abstract the creation process and easily configure objects with different options.
- **Higher-Order Components (HOCs):** (React-specific) Use HOCs to add functionality to existing components.
- **Custom Hooks:** (React-specific) Use custom hooks to extract and reuse stateful logic.
### 2.2. Recommended Approaches for Common Tasks
- **Environment Variables:** Use environment variables to configure your application for different environments (development, staging, production). Access environment variables using `process.env`.
- **Path Aliases:** Configure path aliases to simplify imports. For example, you can alias `@components` to `src/components`. esbuild can be configured to understand these aliases.
- **CSS Preprocessing:** Integrate CSS preprocessors like Sass or Less using esbuild plugins. This allows you to use features like variables, mixins, and nesting in your CSS.
- **Minification and Tree Shaking:** Always enable minification and tree shaking for production builds to reduce bundle size. esbuild does this automatically with the `--minify` flag.
### 2.3. Anti-patterns and Code Smells
- **Global Variables:** Avoid using global variables as they can lead to naming conflicts and make it difficult to reason about your code.
- **Long Component Files:** Break down large component files into smaller, more manageable components.
- **Deeply Nested Components:** Avoid deeply nested component structures as they can make it difficult to understand the component hierarchy.
- **Over-reliance on `any`:** In TypeScript, avoid using `any` excessively as it defeats the purpose of type checking. Use more specific types whenever possible.
- **Direct DOM Manipulation (in React/Vue):** Avoid directly manipulating the DOM. Rely on the framework's virtual DOM for efficient updates.
### 2.4. State Management Best Practices
- **Component State:** Use component state (e.g., `useState` in React) for simple, localized state management.
- **Context API:** (React-specific) Use the Context API to share state between components without prop drilling.
- **Redux/Zustand/Recoil:** Use a state management library like Redux, Zustand, or Recoil for more complex application state.
- **Immutability:** Maintain immutability when updating state to avoid unexpected side effects and improve performance (especially with React).
### 2.5. Error Handling Patterns
- **Try-Catch Blocks:** Use `try-catch` blocks to handle synchronous errors.
- **Async/Await Error Handling:** Use `try-catch` blocks with `async/await` to handle asynchronous errors.
- **Error Boundaries:** (React-specific) Use error boundaries to catch errors that occur during rendering and prevent the entire application from crashing.
- **Centralized Error Logging:** Implement a centralized error logging system to track errors in your application.
## 3. Performance Considerations
### 3.1. Optimization Techniques
- **Minification:** Use esbuild's built-in minification (`--minify`) to reduce the size of your JavaScript and CSS files.
- **Tree Shaking:** esbuild automatically performs tree shaking to remove unused code. Ensure that your code is written in a way that allows for efficient tree shaking (e.g., using ES modules with explicit exports).
- **Code Splitting:** Implement code splitting using dynamic imports and route-based splitting to reduce the initial bundle size.
- **Image Optimization:** Optimize images using tools like ImageOptim or TinyPNG to reduce their file size.
- **Caching:** Configure your server to cache static assets (JavaScript, CSS, images) to improve loading times for returning users.
- **Compression:** Enable gzip or Brotli compression on your server to reduce the size of files transmitted over the network.
- **Target Specific Environments:** Use the `target` option to specify the target JavaScript environment. This allows esbuild to generate code that is optimized for the specific environment.
- **Incremental Builds:** Utilize esbuild's `--watch` option and the context API for incremental builds, which significantly speeds up development by only recompiling changed files.
### 3.2. Memory Management
- **Avoid Memory Leaks:** Be mindful of memory leaks, especially in long-running applications. Remove event listeners and clear timers when they are no longer needed.
- **Use WeakRefs:** Consider using `WeakRef` in situations where you need to hold a reference to an object without preventing it from being garbage collected.
- **Profile Your Code:** Use browser developer tools to profile your code and identify memory bottlenecks.
### 3.3. Rendering Optimization (If Applicable)
- **Virtualization:** Use virtualization techniques (e.g., `react-window`, `react-virtualized`) to efficiently render large lists or tables.
- **Debouncing and Throttling:** Use debouncing and throttling to limit the frequency of expensive operations, such as event handlers or API calls.
- **Memoization:** Use memoization techniques (e.g., `React.memo`, `useMemo`) to cache the results of expensive calculations.
### 3.4. Bundle Size Optimization
- **Analyze Bundle Size:** Use tools like `esbuild-visualizer` or `webpack-bundle-analyzer` to analyze your bundle size and identify large dependencies.
- **Reduce Dependency Size:** Look for opportunities to reduce the size of your dependencies. Consider using smaller alternatives or only importing the specific parts of a library that you need.
- **Remove Dead Code:** Ensure that tree shaking is working effectively to remove unused code.
### 3.5. Lazy Loading Strategies
- **Lazy-Load Components:** Use dynamic imports to lazy-load components that are not immediately needed.
- **Lazy-Load Images:** Use lazy-loading for images that are below the fold to improve initial page load time.
## 4. Security Best Practices
### 4.1. Common Vulnerabilities and Prevention
- **Cross-Site Scripting (XSS):** Prevent XSS attacks by properly escaping user input and using a Content Security Policy (CSP).
- **Injection Attacks:** Prevent injection attacks (e.g., SQL injection, command injection) by validating and sanitizing user input.
- **Dependency Vulnerabilities:** Regularly audit your dependencies for known vulnerabilities using tools like `npm audit` or `yarn audit`. Update to the latest versions of your dependencies to patch vulnerabilities.
### 4.2. Input Validation
- **Validate All Input:** Validate all user input, both on the client-side and the server-side.
- **Use Strong Validation Rules:** Use strong validation rules to ensure that input is in the expected format and range.
- **Sanitize Input:** Sanitize input to remove potentially malicious characters or code.
### 4.3. Authentication and Authorization
- **Use Strong Authentication:** Use strong authentication methods, such as multi-factor authentication (MFA).
- **Implement Proper Authorization:** Implement proper authorization to ensure that users only have access to the resources they are authorized to access.
- **Securely Store Credentials:** Securely store user credentials using hashing and salting.
### 4.4. Data Protection
- **Encrypt Sensitive Data:** Encrypt sensitive data both in transit and at rest.
- **Use HTTPS:** Use HTTPS to encrypt communication between the client and the server.
- **Protect API Keys:** Protect API keys and other sensitive configuration data by storing them in environment variables or a secure configuration store.
### 4.5. Secure API Communication
- **Use HTTPS:** Always use HTTPS for API communication.
- **Validate API Responses:** Validate API responses to ensure that they are in the expected format.
- **Implement Rate Limiting:** Implement rate limiting to prevent abuse of your API.
## 5. Testing Approaches
### 5.1. Unit Testing
- **Test Individual Components:** Unit tests should focus on testing individual components or modules in isolation.
- **Use Mocking and Stubbing:** Use mocking and stubbing to isolate the component under test from its dependencies.
- **Test Edge Cases:** Test edge cases and error conditions to ensure that the component handles them correctly.
### 5.2. Integration Testing
- **Test Interactions Between Components:** Integration tests should focus on testing the interactions between different components or modules.
- **Test API Integrations:** Test integrations with external APIs to ensure that they are working correctly.
### 5.3. End-to-End Testing
- **Test User Flows:** End-to-end tests should simulate user flows to ensure that the application is working correctly from the user's perspective.
- **Use a Testing Framework:** Use a testing framework like Cypress or Playwright to automate end-to-end tests.
### 5.4. Test Organization
- **Co-locate Tests with Code:** Store test files in the same directory as the code they are testing.
- **Use Descriptive Test Names:** Use descriptive test names to clearly indicate what each test is verifying.
### 5.5. Mocking and Stubbing
- **Use a Mocking Library:** Use a mocking library like Jest or Sinon to create mocks and stubs.
- **Mock External Dependencies:** Mock external dependencies, such as API calls or database connections.
- **Stub Function Behavior:** Stub the behavior of functions to control their return values or side effects.
## 6. Common Pitfalls and Gotchas
### 6.1. Frequent Mistakes
- **Forgetting to Bundle:** Failing to enable bundling can result in performance issues due to multiple HTTP requests.
- **Not Minifying:** Not minifying your code will result in larger file sizes and slower loading times.
- **Incorrect `tsconfig.json` Configuration:** Incorrectly configuring your `tsconfig.json` file can lead to compilation errors or unexpected behavior.
- **Not Handling Environment Variables:** Failing to properly handle environment variables can result in incorrect configuration in different environments.
- **Not Using Path Aliases:** Not using path aliases can make imports more verbose and difficult to maintain.
### 6.2. Edge Cases
- **Circular Dependencies:** Circular dependencies can lead to unexpected behavior and bundling issues.
- **Dynamic Imports with Variable Paths:** esbuild's support for dynamic imports with variable paths is limited. Be aware of the restrictions and consider alternative approaches if needed.
- **Plugin Compatibility:** Ensure that plugins are compatible with the version of esbuild you are using.
### 6.3. Version-Specific Issues
- **Breaking Changes:** Be aware of breaking changes in new versions of esbuild. Consult the release notes before upgrading.
### 6.4. Compatibility Concerns
- **Browser Compatibility:** Ensure that your code is compatible with the target browsers. Use Babel or other transpilers if necessary.
- **Node.js Compatibility:** If you are building a Node.js application, ensure that your code is compatible with the target version of Node.js.
### 6.5. Debugging Strategies
- **Source Maps:** Enable source maps to make it easier to debug your code in the browser developer tools.
- **Console Logging:** Use `console.log` statements to debug your code.
- **Debugger Statements:** Use `debugger` statements to pause execution at specific points in your code.
## 7. Tooling and Environment
### 7.1. Recommended Development Tools
- **VS Code:** A popular code editor with excellent support for JavaScript, TypeScript, and esbuild.
- **ESLint:** A linter for JavaScript and TypeScript that can help you identify and fix code quality issues.
- **Prettier:** A code formatter that can automatically format your code to a consistent style.
- **esbuild-visualizer:** A tool to visualize the contents of your esbuild bundle.
### 7.2. Build Configuration Best Practices
- **Use a Configuration File:** Store your esbuild configuration in a dedicated configuration file (e.g., `esbuild.config.js`).
- **Separate Configurations for Different Environments:** Create separate configurations for different environments (development, staging, production).
- **Use Environment Variables:** Use environment variables to configure your build process.
### 7.3. Linting and Formatting
- **Configure ESLint:** Configure ESLint to enforce coding style and identify potential errors.
- **Use Prettier:** Use Prettier to automatically format your code to a consistent style.
- **Integrate Linting and Formatting into Your Workflow:** Integrate linting and formatting into your development workflow using tools like Husky or lint-staged.
### 7.4. Deployment
- **Use a Build Process:** Use a build process to bundle, minify, and optimize your code before deployment.
- **Deploy to a CDN:** Deploy static assets to a content delivery network (CDN) for faster loading times.
- **Use HTTPS:** Always use HTTPS to encrypt communication between the client and the server.
### 7.5. CI/CD Integration
- **Automate Build and Testing:** Automate your build and testing process using a continuous integration and continuous delivery (CI/CD) pipeline.
- **Run Linting and Formatting Checks:** Run linting and formatting checks as part of your CI/CD pipeline.
- **Deploy Automatically:** Automate the deployment process to deploy new versions of your application automatically.
This comprehensive guide provides a solid foundation for using esbuild effectively. Remember to adapt these best practices to your specific project needs and continuously learn as the esbuild ecosystem evolves.š” Suggested Test Inputs
Loading suggested inputs...
šÆ Community Test Results
Loading results...
š¦ Package Info
- Format
- cursor
- Type
- rule
- Category
- cursor-rules
- License
- CC0-1.0