Dojo Framework

repository·master·Indexed 20 days ago

https://github.com/dojo/framework

A progressive TypeScript framework for building modern web applications. It features a reactive unidirectional data flow, a Virtual DOM (vdom) paradigm with VNodes and WNodes, and a comprehensive ecosystem including routing, state management (@dojo/stores), internationalization (@dojo/i18n), and specialized CLI tooling for application and widget development.

Tokens
107.6K
Snippets
339
Records
431
Agent score
69%

What's inside @dojo/framework

  1. Overview of @dojo/framework sub-packages

    master

    The @dojo/framework core is composed of seven primary sub-packages that provide the foundation for building Dojo applications:

    • dojo/core: The foundational code of the Dojo framework.
    • dojo/has: A feature detection library.
    • dojo/i18n: Internationalization tooling.
    • dojo/routing: A routing service for web applications.
    • dojo/shim: Modules providing fills for ES6+ functionality.
    • dojo/stores: A lightweight state container.
    • dojo/testing: Modules for testing Dojo applications.
  2. Overview of the Dojo framework capabilities

    master

    Dojo is a modular web application framework designed to scale from simple pre-rendered websites to enterprise-scale single-page applications (SPAs) and Progressive Web Apps (PWAs). It provides a holistic ecosystem including framework components, tooling, and a build pipeline to address end-to-end development concerns.

    Key capabilities include:

    Application Management

    • Widget-based architecture: Build complex requirements by assembling simple, modular widgets.
    • Reactive state management: Connect widgets using reactive data flows for efficient rendering updates.
    • Centralized data stores: Use command-oriented data stores for advanced state management.
    • Declarative routing: Implement SPA navigation with history support.
    • Feature toggling: Disable developing features and elide unused modules at build time to minimize delivery size.

    Performance and Efficiency

    • Virtualized DOM (VDOM): Avoid costly DOM operations and layout thrashing by declaring widget structures through a VDOM.
    • Resource layering and bundling: Minimize Time-to-Interactive (TTI) via optimized bundling. The framework automatically converts imports to lazy-loaded modules when they cross bundle boundaries.

    Global and Adaptable Features

    • Theming and UI: Develop themeable widgets and use a suite of UI widgets that support internationalization (i18n), accessibility (a11y), and theming out-of-the-box.
    • Internationalization: Support multiple locales and advanced message formatting via Unicode CLDR.
    • Progressive Web Apps (PWA): Implement offline usage, background data syncing, and push notifications.
    • Build-time rendering (BTR): Provide pre-rendering benefits (similar to SSR) for static websites or progressive hydration without requiring a dynamic web server.
    • Modern Web APIs: Consistent support for Web Animations, Intersection Observers, and Resize Observers.

    Developer Experience

    • Dojo CLI: Bootstrap projects, perform builds, and run validation using a type-safe, opinionated CLI.
    • Scaffolding: Quickly scaffold custom widgets and custom themes.
  3. Overview of @dojo/framework/stores

    master

    The @dojo/framework/stores package provides a predictable, consistent state container for JavaScript applications. It is designed as a single source of truth using a uni-directional data flow, inspired by Redux and Flux architectures.

    Key features include:

    • Designed for reactive component architectures.
    • Built-in support for asynchronous commands.
    • State operations are recorded per process, enabling undo/redo via middleware.
    • Support for the optimistic update pattern with rollback capabilities.
    • Fully serializable state and operations.
  4. Overview of @dojo/framework core

    master

    The @dojo/framework core is a library designed for building powerful, composable user interface widgets. It is built on several key architectural pillars:

    • Reactive & Unidirectional Data Flow: Follows reactive principles to ensure predictable and consistent UI behavior.
    • Encapsulated Widgets: Allows the creation of independent widgets that can be wired together to form complex interfaces.
    • DOM Abstractions: Provides APIs that abstract away direct DOM manipulation, encouraging developers to work within the reactive render lifecycle instead of accessing the DOM directly.
    • I18n & Themes: Includes built-in mixins to support internationalization and theming out of the box.
  5. Overview of @dojo/framework/shim features

    master

    The shim package provides implementations for various ECMAScript features, often falling back to native implementations if available in the environment. Key modules include:

    • Array: Utilities via @dojo/framework/shim/array.
    • Data Structures: Map, Set, and WeakMap (note: Map and WeakMap implementations do not include iterators for compatibility with older browsers).
    • Iterators: ES2015 Iterator specification via @dojo/framework/shim/iterator.
    • Math: Math methods via @dojo/framework/shim/math.
    • Number: Number methods via dojo/shim/number.
    • Object: Object methods via dojo/shim/object.
    • Observables: Implementation of the proposed Observable specification via @dojo/framework/shim/Observable.
    • Promises: ES2015 Promise specification via @dojo/framework/shim/Promise.
    • String: String methods via @dojo/framework/shim/string.
    • Symbols: ES2015 Symbol specification via @dojo/framework/shim/Symbol.
  6. What is Middleware in Dojo Stores

    master

    Middleware provides a hook to apply generic or global functionality across multiple or all processes used within an application. A middleware is a function that returns an object containing optional before and after callback functions.

    When multiple middlewares are provided to a process:

    1. All before callbacks are executed in the order they were provided.
    2. The process itself runs.
    3. All after callbacks are executed in the order they were provided.
  7. What is Build-time rendering (BTR)?

    master
    Build-time rendering (BTR) renders a route to HTML during the build process and in-lines critical CSS and assets needed to display the initial view. This provides performance gains and SEO benefits similar to Server Side Rendering (SSR) without the operational complexity of running a server to render HTML.
  8. What is render middleware in Dojo?

    master

    Dojo render middleware bridges the gap between reactive, functional widgets and the underlying imperative DOM. It allows widgets to access DOM-related information (like element size for responsive UIs or viewport visibility for lazy-loading) or handle generic rendering lifecycle concerns (like caching data, pausing/resuming rendering, or marking a widget as invalid for re-rendering).

    Middleware provides advanced control over how a widget is represented and how it interacts with the browser. If a widget accesses middleware properties before the DOM elements exist, Dojo returns sensible defaults. Some middleware can even pause a widget's rendering until specific conditions are met, automatically re-rendering the widget once those conditions are satisfied.

  9. What is an Observable and how to use it

    master

    The @dojo/framework/shim/Observable class implements the proposed Observable specification to simplify push-based data sources like events, timed events, or sockets.

    An Observable is a producer of values. When you subscribe to an Observable, you provide handlers to react to new values, errors, or the completion of the stream. A key characteristic is that resources (like timers) are typically managed per subscriber; if there are no subscribers, the Observable does not perform its work. To prevent memory leaks or unwanted background tasks, you should use the Subscription object returned by subscribe to call unsubscribe().

    const timedObservable = new Observable((observer) => {
    	let handle = null;
    
    	function timer() {
    		observer.next();
    		handle = setTimeout(timer, 1000);
    	}
    
    	handle = setTimeout(timer, 1000);
    
    	return () => {
    		clearTimeout(handle);
    	};
    });
    
    let seconds = 0;
    const subscription = timedObservable.subscribe(() => {
    	seconds++;
    	if (seconds >= 5) {
    		subscription.unsubscribe();
    	}
    });
  10. What is Dojo middleware and how does it work?

    master

    Dojo's middleware system allows you to manage asynchronous or imperative APIs reactively. It is used to influence the behavior and property API of function-based widgets.

    Key capabilities include:

    • Reactive DOM access: Allowing function-based widgets to interact with specific DOM sections.
    • Widget render lifecycle control: Controlling the rendering pipeline, such as invalidating widgets for updates or pausing/resuming rendering.
    • Framework-provided functionality: Built-in middleware for focus management, value caching, intersection/resize events, CSS theming, internationalization, and more.
    • Composition: Middleware is designed to be composed easily within widget hierarchies.
  11. How to use Virtual DOM keys correctly

    master

    To ensure efficient DOM updates and prevent unnecessary re-renders, follow these rules for Virtual DOM keys:

    • Maintain consistency: keys must be consistent across multiple render calls. If a key changes on every render, Dojo cannot associate the new node with the previous one. This causes Dojo to remove the old element and insert an entirely new one, even if no other properties changed.
    • Avoid random keys: Do not assign randomly-generated IDs (like GUIDs or UUIDs) as a node's key within a widget's render function. A key should only be generated within a render function if the generation strategy is idempotent (produces the same result every time for the same input).
  12. State management strategies in Dojo

    master

    Dojo supports different levels of state management depending on application complexity:

    1. Basic (Self-encapsulated): For simple apps, encapsulate data directly within the individual widgets that need it.
    2. Intermediate (Reactive/Property-based): For data flowing between components, wire widgets and properties together in the render function. This allows Dojo to manage change detection and re-rendering reactively.
    3. Large-scale (Dojo Stores): For complex applications requiring centralized state, use the Dojo Stores component. It provides a consistent API for accessing and managing data from multiple locations across the application.