# Spanish translations for PACKAGE package
# Traducciones al español para el paquete PACKAGE
# Copyright (C) 2023 Free Software Foundation, Inc.
# This file is distributed under the same license as the PACKAGE package.
# Automatically generated, 2023.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2023-07-25 20:53+0300\n"
"PO-Revision-Date: 2023-07-25 20:53+0300\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. type: Title =
#: src/en/modules/ROOT/pages/best-practices.adoc:1
#, no-wrap
msgid "Designing Your Application for Module Federation: Best Practices and Tips"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:2
msgid ""
"Module Federation is a powerful tool for sharing modules between multiple "
"applications, but designing your application to take advantage of this "
"feature requires careful planning and consideration. In this guide, we'll "
"explore some best practices and tips for designing your application to more "
"easily use Module Federation."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/best-practices.adoc:3
#, no-wrap
msgid "Modular Application Architecture"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:4
msgid ""
"One of the most important considerations when designing an application for "
"Module Federation is the architecture of the application itself. "
"Applications that are designed with a modular architecture are better suited "
"for sharing modules using Module Federation."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:5
msgid ""
"A modular architecture involves breaking down an application into smaller, "
"more manageable modules. Each module should have a well-defined set of "
"responsibilities and should be designed to be as self-contained as possible. "
"By designing an application in this way, modules can be more easily shared "
"between different applications using Module Federation."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/best-practices.adoc:6
#, no-wrap
msgid "Versioning and Compatibility"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:7
msgid ""
"When sharing modules between different applications, it is important to "
"ensure that those modules are compatible with each other. This requires "
"careful versioning and compatibility testing to ensure that changes to one "
"module do not break other applications that rely on it."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:8
msgid ""
"To ensure compatibility between shared modules, it is important to establish "
"a clear xref:versioned-shared-modules.adoc[versioning strategy]. This "
"strategy should define how versions are numbered, how backwards "
"compatibility is maintained, and how changes to modules are communicated to "
"other applications that rely on them."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:9
msgid ""
"To learn more about versioning of modules, proceed to dedicated xref:"
"versioned-shared-modules.adoc[Versioned Shared Modules] documentation page."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/best-practices.adoc:10
#, no-wrap
msgid "Code Organization and Structure"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:11
msgid ""
"To more easily use Module Federation, it is important to structure your code "
"in a way that is well-suited to sharing modules. This involves organizing "
"your code into modules and packages that can be more easily shared between "
"different applications."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:12
msgid ""
"In addition to organizing code into modules and packages, it is important to "
"establish clear boundaries between different modules. This can be achieved "
"through the use of well-defined interfaces and APIs, which allow different "
"modules to communicate with each other in a standardized way."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/best-practices.adoc:13
#, no-wrap
msgid "Dependency Management"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:14
msgid ""
"Effective dependency management is critical for designing an application "
"that is well-suited for Module Federation. This involves carefully managing "
"dependencies between modules to ensure that they can be easily shared "
"between different applications."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:15
msgid ""
"To more easily manage dependencies between modules, it is important to "
"establish a clear dependency hierarchy. This hierarchy should define the "
"relationships between different modules and should be designed to minimize "
"dependencies between modules wherever possible."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/best-practices.adoc:16
#, no-wrap
msgid "Communication Protocols"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:17
msgid ""
"When sharing modules between different applications, it is important to "
"establish clear communication protocols. This involves defining how "
"different modules communicate with each other, and how data is passed "
"between different applications."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:18
msgid ""
"To establish clear communication protocols, it is important to standardize "
"interfaces and APIs. This allows different modules to communicate with each "
"other in a consistent and predictable way, which can help to reduce errors "
"and improve maintainability."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/best-practices.adoc:19
#, no-wrap
msgid "Testability"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:20
msgid ""
"To more easily use Module Federation, it is important to design your "
"application with testability in mind. This involves designing modules and "
"packages that can be easily tested in isolation, as well as designing tests "
"that can be easily run against shared modules."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:21
msgid ""
"By designing modules and packages that are easily testable, developers can "
"more easily ensure that changes to those modules do not break other "
"applications that rely on them. This can help to reduce the risk of errors "
"and improve the overall quality of the application."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:22
msgid ""
"To learn more about testing of modules, proceed to dedicated xref:unit-"
"testing.adoc[How to Create Unit Tests for Distributed Code] documentation "
"page."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/best-practices.adoc:23
#, no-wrap
msgid "Security"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:24
msgid ""
"When sharing modules between different applications, it is important to "
"consider security implications. This involves designing modules and packages "
"that are secure by default, as well as implementing security measures to "
"protect shared modules from unauthorized access or modification."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:25
msgid ""
"To ensure the security of shared modules, it is important to establish clear "
"access control policies. This involves defining who has access to shared "
"modules, as well as implementing authentication and authorization mechanisms "
"to control access to those modules."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/best-practices.adoc:26
#, no-wrap
msgid "Monitoring and Metrics"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:27
msgid ""
"To more easily use Module Federation, it is important to design your "
"application with monitoring and metrics in mind. This involves designing "
"modules and packages that can be easily monitored, as well as designing "
"monitoring tools that can be used to track the performance of shared modules."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:28
msgid ""
"By designing modules and packages that are easily monitorable, developers "
"can more easily identify performance issues and other problems that may "
"affect the overall quality of the application. This can help to improve the "
"overall reliability and performance of the application."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:29
msgid ""
"To get more visibility of your federated modules, we suggest using https://"
"www.medusa.codes/[Medusa]. Medusa provides visibility of tracking how every "
"new feature update influences the performance, compare current, historical, "
"and the upcoming version, discover insights, and take-data driven decisions."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/best-practices.adoc:30
#, no-wrap
msgid "Performance"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:31
msgid ""
"To more easily use Module Federation, it is important to design your "
"application with performance in mind. This involves designing modules and "
"packages that are optimized for performance, as well as designing tools that "
"can be used to monitor and optimize the performance of shared modules."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:32
msgid ""
"By designing modules and packages that are optimized for performance, "
"developers can ensure that shared modules do not negatively impact the "
"performance of the overall application. This can help to improve the user "
"experience and ensure that the application can scale to meet increasing "
"demand."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/best-practices.adoc:33
#, no-wrap
msgid "Error Handling"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:34
msgid ""
"When sharing modules between different applications, it is important to "
"consider error handling. This involves designing modules and packages that "
"are robust and resilient to errors, as well as designing error handling "
"mechanisms to handle errors that occur in shared modules."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:35
msgid ""
"To ensure that errors are handled effectively, it is important to establish "
"clear error handling guidelines. This involves defining how errors should be "
"logged and reported, as well as defining how errors should be handled in "
"different contexts."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/best-practices.adoc:36
#, no-wrap
msgid "Documentation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:37
msgid ""
"To more easily use Module Federation, it is important to document shared "
"modules and their APIs. This involves designing clear and comprehensive "
"documentation for shared modules, as well as ensuring that the documentation "
"is kept up-to-date as shared modules evolve over time."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:38
msgid ""
"By designing clear and comprehensive documentation for shared modules, "
"developers can more easily understand how different modules communicate with "
"each other, and how data is passed between different applications. This can "
"help to reduce errors and improve maintainability."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/best-practices.adoc:39
#: src/en/modules/ROOT/pages/brown-green.adoc:36
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:38
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:193
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:102
#: src/en/modules/ROOT/pages/delegate-modules.adoc:59
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:55
#: src/en/modules/ROOT/pages/getting-started.adoc:10
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:81
#: src/en/modules/ROOT/pages/mf-ssr.adoc:8
#: src/en/modules/ROOT/pages/mf-ssr.adoc:49
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:58
#: src/en/modules/ROOT/pages/pros-cons.adoc:23
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:44
#: src/en/modules/ROOT/pages/shared-api.adoc:54
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:84
#: src/en/modules/ROOT/pages/unit-testing.adoc:59
#: src/en/modules/ROOT/pages/use-cases.adoc:15
#, no-wrap
msgid "Conclusion"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/best-practices.adoc:40
msgid ""
"Designing an application to more easily use Module Federation requires "
"careful planning and consideration. By adopting a modular architecture, "
"establishing clear versioning and compatibility strategies, organizing code "
"effectively, and managing dependencies, developers can create applications "
"that are well-suited for sharing modules between different applications "
"using Module Federation. By following these best practices and tips, "
"developers can take full advantage of the power and flexibility of Module "
"Federation to create more modular and flexible web applications."
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/brown-green.adoc:1
#, no-wrap
msgid "Brownfield vs. Greenfield Development with Module Federation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:2
msgid ""
"In this documentation page, we'll explore two different approaches to "
"implementing Module Federation in your projects: Brownfield and Greenfield "
"development. This guide is intended for advanced users and will provide a "
"thorough understanding of the differences, advantages, and drawbacks of each "
"approach."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/brown-green.adoc:3
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:3
#, no-wrap
msgid "Overview"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:4
msgid ""
"Module Federation is a powerful tool in Webpack 5 that enables you to share "
"dependencies and modules across applications, providing significant "
"performance improvements and enabling the creation of distributed "
"applications."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:5
msgid ""
"When considering implementing Module Federation in your projects, you'll "
"often come across two primary development approaches depending on the state "
"of your current project:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:6
msgid ""
"Brownfield Development: Integrating Module Federation into an existing "
"application."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:7
msgid ""
"Greenfield Development: Building a new application from scratch with Module "
"Federation in mind."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:8
msgid ""
"This guide aims to provide an in-depth understanding of both development "
"strategies to help you make an informed decision on whether to start from "
"scratch, or lean more towards a refactoring-way."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/brown-green.adoc:9
#, no-wrap
msgid "Brownfield Development with Module Federation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:10
msgid ""
"Brownfield development refers to integrating Module Federation into an "
"existing application. This can be a complex process, as it may involve "
"refactoring existing code and adapting your application's architecture to "
"work with Module Federation."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/brown-green.adoc:11
#: src/en/modules/ROOT/pages/brown-green.adoc:25
#, no-wrap
msgid "Advantages"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:12
msgid ""
"Leverage existing code and resources: You can continue building on your "
"existing application, without needing to start from scratch."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:13
msgid ""
"Incremental improvements: You can gradually introduce Module Federation into "
"your application, improving performance and code sharing over time."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/brown-green.adoc:14
#: src/en/modules/ROOT/pages/brown-green.adoc:29
#, no-wrap
msgid "Challenges"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:15
msgid ""
"Refactoring existing code: You may need to refactor parts of your existing "
"application to accommodate Module Federation. This can be time-consuming and "
"may introduce temporary instability."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:16
msgid ""
"Potential architectural changes: Your existing application architecture "
"might not be optimized for Module Federation, which may require significant "
"changes to fully leverage its potential."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:17
msgid ""
"Dependency management: Ensuring consistency and compatibility across shared "
"dependencies can be challenging in Brownfield projects, as different parts "
"of the application may rely on various dependency versions."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/brown-green.adoc:18
#: src/en/modules/ROOT/pages/brown-green.adoc:32
#, no-wrap
msgid "Best Practices"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:19
msgid ""
"Analyze your existing application: Identify the areas that would benefit "
"most from Module Federation and prioritize them."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:20
msgid ""
"Plan your refactoring: Develop a detailed plan to refactor your application "
"and integrate Module Federation. Consider breaking the process into smaller, "
"manageable tasks."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:21
msgid ""
"Test thoroughly: Ensure you have a robust testing strategy in place to catch "
"potential issues during the refactoring process."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/brown-green.adoc:22
#, no-wrap
msgid "Refactoring Example "
msgstr ""

#. TODO:
#. type: Title ==
#: src/en/modules/ROOT/pages/brown-green.adoc:23
#, no-wrap
msgid "Greenfield Development with Module Federation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:24
msgid ""
"Greenfield development refers to building a new application from scratch, "
"with Module Federation in mind from the beginning. This approach allows you "
"to design and architect your application to take full advantage of Module "
"Federation's capabilities."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:26
msgid ""
"Optimized architecture: Design your application architecture to fully "
"leverage Module Federation from the start, maximizing its benefits."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:27
msgid ""
"Easier dependency management: Plan and manage dependencies with Module "
"Federation in mind, ensuring compatibility and consistency across your "
"application."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:28
msgid ""
"Faster implementation: Since you're starting from scratch, there's no need "
"to refactor existing code, reducing potential complexity."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:30
msgid ""
"Uncertain ROI: As you're starting with a new application, it may be "
"difficult to estimate the exact return on investment (ROI) of implementing "
"Module Federation."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:31
msgid ""
"Potential for over-optimization: In an effort to fully leverage Module "
"Federation, you might over-optimize the architecture, which could lead to "
"unnecessary complexity."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:33
msgid ""
"Establish clear goals: Clearly define the objectives for your Greenfield "
"project, including the expected benefits of implementing Module Federation."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:34
msgid ""
"Design with scalability in mind: Ensure that your application architecture "
"is flexible and scalable, allowing you to take full advantage of Module "
"Federation as your project grows."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:35
msgid ""
"Maintain simplicity: Avoid over-complicating your application design to "
"maximize the benefits of Module Federation. Focus on simplicity and "
"maintainability."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:37
msgid ""
"Both Brownfield and Greenfield development approaches offer unique "
"advantages and challenges when implementing Module Federation in your "
"projects. The right choice for your project depends on your specific needs, "
"resources, and goals."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:38
msgid ""
"For existing applications that could benefit from Module Federation, "
"Brownfield development may be the most suitable approach. However, be "
"prepared for potential refactoring and architectural changes."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:39
msgid ""
"On the other hand, if you're starting a new project and want to build an "
"application optimized for Module Federation from the outset, Greenfield "
"development might be the better option. This approach allows you to create "
"an architecture that fully leverages Module Federation capabilities while "
"ensuring easier dependency management."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/brown-green.adoc:40
msgid ""
"Ultimately, the decision between Brownfield and Greenfield development "
"depends on your project's unique requirements and constraints. Carefully "
"consider the advantages and challenges of each approach and adopt best "
"practices to maximize the benefits of implementing Module Federation in your "
"applications. With a thoughtful strategy in place, you can harness the power "
"of Module Federation to create efficient, high-performance distributed "
"systems."
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:1
#, no-wrap
msgid "Module Federation: Component Level Ownership"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:2
msgid ""
"In this guide, we will delve into the concept of Component Level Ownership "
"in the context of Module Federation, a feature introduced in Webpack 5. You "
"will learn how this ownership model works, its benefits, and how to "
"implement it within your projects."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:3
#, no-wrap
msgid "Introduction to Component Level Ownership"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:4
msgid ""
"Component Level Ownership is a design pattern that allows individual "
"components to be owned, managed, and versioned independently within a "
"federated architecture. This approach empowers developers to create more "
"maintainable and scalable applications by encapsulating the logic and "
"dependencies of each component, reducing the risk of conflicts and promoting "
"better collaboration."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:5
msgid ""
"By leveraging Component Level Ownership, teams can work on different parts "
"of the application simultaneously, enabling faster development cycles and "
"increased agility."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:6
msgid ""
"A good example of this would be the `checkout` team, they own everything "
"around cart, payment, and quantities. A different team owns the `shop` "
"experience, but that app needs an \"add to cart\" modal. Before federation, "
"this meant old-school npm packages for the shared part or literally having "
"to PR some component you own in someone else's app."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:7
msgid ""
"With Module Federation this is achievable at runtime in a very convenient "
"way:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:8
#, no-wrap
msgid "import CartModal from \"checkoutTeam/components/cart-modal\"\n"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:9
#, no-wrap
msgid "Implementing Component Level Ownership"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:10
msgid ""
"To achieve Component Level Ownership, each application needs to configure "
"its Webpack Module Federation plugin with two options: `name` and `exposes`. "
"The `name` option defines the unique identifier of the application, which "
"will be used by other applications to reference it. The `exposes` option "
"defines a mapping of keys to local files that contain the components to be "
"exposed. For example:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:11
#, no-wrap
msgid ""
"new ModuleFederationPlugin({\n"
"  name: \"app1\",\n"
"  exposes: {\n"
"    \"./Heroes\": \"./src/app/heroes/heroes.component.ts\",\n"
"    \"./Villains\": \"./src/app/villains/villains.component.ts\",\n"
"  },\n"
"});\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:12
msgid ""
"This configuration tells Webpack that `app1` exposes two components: "
"`Heroes` and `Villains`, which are located in the specified files. These "
"components can be imported by other applications using the syntax `app1/"
"ComponentName`, where `app1` is the name of the application and "
"`ComponentName` is the key of the component in the `exposes` option."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:13
msgid ""
"For example, another application called `app2` can import and use the "
"`Heroes` component from `app1` like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:14
#, no-wrap
msgid "import { Heroes } from \"app1/Heroes\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:15
#, no-wrap
msgid "// use Heroes component in app2\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:16
msgid ""
"To make this work, `app2` also needs to configure its Webpack module "
"federation plugin with two options: `remotes` and `shared`. The `remotes` "
"option defines a mapping of names to URLs that point to the remote entry "
"files of other applications. The remote entry file is a special file "
"generated by Webpack that contains information about the exposed modules and "
"how to load them. The `shared` option defines which modules are shared "
"between the applications, such as vendor libraries or common dependencies."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:17
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:7
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:15
msgid "For example:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:18
#, no-wrap
msgid ""
"new ModuleFederationPlugin({\n"
"  remotes: {\n"
"    app1: \"app1@http://localhost:3000/remoteEntry.js\",\n"
"  },\n"
"  shared: [\"@angular/core\", \"@angular/common\", \"@angular/router\"],\n"
"});\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:19
msgid ""
"This configuration tells Webpack that `app2` can import modules from `app1`, "
"which has a remote entry file at the specified URL. It also tells Webpack "
"that both applications share some Angular modules, so they don't need to "
"load them twice."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:20
#, no-wrap
msgid "Benefits of Component Level Ownership"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:21
#, no-wrap
msgid "**Improved Scalability**: As your application grows, Component Level Ownership allows you to maintain a modular architecture, preventing tightly-coupled dependencies and reducing complexity by breaking down an application into smaller components, so you can better allocate resources and scale your application as needed.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:22
#, no-wrap
msgid "**Maintainability**: By encapsulating the logic and dependencies of each component, you can improve code readability and maintainability, making it easier to update and refactor components as needed. Additionally, assigning ownership to individual components simplifies the process of maintaining and updating the codebase too, as it is clear who is responsible for each component.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:23
#, no-wrap
msgid "**Team Collaboration**: Component Level Ownership enables better collaboration between teams by allowing them to work independently on their respective components, streamlining the development process and reducing the risk of conflicts.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:24
#, no-wrap
msgid "**Performance**: With dynamic imports and lazy loading, you can optimize your application's performance by only loading the required components and their dependencies as needed.\n"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:25
#, no-wrap
msgid "What are the challenges of Component Level Ownership?"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:26
msgid ""
"Component Level Ownership also comes with some challenges that need to be "
"addressed:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:27
msgid ""
"It requires careful design and documentation of the exposed components, as "
"they need to have a clear interface and contract with other applications."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:28
msgid ""
"It introduces some complexity and overhead in the configuration and "
"orchestration of the applications, as they need to know where and how to "
"find and load each other's components."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:29
msgid ""
"It may cause some compatibility issues or conflicts between different "
"versions or implementations of the same component, especially if they are "
"not properly isolated or scoped."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:30
#, no-wrap
msgid "How can we overcome these challenges?"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:31
msgid ""
"There are some best practices and tools that can help us overcome these "
"challenges and leverage Component Level Ownership effectively:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:32
msgid ""
"Use standalone components that have minimal dependencies and side effects, "
"and follow a single responsibility principle. This will make them easier to "
"expose"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:33
msgid ""
"Use SCAM (Single Component Angular Module) pattern for shared components, "
"which means creating a dedicated NgModule for each component that declares "
"and exports it. This will make them easier to import and reuse by other "
"applications."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:34
msgid ""
"Use Dynamic Module Federation to load remote components on demand, instead "
"of statically importing them. This will reduce the initial bundle size and "
"improve performance."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:35
msgid ""
"Use Angular's built-in mechanisms to isolate and scope component styles, "
"such as ViewEncapsulation and :host selector. This will prevent style "
"conflicts and leakage between components."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:36
msgid ""
"Use Angular's dependency injection system to provide services and "
"configuration to components, instead of relying on global variables or "
"constants. This will make them more testable and adaptable to different "
"environments³."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:37
msgid ""
"Use custom elements or web components to wrap standalone components and "
"expose them as standard HTML elements. This will make them interoperable "
"with other frameworks or vanilla JavaScript."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:39
msgid ""
"Component Level Ownership is a powerful concept that enables a federated "
"architecture for Angular applications. It allows each application to expose "
"and consume individual components from other applications, without requiring "
"coordination or synchronization between teams or domains. It also reduces "
"coupling and increases cohesion between applications, improves scalability "
"and performance, and enhances user experience."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:40
msgid ""
"However, Component Level Ownership also comes with some challenges that need "
"to be addressed, such as design and documentation of the exposed components, "
"configuration and orchestration of the applications, and compatibility and "
"conflict resolution between different versions or implementations of the "
"same component."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:41
msgid ""
"To overcome these challenges, there are some best practices and tools that "
"can help us leverage Component Level Ownership effectively, such as using "
"standalone components that have minimal dependencies and side effects, using "
"SCAM pattern for shared components, using Dynamic Module Federation to load "
"remote components on demand, using Angular's built-in mechanisms to isolate "
"and scope component styles, using Angular's dependency injection system to "
"provide services and configuration to components, and using custom elements "
"or web components to wrap standalone components and expose them as standard "
"HTML elements."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/component-level-ownership.adoc:42
msgid ""
"By following these best practices and tools, we can take full advantage of "
"Module Federation and Component Level Ownership in Angular applications."
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:1
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:1
#, no-wrap
msgid "Composable Commerce with Module Federation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:2
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:2
msgid ""
"Composable Commerce is a new approach to building e-commerce applications "
"that allows you to customize and extend every aspect of your online store. "
"With Composable Commerce, you can leverage best-of-breed solutions from "
"different vendors and combine them into a unified shopping experience for "
"your customers."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:3
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:3
msgid ""
"In this guide, you will learn how to use Composable Commerce and Module "
"Federation to create a modular and scalable e-commerce application. You will "
"learn see how to:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:4
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:4
msgid "Figure out Composable Commerce concept;"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:5
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:5
msgid "Benefits of Composable Commerce to e-commerce;"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:6
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:6
msgid "Define the architecture and components of your application;"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:7
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:7
msgid "Configure Webpack to enable Module Federation;"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:8
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:8
msgid "Expose and consume modules from different bundles;"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:9
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:9
msgid ""
"Implement common e-commerce features such as product catalog, cart, "
"checkout, and payment using Module Federation;"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:10
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:10
#, no-wrap
msgid "What is Composable Commerce?"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:11
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:11
msgid ""
"Composable commerce is an approach to e-commerce development that follows "
"the principles of microservices, domain-driven design and API-first design. "
"It breaks down the monolithic e-commerce application into smaller, loosely "
"coupled components that can be composed together to create a customized and "
"adaptable user experience. Each component is responsible for a specific "
"business domain or functionality, such as product catalog, shopping cart, "
"checkout, payment, etc. These components communicate with each other through "
"well-defined APIs and events."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:12
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:12
msgid "Composable commerce enables you to:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:13
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:13
msgid ""
"Choose the best components for your business needs from different vendors or "
"develop your own."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:14
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:14
msgid ""
"Mix and match components from different sources and technologies without "
"worrying about compatibility or integration issues."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:15
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:15
msgid ""
"Replace or upgrade components without affecting the rest of the application "
"or requiring downtime."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:16
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:16
msgid ""
"Experiment with new features or functionalities without risking the "
"stability of the application."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:17
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:17
msgid "Scale each component independently according to the demand and traffic."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:18
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:18
msgid ""
"For example, suppose you have an e-commerce application that sells books "
"online. You can use composable commerce to create your application from "
"different components such as:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:19
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:19
msgid ""
"A product catalog component that provides the data and UI for browsing and "
"searching books by title, author, genre, etc."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:20
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:20
msgid ""
"A shopping cart component that provides the data and UI for adding, removing "
"and updating items in the cart."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:21
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:21
msgid ""
"A checkout component that provides the data and UI for entering shipping and "
"billing information, applying discounts and coupons, etc."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:22
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:22
msgid ""
"A payment component that provides the data and UI for choosing and "
"processing payment methods such as credit card, PayPal, etc."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:23
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:23
msgid ""
"A review component that provides the data and UI for rating and reviewing "
"books after purchase."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:24
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:24
msgid ""
"Each component can be developed by a different team using a different "
"technology stack. For example, the product catalog component can be "
"developed using React and GraphQL, the shopping cart component can be "
"developed using Angular and RESTful APIs, the checkout component can be "
"developed using Vue and Firebase, etc. Each component can also be deployed "
"and updated separately on different servers or domains."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:25
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:25
msgid ""
"To compose your application from these components, you need to define how "
"they interact with each other through APIs and events. For example, you can "
"define an API for the product catalog component that exposes endpoints for "
"querying books by various criteria. You can also define an event for the "
"shopping cart component that emits a message when an item is added to or "
"removed from the cart. You can then use these APIs and events to connect "
"your components together and create a seamless user experience."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:26
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:26
#, no-wrap
msgid "What are the benefits of Module Federation + Composable Commerce?"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:27
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:27
msgid ""
"By using Module Federation + Composable Commerce, you can achieve the "
"following benefits:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:28
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:28
#, no-wrap
msgid "*Faster time to market*: You can reuse existing code and components from different sources without having to rebuild or redeploy them. You can also update or replace any component at any time without affecting the rest of the system.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:29
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:29
#, no-wrap
msgid "*Greater flexibility and scalability*: You can choose the best-of-breed vendors that provide the functionality you need for each business capability, such as product catalog, checkout, payment, etc. You can also scale each component independently according to your traffic and performance needs.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:30
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:30
#, no-wrap
msgid "*Better customer experience*: You can deliver consistent and engaging product experiences across multiple channels and touchpoints, such as web, mobile, social media, etc. You can also customize and optimize each component according to your customer preferences and behavior.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:31
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:31
msgid ""
"For example, suppose you want to add a new feature to your e-commerce "
"application that allows customers to create personalized book "
"recommendations based on their preferences. You can use composable commerce "
"to achieve this by:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:32
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:32
msgid ""
"Reusing an existing component that provides a survey service to collect "
"customer preferences."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:33
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:33
msgid ""
"Developing a new component that provides a recommendation engine to generate "
"book suggestions based on customer preferences."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:34
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:34
msgid ""
"Integrating these components with your existing product catalog component "
"using APIs and events."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:35
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:35
msgid ""
"Deploying these components separately without affecting the rest of the "
"application or requiring downtime."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:36
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:36
msgid ""
"This way, you can deliver this new feature faster, cheaper and more reliably "
"than if you had to modify your monolithic application."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:37
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:37
#, no-wrap
msgid "How does Module Federation + Composable Commerce work?"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:38
msgid ""
"Module Federation + Composable Commerce works by breaking down your e-"
"commerce solution into modular building blocks called Packaged Business "
"Capabilities (PBCs). Each PBC represents a specific business function, such "
"as product search, cart, reviews, etc. Each PBC can be deployed and scaled "
"independently, and can communicate with other PBCs via APIs. You can choose "
"the PBCs that suit your business requirements from different vendors or "
"sources, or create your own PBCs if needed. You can then compose them "
"together into a custom e-commerce application that meets your specific needs."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:39
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:39
#, no-wrap
msgid "Migration to Composable Commerce using Module Federation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:40
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:40
msgid ""
"Module federation is a feature of Webpack 5 that allows you to dynamically "
"load modules from remote applications at runtime. It also enables you to "
"share modules across different applications without duplicating code or "
"creating dependencies. Module federation can help you migrate your existing "
"e-commerce application to a composable commerce architecture by allowing you "
"to:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:41
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:41
msgid ""
"Split your monolithic application into smaller modules that can be loaded on "
"demand by different applications."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:42
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:42
msgid ""
"Create a shell application that acts as a container for loading and "
"rendering different modules based on the user's context and actions."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:43
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:43
msgid ""
"Share common modules such as authentication, navigation, UI components, etc."
"across different applications to ensure consistency and avoid duplication."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:44
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:44
msgid ""
"Leverage existing modules from third-party vendors or open source projects "
"to enhance your application's functionality and user experience."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:45
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:45
msgid "To use module federation, you need to:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:46
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:46
msgid ""
"Configure Webpack 5 in each module and shell application to expose and "
"consume remote modules using the `ModuleFederationPlugin`."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:47
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:47
msgid ""
"Define the entry points, dependencies and fallbacks for each remote module "
"using the `exposes`, `remotes` and `shared` options in the plugin "
"configuration."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:48
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:48
msgid ""
"Use dynamic imports or custom hooks to load and use remote modules in your "
"shell or module applications."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:49
msgid ""
"In this example, we have four PBCs: Product Catalog, Cart, Checkout and "
"Payment. Each PBC is provided by a different vendor or source:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:50
#, no-wrap
msgid "*Product Catalog*: This PBC is provided by https://api.akeneo.com/[Akeneo], a product information management (PIM) platform that helps you manage and enrich your product data across multiple channels.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:51
#, no-wrap
msgid "*Cart:* This PBC is provided by https://www.shopify.com/ca/enterprise/composable-commerce[Shopify], a leading e-commerce platform that offers a powerful cart functionality with features such as discounts, taxes, shipping rates, etc.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:52
#, no-wrap
msgid ""
"*Checkout:* This PBC is provided by https://www.sitecore.com/blog/commerce/what-is-composable-commerce[Sitecore], a digital experience platform that enables you to create personalized and optimized checkout experiences for your customers.\n"
"*Payment:* This PBC is provided by https://api.stripe.com/[Stripe], a payment platform that supports various payment methods, currencies, fraud prevention, etc.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:53
msgid ""
"Each PBC is exposed as a remote module that can be loaded at runtime from "
"its container. The containers are created using webpack's Module Federation "
"plugin, which allows sharing code between different builds. The containers "
"are connected via APIs that enable data exchange and orchestration between "
"the PBCs."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:54
msgid ""
"The front-end application is built using React. The front-end application "
"acts as the host that consumes the remote modules from the containers and "
"renders them on the web page. The front-end application can also customize "
"and extend the functionality of the remote modules if needed."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:55
#, no-wrap
msgid "How to get started with Module Federation + Composable Commerce?"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:56
msgid ""
"To get started with Module Federation + Composable Commerce, you will need "
"the following:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:57
msgid "A basic understanding of JavaScript, React and webpack"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:58
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:13
msgid "A code editor of your choice"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:59
msgid "A terminal or command-line interface"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:60
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:12
msgid "Node.js and npm installed on your machine"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:61
msgid ""
"An account with each of the vendors or sources that provide the PBCs you "
"want to use"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:62
msgid ""
"The following steps will guide you through creating a simple e-commerce "
"application using Module Federation and Composable Commerce:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:63
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:86
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:105
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:126
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:146
msgid ""
"Create a new folder for your project and navigate to it in your terminal or "
"command-line interface."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:64
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:87
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:106
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:127
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:147
msgid "Initialize a new npm project by running `npm init -y`."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:65
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:88
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:107
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:128
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:148
msgid ""
"Install webpack and its dependencies by running `npm install webpack webpack-"
"cli webpack-dev-server html-webpack-plugin @module-federation/module-"
"federation-plugin --save-dev`."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:66
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:89
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:108
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:129
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:149
msgid ""
"Create a `webpack.config.js` file in the root folder of your project and add "
"the following code:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:67
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:90
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:109
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:130
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:150
#, no-wrap
msgid ""
"// webpack.config.js\n"
"const HtmlWebpackPlugin = require(\"html-webpack-plugin\");\n"
"const ModuleFederationPlugin = require(\"@module-federation/module-federation-plugin\");\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:68
#, no-wrap
msgid ""
"module.exports = {\n"
"  mode: \"development\",\n"
"  devServer: {\n"
"    port: 3000,\n"
"  },\n"
"  plugins: [\n"
"    new HtmlWebpackPlugin({\n"
"      template: \"./public/index.html\",\n"
"    }),\n"
"    new ModuleFederationPlugin({\n"
"      name: \"host\",\n"
"      remotes: {\n"
"        productCatalog: \"productCatalog@http://localhost:3001/remoteEntry.js\",\n"
"        cart: \"cart@http://localhost:3002/remoteEntry.js\",\n"
"        checkout: \"checkout@http://localhost:3003/remoteEntry.js\",\n"
"        payment: \"payment@http://localhost:3004/remoteEntry.js\",\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:69
msgid ""
"This code configures webpack to create a development server on port 3000 and "
"to use Module Federation plugin to define the host application and the "
"remote modules from the containers. Each remote module has a name and a URL "
"that points to its container entry."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:70
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:93
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:112
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:133
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:153
msgid ""
"Create a `public` folder in the root folder of your project and add an "
"`index.html` file with the following code:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:71
#, no-wrap
msgid ""
"<!-- index.html -->\n"
"<html>\n"
"  <head>\n"
"    <title>Module Federation + Composable Commerce</title>\n"
"  </head>\n"
"  <body>\n"
"    <div id=\"root\"></div>\n"
"    <script src=\"main.js\"></script>\n"
"  </body>\n"
"</html>\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:72
msgid ""
"This code defines the HTML template for the host application and loads the "
"main JavaScript bundle."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:73
msgid ""
"Create a `src` folder in the root folder of your project and add an `index."
"js` file with the following code:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:74
#, no-wrap
msgid ""
"// index.js\n"
"import React from \"react\";\n"
"import ReactDOM from \"react-dom\";\n"
"import App from \"./App\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:75
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:58
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:80
#, no-wrap
msgid "ReactDOM.render(<App />, document.getElementById(\"root\"));\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:76
msgid ""
"This code imports React and ReactDOM libraries and renders the App component "
"on the web page."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:77
msgid ""
"In the same `src` folder, create an `App.js` file with the following code:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:78
#, no-wrap
msgid ""
"// App.js\n"
"import React, { lazy, Suspense } from \"react\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:79
#, no-wrap
msgid ""
"const ProductCatalog = lazy(() => import(\"productCatalog/ProductCatalog\"));\n"
"const Cart = lazy(() => import(\"cart/Cart\"));\n"
"const Checkout = lazy(() => import(\"checkout/Checkout\"));\n"
"const Payment = lazy(() => import(\"payment/Payment\"));\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:80
#, no-wrap
msgid ""
"const App = () => {\n"
"  return (\n"
"    <div>\n"
"      <h1>Module Federation + Composable Commerce</h1>\n"
"      <Suspense fallback={<div>Loading...</div>}>\n"
"        <ProductCatalog />\n"
"        <Cart />\n"
"        <Checkout />\n"
"        <Payment />\n"
"      </Suspense>\n"
"    </div>\n"
"  );\n"
"};\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:81
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:49
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:84
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:97
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:54
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:76
#, no-wrap
msgid "export default App;\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:82
msgid ""
"This code imports React and its lazy and Suspense features, which allow "
"loading components asynchronously. It also imports the remote modules from "
"the containers using their names defined in the webpack configuration. It "
"then renders each component on the web page using Suspense to handle loading "
"states."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:83
msgid ""
"In your terminal or command-line interface, run `npm start` to start the "
"development server and open your browser to `http://localhost:3000`. You "
"should see a web page with a title and four loading messages."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:84
msgid ""
"Congratulations! You have successfully created a host application that "
"consumes remote modules from different containers using Module Federation + "
"Composable Commerce. The next steps are to create each container application "
"and expose its PBC as a remote module. For simplicity, we will use React for "
"each container application, but you can use any framework or library of your "
"choice."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:85
msgid ""
"To create the Product Catalog container application, follow these steps:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:91
#, no-wrap
msgid ""
"module.exports = {\n"
"  mode: \"development\",\n"
"  devServer: {\n"
"    port: 3001,\n"
"  },\n"
"  plugins: [\n"
"    new HtmlWebpackPlugin({\n"
"      template: \"./public/index.html\",\n"
"    }),\n"
"    new ModuleFederationPlugin({\n"
"      name: \"productCatalog\",\n"
"      filename: \"remoteEntry.js\",\n"
"      exposes: {\n"
"        \"./ProductCatalog\": \"./src/ProductCatalog\",\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:92
msgid ""
"This code configures webpack to create a development server on port 3001 and "
"to use Module Federation plugin to expose the Product Catalog PBC as a "
"remote module with the name `productCatalog` and the filename `remoteEntry."
"js`."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:94
#, no-wrap
msgid ""
"<!-- index.html -->\n"
"<html>\n"
"  <head>\n"
"    <title>Product Catalog</title>\n"
"  </head>\n"
"  <body>\n"
"    <div id=\"root\"></div>\n"
"    <script src=\"remoteEntry.js\"></script>\n"
"  </body>\n"
"</html>\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:95
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:114
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:135
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:155
msgid ""
"This code defines the HTML template for the container application and loads "
"the remote entry JavaScript bundle."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:96
msgid ""
"Create a `src` folder in the root folder of your project and add a "
"`ProductCatalog.js` file with the following code:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:97
#, no-wrap
msgid ""
"// ProductCatalog.js\n"
"import React, { useState, useEffect } from \"react\";\n"
"import axios from \"axios\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:98
#, no-wrap
msgid ""
"const ProductCatalog = () => {\n"
"  const [products, setProducts] = useState([]);\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:99
#, no-wrap
msgid ""
"  useEffect(() => {\n"
"    // Fetch products from Akeneo PIM using its REST API\n"
"    // For simplicity, we hardcode the authentication token and the query parameters\n"
"    // In a real scenario, you would use a dynamic way to get these values\n"
"    const token = \"Bearer xxx\"; // Replace with your own token\n"
"    const query = {\n"
"      search: JSON.stringify({\n"
"        enabled: [{ operator: \"=\", value: true }],\n"
"      }),\n"
"      scope: \"e-commerce\",\n"
"      locales: \"en_US\",\n"
"      limit: 10,\n"
"      with_attribute_options: true,\n"
"    };\n"
"    axios\n"
"      .get(\"https://demo.akeneo.com/api/rest/v1/products\", {\n"
"        headers: {\n"
"          Authorization: token,\n"
"          Accept: \"application/json\",\n"
"        },\n"
"        params: query,\n"
"      })\n"
"      .then((response) => {\n"
"        // Extract the product data from the response\n"
"        const products = response.data._embedded.items.map((item) => {\n"
"          return {\n"
"            id: item.identifier,\n"
"            name: item.values.name.en_US[0].data,\n"
"            description: item.values.description.en_US[0].data,\n"
"            price: item.values.price[0].data[0].amount,\n"
"            image: item.values.images[0].data,\n"
"          };\n"
"        });\n"
"        // Update the state with the product data\n"
"        setProducts(products);\n"
"      })\n"
"      .catch((error) => {\n"
"        // Handle errors\n"
"        console.error(error);\n"
"      });\n"
"  }, []);\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:100
#, no-wrap
msgid ""
"  return (\n"
"    <div>\n"
"      <h2>Product Catalog</h2>\n"
"      <ul>\n"
"        {products.map((product) => (\n"
"          <li key={product.id}>\n"
"            <img src={product.image} alt={product.name} width=\"100\" />\n"
"            <h3>{product.name}</h3>\n"
"            <p>{product.description}</p>\n"
"            <p>${product.price}</p>\n"
"          </li>\n"
"        ))}\n"
"      </ul>\n"
"    </div>\n"
"  );\n"
"};\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:101
#, no-wrap
msgid "export default ProductCatalog;\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:102
msgid ""
"This code imports React and its useState and useEffect hooks, as well as "
"axios library for making HTTP requests. It defines a ProductCatalog "
"component that fetches products from Akeneo PIM using its REST API² and "
"renders them on the web page."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:103
msgid ""
"In your terminal or command-line interface, run `npm start` to start the "
"development server and open your browser to `http://localhost:3001`. You "
"should see a web page with a title and a list of products."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:104
msgid "To create the Cart container application, follow these steps:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:110
#, no-wrap
msgid ""
"module.exports = {\n"
"  mode: \"development\",\n"
"  devServer: {\n"
"    port: 3002,\n"
"  },\n"
"  plugins: [\n"
"    new HtmlWebpackPlugin({\n"
"      template: \"./public/index.html\",\n"
"    }),\n"
"    new ModuleFederationPlugin({\n"
"      name: \"cart\",\n"
"      filename: \"remoteEntry.js\",\n"
"      exposes: {\n"
"        \"./Cart\": \"./src/Cart\",\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:111
msgid ""
"This code configures webpack to create a development server on port 3002 and "
"to use Module Federation plugin to expose the Cart PBC as a remote module "
"with the name `cart` and the filename `remoteEntry.js`."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:113
#, no-wrap
msgid ""
"<!-- index.html -->\n"
"<html>\n"
"  <head>\n"
"    <title>Cart</title>\n"
"  </head>\n"
"  <body>\n"
"    <div id=\"root\"></div>\n"
"    <script src=\"remoteEntry.js\"></script>\n"
"  </body>\n"
"</html>\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:115
msgid ""
"Create a `src` folder in the root folder of your project and add a `Cart.js` "
"file with the following code:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:116
#, no-wrap
msgid ""
"// Cart.js\n"
"import React, { useState } from \"react\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:117
#, no-wrap
msgid ""
"const Cart = () => {\n"
"  const [items, setItems] = useState([]);\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:118
#, no-wrap
msgid ""
"  const addToCart = (product) => {\n"
"    // Add the product to the cart items\n"
"    setItems([...items, product]);\n"
"  };\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:119
#, no-wrap
msgid ""
"  const removeFromCart = (id) => {\n"
"    // Remove the product from the cart items by its id\n"
"    setItems(items.filter((item) => item.id !== id));\n"
"  };\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:120
#, no-wrap
msgid ""
"  const getTotal = () => {\n"
"    // Calculate the total price of the cart items\n"
"    return items.reduce((total, item) => total + parseFloat(item.price), 0);\n"
"  };\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:121
#, no-wrap
msgid ""
"  return (\n"
"    <div>\n"
"      <h2>Cart</h2>\n"
"      <ul>\n"
"        {items.map((item) => (\n"
"          <li key={item.id}>\n"
"            <img src={item.image} alt={item.name} width=\"100\" />\n"
"            <h3>{item.name}</h3>\n"
"            <p>${item.price}</p>\n"
"            <button onClick={() => removeFromCart(item.id)}>Remove</button>\n"
"          </li>\n"
"        ))}\n"
"      </ul>\n"
"      <p>Total: ${getTotal()}</p>\n"
"    </div>\n"
"  );\n"
"};\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:122
#, no-wrap
msgid "export default Cart;\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:123
msgid ""
"This code imports React and its useState hook. It defines a Cart component "
"that manages an array of cart items and provides functions to add, remove "
"and calculate the total price of the items. It also renders the cart items "
"on the web page."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:124
msgid ""
"In your terminal or command-line interface, run `npm start` to start the "
"development server and open your browser to `http://localhost:3002`. You "
"should see a web page with a title and an empty cart."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:125
msgid "To create the Checkout container application, follow these steps:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:131
#, no-wrap
msgid ""
"module.exports = {\n"
"  mode: \"development\",\n"
"  devServer: {\n"
"    port: 3003,\n"
"  },\n"
"  plugins: [\n"
"    new HtmlWebpackPlugin({\n"
"      template: \"./public/index.html\",\n"
"    }),\n"
"    new ModuleFederationPlugin({\n"
"      name: \"checkout\",\n"
"      filename: \"remoteEntry.js\",\n"
"      exposes: {\n"
"        \"./Checkout\": \"./src/Checkout\",\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:132
msgid ""
"This code configures webpack to create a development server on port 3003 and "
"to use Module Federation plugin to expose the Checkout PBC as a remote "
"module with the name `checkout` and the filename `remoteEntry.js`."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:134
#, no-wrap
msgid ""
"<!-- index.html -->\n"
"<html>\n"
"  <head>\n"
"    <title>Checkout</title>\n"
"  </head>\n"
"  <body>\n"
"    <div id=\"root\"></div>\n"
"    <script src=\"remoteEntry.js\"></script>\n"
"  </body>\n"
"</html>\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:136
msgid ""
"Create a `src` folder in the root folder of your project and add a `Checkout."
"js` file with the following code:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:137
#, no-wrap
msgid ""
"// Checkout.js\n"
"import React, { useState } from \"react\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:138
#, no-wrap
msgid ""
"const Checkout = () => {\n"
"  const [customer, setCustomer] = useState({\n"
"    firstName: \"\",\n"
"    lastName: \"\",\n"
"    email: \"\",\n"
"    address: \"\",\n"
"    city: \"\",\n"
"    state: \"\",\n"
"    zip: \"\",\n"
"    country: \"\",\n"
"  });\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:139
#, no-wrap
msgid ""
"  const handleChange = (event) => {\n"
"    // Update the customer state with the input value\n"
"    const { name, value } = event.target;\n"
"    setCustomer({ ...customer, [name]: value });\n"
"  };\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:140
#, no-wrap
msgid ""
"  const handleSubmit = (event) => {\n"
"    // Prevent the default form submission behavior\n"
"    event.preventDefault();\n"
"    // Validate the customer data and send it to Sitecore using its REST API\n"
"    // For simplicity, we hardcode the authentication token and the base URL\n"
"    // In a real scenario, you would use a dynamic way to get these values\n"
"    const token = \"Bearer xxx\"; // Replace with your own token\n"
"    const baseURL = \"https://demo.sitecore.com/api/checkout\"; // Replace with your own URL\n"
"    axios\n"
"      .post(\n"
"        `${baseURL}/customer`,\n"
"        {\n"
"          firstName: customer.firstName,\n"
"          lastName: customer.lastName,\n"
"          email: customer.email,\n"
"          address: customer.address,\n"
"          city: customer.city,\n"
"          state: customer.state,\n"
"          zip: customer.zip,\n"
"          country: customer.country,\n"
"        },\n"
"        {\n"
"          headers: {\n"
"            Authorization: token,\n"
"            \"Content-Type\": \"application/json\",\n"
"          },\n"
"        }\n"
"      )\n"
"      .then((response) => {\n"
"        // Handle success\n"
"        console.log(response.data);\n"
"      })\n"
"      .catch((error) => {\n"
"        // Handle errors\n"
"        console.error(error);\n"
"      });\n"
"  };\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:141
#, no-wrap
msgid ""
"  return (\n"
"    <div>\n"
"      <h2>Checkout</h2>\n"
"      <form onSubmit={handleSubmit}>\n"
"        <label htmlFor=\"firstName\">First name</label>\n"
"        <input\n"
"          type=\"text\"\n"
"          id=\"firstName\"\n"
"          name=\"firstName\"\n"
"          value={customer.firstName}\n"
"          onChange={handleChange}\n"
"          required\n"
"        />\n"
"        <label htmlFor=\"lastName\">Last name</label>\n"
"        <input\n"
"          type=\"text\"\n"
"          id=\"lastName\"\n"
"          name=\"lastName\"\n"
"          value={customer.lastName}\n"
"          onChange={handleChange}\n"
"          required\n"
"        />\n"
"        <label htmlFor=\"email\">Email</label>\n"
"        <input\n"
"          type=\"email\"\n"
"          id=\"email\"\n"
"          name=\"email\"\n"
"          value={customer.email}\n"
"          onChange={handleChange}\n"
"          required\n"
"        />\n"
"        <label htmlFor=\"address\">Address</label>\n"
"        <input\n"
"          type=\"text\"\n"
"          id=\"address\"\n"
"          name=\"address\"\n"
"          value={customer.address}\n"
"          onChange={handleChange}\n"
"          required\n"
"        />\n"
"        <label htmlFor=\"city\">City</label>\n"
"        <input\n"
"          type=\"text\"\n"
"          id=\"city\"\n"
"          name=\"city\"\n"
"          value={customer.city}\n"
"          onChange={handleChange}\n"
"          required\n"
"        />\n"
"        <label htmlFor=\"state\">State</label>\n"
"        <input\n"
"          type=\"text\"\n"
"          id=\"state\"\n"
"          name=\"state\"\n"
"          value={customer.state}\n"
"          onChange={handleChange}\n"
"          required\n"
"        />\n"
"        <label htmlFor=\"zip\">Zip code</label>\n"
"        <input\n"
"          type=\"text\"\n"
"          id=\"zip\"\n"
"          name=\"zip\"\n"
"          value={customer.zip}\n"
"          onChange={handleChange}\n"
"          required\n"
"        />\n"
"        <label htmlFor=\"country\">Country</label>\n"
"        <input\n"
"          type=\"text\"\n"
"          id=\"country\"\n"
"          name=\"country\"\n"
"          value={customer.country}\n"
"          onChange={handleChange}\n"
"          required\n"
"        />\n"
"        <button type=\"submit\">Submit</button>\n"
"      </form>\n"
"    </div>\n"
"  );\n"
"};\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:142
#, no-wrap
msgid "export default Checkout;\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:143
msgid ""
"This code imports React and its useState hook. It defines a Checkout "
"component that manages an object of customer data and provides functions to "
"handle input changes and form submission. It also renders a form with the "
"customer data on the web page."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:144
msgid ""
"In your terminal or command-line interface, run `npm start` to start the "
"development server and open your browser to `http://localhost:3003`. You "
"should see a web page with a title and a form."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:145
msgid "To create the Payment container application, follow these steps:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:151
#, no-wrap
msgid ""
"module.exports = {\n"
"  mode: \"development\",\n"
"  devServer: {\n"
"    port: 3004,\n"
"  },\n"
"  plugins: [\n"
"    new HtmlWebpackPlugin({\n"
"      template: \"./public/index.html\",\n"
"    }),\n"
"    new ModuleFederationPlugin({\n"
"      name: \"payment\",\n"
"      filename: \"remoteEntry.js\",\n"
"      exposes: {\n"
"        \"./Payment\": \"./src/Payment\",\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:152
msgid ""
"This code configures webpack to create a development server on port 3004 and "
"to use Module Federation plugin to expose the Payment PBC as a remote module "
"with the name `payment` and the filename `remoteEntry.js`."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:154
#, no-wrap
msgid ""
"<!-- index.html -->\n"
"<html>\n"
"  <head>\n"
"    <title>Payment</title>\n"
"  </head>\n"
"  <body>\n"
"    <div id=\"root\"></div>\n"
"    <script src=\"remoteEntry.js\"></script>\n"
"  </body>\n"
"</html>\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:156
msgid ""
"Create a `src` folder in the root folder of your project and add a `Payment."
"js` file with the following code:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:157
#, no-wrap
msgid ""
"// Payment.js\n"
"import React, { useState } from \"react\";\n"
"import { loadStripe } from \"@stripe/stripe-js\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:158
#, no-wrap
msgid ""
"const Payment = () => {\n"
"  const [paymentIntent, setPaymentIntent] = useState(null);\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:159
#, no-wrap
msgid ""
"  const handlePayment = async () => {\n"
"    // Create a Stripe instance using your publishable key\n"
"    // For simplicity, we hardcode the key here\n"
"    // In a real scenario, you would use a dynamic way to get this value\n"
"    const stripe = await loadStripe(\n"
"      \"test_key_XXXXXXXXXXX\"\n"
"    );\n"
"    // Create a payment intent using Stripe's REST API\n"
"    // For simplicity, we hardcode the authentication token and the amount here\n"
"    // In a real scenario, you would use a dynamic way to get these values\n"
"    const token = \"Bearer xxx\"; // Replace with your own token\n"
"    const amount = 100; // Replace with your own amount\n"
"    const response = await fetch(\"https://api.stripe.com/v1/payment_intents\", {\n"
"      method: \"POST\",\n"
"      headers: {\n"
"        Authorization: token,\n"
"        \"Content-Type\": \"application/x-www-form-urlencoded\",\n"
"      },\n"
"      body: `amount=${amount}&currency=usd`,\n"
"    });\n"
"    const data = await response.json();\n"
"    // Update the state with the payment intent data\n"
"    setPaymentIntent(data);\n"
"    // Confirm the payment using Stripe's JavaScript library\n"
"    const result = await stripe.confirmCardPayment(data.client_secret, {\n"
"      payment_method: {\n"
"        card: {\n"
"          number: \"4242424242424242\", // Replace with your own card number\n"
"          exp_month: 12, // Replace with your own card expiration month\n"
"          exp_year: 2025, // Replace with your own card expiration year\n"
"          cvc: \"123\", // Replace with your own card CVC\n"
"        },\n"
"      },\n"
"    });\n"
"    // Handle the payment result\n"
"    if (result.error) {\n"
"      // Show error message to the customer\n"
"      console.error(result.error.message);\n"
"    } else {\n"
"      if (result.paymentIntent.status === \"succeeded\") {\n"
"        // Show success message to the customer\n"
"        console.log(\"Payment succeeded\");\n"
"      }\n"
"    }\n"
"  };\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:160
#, no-wrap
msgid ""
"  return (\n"
"    <div>\n"
"      <h2>Payment</h2>\n"
"      <button onClick={handlePayment}>Pay</button>\n"
"      {paymentIntent && (\n"
"        <div>\n"
"          <p>Payment intent ID: {paymentIntent.id}</p>\n"
"          <p>Payment intent status: {paymentIntent.status}</p>\n"
"        </div>\n"
"      )}\n"
"    </div>\n"
"  );\n"
"};\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:161
#, no-wrap
msgid "export default Payment;\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:162
msgid ""
"This code imports React and its useState hook, as well as Stripe's "
"JavaScript library for creating and confirming payments. It defines a "
"Payment component that manages an object of payment intent data and provides "
"a function to handle payment using Stripe's REST API and JavaScript library. "
"It also renders a button and the payment intent data on the web page."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:163
msgid ""
"In your terminal or command-line interface, run `npm start` to start the "
"development server and open your browser to `http://localhost:3004`. You "
"should see a web page with a title and a button."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:164
msgid ""
"You have now created four container applications that expose their PBCs as "
"remote modules using Module Federation. To test the integration of these "
"modules with the host application, go back to the host application folder in "
"your terminal or command-line interface and run `npm start` again. Then open "
"your browser to `http://localhost:3000`. You should see a web page with four "
"components: Product Catalog, Cart, Checkout and Payment."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:165
msgid "To interact with these components, follow these steps:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:166
msgid ""
"Click on any product image or name in the Product Catalog component to add "
"it to the Cart component."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:167
msgid ""
"Click on the Remove button in the Cart component to remove any product from "
"the cart."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:168
msgid ""
"Fill in the form in the Checkout component with your customer details and "
"click on the Submit button to send them to Sitecore."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:169
msgid ""
"Click on the Pay button in the Payment component to pay for your order using "
"Stripe."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:170
msgid ""
"Check the console logs in your browser's developer tools to see the "
"responses from Sitecore and Stripe."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:171
msgid ""
"Congratulations! You have successfully created an e-commerce application "
"using Module Federation + Composable Commerce. You have learned how to:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:172
msgid ""
"Use webpack's Module Federation plugin to expose and consume remote modules "
"from different containers."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:173
msgid "Use React to create user interfaces for each PBC."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:174
msgid "Use axios to make HTTP requests to different APIs."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:175
msgid "Use Stripe to create and confirm payments."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:176
#, no-wrap
msgid "Next steps"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:177
msgid ""
"This guide has shown you how to create a simple e-commerce application using "
"Module Federation + Composable Commerce. However, there are many more "
"features and possibilities that you can explore with this approach. Here are "
"some ideas for further improvement:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:178
msgid ""
"Add more PBCs from different vendors or sources, such as product reviews, "
"recommendations, loyalty programs, etc."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:179
msgid ""
"Add more functionality and customization options to each PBC, such as "
"filters, sorting, pagination, etc."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:180
msgid ""
"Add more validation and error handling logic to each PBC, such as input "
"validation, API error handling, etc."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:181
msgid ""
"Add more security and authentication mechanisms to each PBC, such as HTTPS, "
"CORS, CSRF protection, etc."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:182
msgid ""
"Add more testing and debugging tools to each PBC, such as unit tests, "
"integration tests, code coverage, logging, etc."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:183
msgid ""
"Add more performance and optimization techniques to each PBC, such as "
"caching, compression, minification, code splitting, lazy loading, etc."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:184
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:93
#, no-wrap
msgid "Best Practices for Composable Commerce with Module Federation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:185
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:94
msgid ""
"To ensure a successful migration to composable commerce with module "
"federation, you should follow some best practices such as:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:186
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:95
msgid ""
"Design your modules based on business domains or functionalities rather than "
"technical layers or features. This will help you achieve high cohesion and "
"low coupling among your modules."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:187
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:96
msgid ""
"Define clear contracts and interfaces for your modules using APIs and "
"events. This will help you ensure interoperability and compatibility among "
"your modules."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:188
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:97
msgid ""
"Use versioning and semantic versioning for your modules to manage changes "
"and updates without breaking dependencies."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:189
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:98
msgid ""
"Use feature flags or toggles to enable or disable features or "
"functionalities in your modules without redeploying them."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:190
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:99
msgid ""
"Use testing tools such as Jest or Cypress to test your modules individually "
"and integrally. This will help you ensure quality and reliability of your "
"modules."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:191
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:100
msgid ""
"Use monitoring tools such as Sentry or New Relic to track performance, "
"errors and usage of your modules. This will help you optimize and "
"troubleshoot your modules."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:192
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:101
msgid ""
"For example, suppose you want to update the cart component in the `cart-app` "
"to show more information about the items such as quantity, price, subtotal, "
"etc. You can use semantic versioning to indicate that this is a minor update "
"that adds new functionality without breaking existing functionality. You can "
"also use feature flags to enable this new functionality only for a subset of "
"users for testing purposes. You can then deploy the updated `cart-app` "
"without affecting the rest of the application or requiring downtime."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:194
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:103
msgid ""
"Composable commerce with module federation is a powerful way to migrate your "
"existing e-commerce application to a modular, flexible and scalable "
"architecture. It allows you to leverage existing components from different "
"sources or create your own components that can be composed together to "
"create a customized user experience. It also enables you to update or "
"replace components without affecting the rest of the application or "
"requiring downtime."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:195
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:104
msgid ""
"In this guide, you learned what composable commerce is, what benefits it "
"provides for e-commerce businesses, how to use module federation to migrate "
"your monolithic e-commerce application to a composable commerce "
"architecture, what best practices you should follow, and how to use code "
"examples to illustrate the steps."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:196
msgid ""
"If you want to learn more about composable commerce, you can check out these "
"resources, we relied on them while writing this documentation:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:197
msgid ""
"https://www.akeneo.com/blog/what-is-composable-commerce/[Akneo: What Is "
"Composable Commerce?]"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:198
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:106
msgid ""
"https://webpack.js.org/concepts/module-federation/[Webpack 5 Module "
"Federation]"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:199
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:107
msgid "https://www.composablecommercehub.com/[Composable Commerce Hub]"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:200
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:108
msgid ""
"https://www.udemy.com/course/microfrontend-course/[Building Micro Frontends "
"with React]"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:201
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:109
msgid ""
"https://commercelayer.io/blog/composable-commerce-with-micro-"
"frontends[Composable commerce with micro frontends]"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-PBC-edition.adoc:202
msgid ""
"https://fabric.inc/blog/composable-commerce/[What Is Composable Commerce?]"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:38
msgid ""
"Module Federation + Composable Commerce works by breaking down your "
"ecommerce solution into modular building blocks called Packaged Business "
"Capabilities (PBCs). Each PBC represents a specific business function, such "
"as product search, cart, reviews, etc. Each PBC can be deployed and scaled "
"independently, and can communicate with other PBCs via APIs. You can choose "
"the PBCs that suit your business requirements from different vendors or "
"sources, or create your own PBCs if needed. You can then compose them "
"together into a custom ecommerce application that meets your specific needs."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:49
msgid "In this example, you have four bundles:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:50
#, no-wrap
msgid ""
"**Shell**: This is the main bundle that provides the layout and navigation of your application. It also acts as the host for the other bundles\n"
"and consumes their modules.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:51
#, no-wrap
msgid "**Catalog**: This bundle exposes a product list component that displays the products from a product catalog service.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:52
#, no-wrap
msgid "**Cart**: This bundle exposes a cart component that displays the items in the shopping cart and allows the user to update or remove them. It also communicates with a cart service to persist the cart data.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:53
#, no-wrap
msgid "**Checkout**: This bundle exposes a checkout component that guides the user through the checkout process. It also communicates with a checkout service to handle the payment and order confirmation.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:54
msgid ""
"You can follow these steps to migrate your e-commerce application using "
"these bundles:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:55
msgid ""
"Create four separate module applications for each bundle: `shell-app`, "
"`catalog-app`, `cart-app` and `checkout-app`. Each module application should "
"contain the logic, data and UI components related to its bundle. For "
"example, the `catalog-app` should contain the product catalog service, the "
"product list component, etc."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:56
#, no-wrap
msgid ""
"// src/ProductList.js\n"
"import React from \"react\";\n"
"import { useQuery } from \"@apollo/client\";\n"
"import { GET_ALL_BOOKS } from \"./queries\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:57
#, no-wrap
msgid ""
"function ProductList() {\n"
"  const { loading, error, data } = useQuery(GET_ALL_BOOKS);\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:58
#, no-wrap
msgid ""
"  if (loading) return <div>Loading...</div>;\n"
"  if (error) return <div>Error: {error.message}</div>;\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:59
#, no-wrap
msgid "  const { books } = data;\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:60
#, no-wrap
msgid ""
"  return (\n"
"    <div className=\"product-list\">\n"
"      <h1>Books</h1>\n"
"      <ul>\n"
"        {books.map((book) => (\n"
"          <li key={book.id}>\n"
"            <a href={`/product/${book.id}`}>{book.title}</a>\n"
"          </li>\n"
"        ))}\n"
"      </ul>\n"
"    </div>\n"
"  );\n"
"}\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:61
#, no-wrap
msgid "export default ProductList;\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:62
msgid ""
"Create a shell application that will act as a container for loading and "
"rendering different module applications based on the user's context and "
"actions. The shell application should contain the common modules such as "
"authentication, navigation, UI components, etc.that are shared across all "
"bundles. The shell application should also contain a router that will "
"determine which module application to load based on the URL path."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:63
#, no-wrap
msgid "// src/Shell.js\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:64
#, no-wrap
msgid ""
"import React from \"react\";\n"
"import { BrowserRouter as Router } from \"react-router-dom\";\n"
"import Header from \"./Header\";\n"
"import Footer from \"./Footer\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:65
#, no-wrap
msgid ""
"function Shell() {\n"
"  return (\n"
"    <Router>\n"
"      <div className=\"shell\">\n"
"        <Header />\n"
"        {/* render module applications based on route */}\n"
"        <Footer />\n"
"      </div>\n"
"    </Router>\n"
"  );\n"
"}\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:66
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:78
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:90
#, no-wrap
msgid "export default Shell;\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:67
msgid "The previous chapter was:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:68
msgid ""
"Configure Webpack 5 in each module and shell application using the "
"`ModuleFederationPlugin`. For example, in the `catalog-app`, you should "
"expose the product list component as a remote module using the `exposes` "
"option:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:69
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:72
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:80
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:83
#, no-wrap
msgid ""
"// webpack.config.js\n"
"const ModuleFederationPlugin = require(\"webpack/lib/container/ModuleFederationPlugin\");\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:70
#, no-wrap
msgid ""
"module.exports = {\n"
"  // ...\n"
"  plugins: [\n"
"    new ModuleFederationPlugin({\n"
"      name: \"catalog\",\n"
"      filename: \"remoteEntry.js\",\n"
"      exposes: {\n"
"        \"./ProductList\": \"./src/ProductList\",\n"
"      },\n"
"      shared: {\n"
"        // specify shared dependencies\n"
"        react: { singleton: true },\n"
"        \"react-router-dom\": { singleton: true },\n"
"        \"@apollo/client\": { singleton: true },\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:71
msgid ""
"In the shell application, you should consume the product list component as a "
"remote module using the `remotes` option:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:73
#, no-wrap
msgid ""
"module.exports = {\n"
"  // ...\n"
"  plugins: [\n"
"    new ModuleFederationPlugin({\n"
"      name: \"shell\",\n"
"      filename: \"remoteEntry.js\",\n"
"      remotes: {\n"
"        catalog: \"catalog@http://localhost:3001/remoteEntry.js\",\n"
"      },\n"
"      shared: {\n"
"        // specify shared dependencies\n"
"        react: { singleton: true },\n"
"        \"react-router-dom\": { singleton: true },\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:74
msgid ""
"Use dynamic imports or custom hooks to load and use remote modules in your "
"shell or module applications. For example, in the shell application, you can "
"use React.lazy() to load and render the product list component from the "
"`catalog-app` when the user navigates to `/products`:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:75
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:86
#, no-wrap
msgid ""
"// src/Shell.js\n"
"import React from \"react\";\n"
"import { BrowserRouter as Router, Route } from \"react-router-dom\";\n"
"import Header from \"./Header\";\n"
"import Footer from \"./Footer\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:76
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:87
#, no-wrap
msgid ""
"const ProductList = React.lazy(() =>\n"
"  import(\"catalog/ProductList\")\n"
");\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:77
#, no-wrap
msgid ""
"function Shell() {\n"
"  return (\n"
"    <Router>\n"
"      <div className=\"shell\">\n"
"        <Header />\n"
"        {/* render module applications based on route */}\n"
"        <Route path=\"/products\">\n"
"          <React.Suspense fallback={<div>Loading...</div>}>\n"
"            <ProductList />\n"
"          </React.Suspense>\n"
"        </Route>\n"
"        {/* render other routes */}\n"
"        <Footer />\n"
"      </div>\n"
"    </Router>\n"
"  );\n"
"}\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:79
msgid ""
"Repeat steps 3 and 4 for other module applications such as `cart-app` and "
"`checkout-app`. For example, in the `cart-app`, you can expose the cart "
"component as a remote module:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:81
#, no-wrap
msgid ""
"module.exports = {\n"
"  // ...\n"
"  plugins: [\n"
"    new ModuleFederationPlugin({\n"
"      name: \"cart\",\n"
"      filename: \"remoteEntry.js\",\n"
"      exposes: {\n"
"        \"./Cart\": \"./src/Cart\",\n"
"      },\n"
"      shared: {\n"
"        // specify shared dependencies\n"
"        react: { singleton: true },\n"
"        \"react-router-dom\": { singleton: true },\n"
"        axios: { singleton: true },\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:82
msgid ""
"In the shell application, you can consume the cart component as a remote "
"module:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:84
#, no-wrap
msgid ""
"module.exports = {\n"
"  // ...\n"
"  plugins: [\n"
"    new ModuleFederationPlugin({\n"
"      name: \"shell\",\n"
"      filename: \"remoteEntry.js\",\n"
"      remotes: {\n"
"        catalog: \"catalog@http://localhost:3001/remoteEntry.js\",\n"
"        cart: \"cart@http://localhost:3002/remoteEntry.js\",\n"
"      },\n"
"      shared: {\n"
"        // specify shared dependencies\n"
"        react: { singleton: true },\n"
"        \"react-router-dom\": { singleton: true },\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:85
msgid ""
"And use React.lazy() to load and render the cart component from the `cart-"
"app` when the user navigates to `/cart`:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:88
#, no-wrap
msgid ""
"const Cart = React.lazy(() =>\n"
"  import(\"cart/Cart\")\n"
");\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:89
#, no-wrap
msgid ""
"function Shell() {\n"
"  return (\n"
"    <Router>\n"
"      <div className=\"shell\">\n"
"        <Header />\n"
"        {/* render module applications based on route */}\n"
"        <Route path=\"/products\">\n"
"          <React.Suspense fallback={<div>Loading...</div>}>\n"
"            <ProductList />\n"
"          </React.Suspense>\n"
"        </Route>\n"
"        <Route path=\"/cart\">\n"
"          <React.Suspense fallback={<div>Loading...</div>}>\n"
"            <Cart />\n"
"          </React.Suspense>\n"
"        </Route>\n"
"        {/* render other routes */}\n"
"        <Footer />\n"
"      </div>\n"
"    </Router>\n"
"  );\n"
"}\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:91
msgid ""
"Deploy each module and shell application separately on different servers or "
"domains. For example, you can deploy `catalog-app` on http://"
"localhost:3001/, `cart-app` on http://localhost:3002/, and `shell-app` on "
"http://localhost:3003/."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:92
msgid ""
"Test your composable commerce application by accessing http://"
"localhost:3003/ in your browser."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/composable-commerce-simple.adoc:105
msgid ""
"If you want to learn more about composable commerce with module federation, "
"you can check out these resources:"
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/delegate-modules.adoc:1
#, no-wrap
msgid "Getting Familiar with Delegate Modules: An In-Depth Guide "
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:2
msgid ""
"In this comprehensive guide, we will delve into the powerful feature of "
"Delegate Modules in Module Federation version 7, exploring their purpose, "
"use cases, and implementation techniques. We will also discuss how they can "
"enhance the flexibility and control of your Webpack configuration, "
"empowering you to create more sophisticated applications"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/delegate-modules.adoc:3
#, no-wrap
msgid "Understanding Delegate Modules"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:4
msgid ""
"Delegate modules have been introduced to tackle a longstanding challenge in "
"the module federation space - dynamic remotes. These modules offer a more "
"streamlined and scalable way to control the \"glue\" code that connects "
"remote applications, without sacrificing the advantages of Webpack."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:5
msgid ""
"To get more familiar with the concept of Dynamic Remotes, we suggest reading "
"a dedicated documentation page: xref:dynamic-remotes.adoc[Dynamic Remotes]"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:6
msgid ""
"Traditionally, managing dynamic remotes involved injecting a script using "
"the low-level module federation API, which resulted in losing many of "
"Webpack's features. With delegate modules, you can now instruct Webpack that "
"a remote entry is a code within the Webpack build itself, enabling you to "
"bundle various entry-point logic and export back a promise that resolves to "
"a federated remote."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:7
msgid ""
"Compared to using the promise `new Promise syntax`, delegate modules are "
"bundled into Webpack and can utilize `require` and `import` statements. This "
"makes them ideal for handling complex requirements such as loading remote "
"modules or customizing the federation API. However, it's important to note "
"that delegate modules are an advanced feature and may not be necessary for "
"the majority of users."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/delegate-modules.adoc:8
#, no-wrap
msgid "Advantages of Using Delegate Modules"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:9
msgid ""
"Delegate modules provide several benefits when compared to the older "
"implementation involving the \"promise new promise\" syntax. By adopting "
"delegate modules, you can:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:10
msgid ""
"Gain fine-grained control over the glue code part of when Webpack requests a "
"remote and how it retrieves the container, without the brittleness and "
"restrictions of traditional methods."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:11
msgid ""
"Bundle a diverse range of entry point logic, effectively creating a "
"framework-like structure for managing federated remotes."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:12
msgid ""
"Access various methods for retrieving containers, including HTTP, file "
"systems, or even databases, without waiting for support from the module "
"federation team."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:13
msgid ""
"Implement robust middleware between the connection points of Webpack graphs, "
"gaining unprecedented control over graphs and their behavior."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:14
msgid ""
"Seamlessly integrate with different environments, such as edge workers or "
"server-side applications, without the need for complex top-to-bottom "
"implementation."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/delegate-modules.adoc:15
#, no-wrap
msgid "Exploring Use Cases"
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/delegate-modules.adoc:16
#, no-wrap
msgid "Fallbacks"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:17
msgid ""
"One of the primary use cases for delegate modules is handling fallbacks. In "
"scenarios where a remote is not available when expected, you can use "
"delegate modules to recover the federated remote seamlessly. This middleware "
"approach allows you to redirect Webpack to retrieve alternative code while "
"maintaining the same import interface, resulting in a more resilient "
"application."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/delegate-modules.adoc:18
#, no-wrap
msgid "Server-Side Integration"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:19
msgid ""
"Delegate modules can also be employed for server-side integration. They can "
"be used to fetch remote entries from various sources, such as databases or "
"file systems, without relying solely on HTTP. This approach offers enhanced "
"security and control over user-based access and data retrieval, allowing for "
"more granular access control and data protection."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/delegate-modules.adoc:20
#, no-wrap
msgid "Edge Side Includes (ESI) and Key Value (KV) Integration"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:21
msgid ""
"Delegate modules can support ESI and KV integration on edge networks by "
"fetching HTML and returning it as React components. This approach enables a "
"more agnostic method for distributed systems without requiring a complete "
"top-to-bottom implementation for edge deployment. By leveraging delegate "
"modules, you can simplify the process of implementing edge-side applications "
"and enhance their performance."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/delegate-modules.adoc:22
#, no-wrap
msgid "How Delegate Modules work"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:23
msgid ""
"A delegate module is a federated module that does not contain any code of "
"its own, but instead delegates the loading and execution of another module "
"to a different remote build. The delegate module acts as a placeholder for "
"the actual module until it is requested by the application."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:24
msgid ""
"The delegate module has two main properties: `remote` and `remoteType`. The "
"`remote` property specifies the name of the remote build that contains the "
"actual module. The `remoteType` property specifies the type of the remote "
"build, such as `var`, `script`, `module`, etc."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:25
msgid ""
"The delegate module also has a `get` method that returns a promise that "
"resolves to the actual module. The `get` method takes care of loading the "
"remote build and requesting the actual module from it."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:26
msgid ""
"The delegate module can be exposed by any remote build using the `exposes` "
"option in the Module Federation plugin configuration. For example, if you "
"have a remote build named `app1` that exposes a delegate module named "
"`delegate`, you can configure it like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/delegate-modules.adoc:27
#, no-wrap
msgid ""
"// webpack.config.js for app1\n"
"module.exports = {\n"
"  // ...\n"
"  plugins: [\n"
"    new ModuleFederationPlugin({\n"
"      name: \"app1\",\n"
"      filename: \"remoteEntry.js\",\n"
"      exposes: {\n"
"        \"./delegate\": \"./src/delegate.js\",\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:28
msgid ""
"The `src/delegate.js` file contains the code for the delegate module. For "
"example, if you want to delegate the loading of a module named `foo` from "
"another remote build named `app2`, you can write it like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/delegate-modules.adoc:29
#, no-wrap
msgid ""
"// src/delegate.js for app1\n"
"import { get } from \"webpack/container/entry/dynamic-remotes\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/delegate-modules.adoc:30
#, no-wrap
msgid ""
"export default {\n"
"  // Specify the name and type of the remote build\n"
"  remote: \"app2\",\n"
"  remoteType: \"var\",\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/delegate-modules.adoc:31
#, no-wrap
msgid ""
"  // Define a getter function that returns a promise for the actual module\n"
"  get: () => get(\"app2/foo\"),\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:32
msgid ""
"The `get` function uses the `get` function from the `webpack/container/entry/"
"dynamic-remotes` module, which is a helper function provided by webpack for "
"loading dynamic remotes. It takes the name of the remote build and the name "
"of the exposed module as arguments, and returns a promise that resolves to "
"the actual module."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:33
msgid ""
"The delegate module can then be consumed by any application that has access "
"to the remote build that exposes it. For example, if you have an application "
"named `host` that consumes the delegate module from `app1`, you can "
"configure it like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/delegate-modules.adoc:34
#, no-wrap
msgid ""
"// webpack.config.js for host\n"
"module.exports = {\n"
"  // ...\n"
"  plugins: [\n"
"    new ModuleFederationPlugin({\n"
"      name: \"host\",\n"
"      remotes: {\n"
"        // Specify the URL of the remote build that exposes the delegate module\n"
"        app1: \"app1@http://localhost:3001/remoteEntry.js\",\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:35
msgid ""
"The application can then import and use the delegate module like any other "
"federated module. For example:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/delegate-modules.adoc:36
#, no-wrap
msgid ""
"// src/index.js for host\n"
"import(\"./bootstrap\");\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/delegate-modules.adoc:37
#, no-wrap
msgid ""
"async function bootstrap() {\n"
"  // Import the delegate module from app1\n"
"  const delegate = await import(\"app1/delegate\");\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/delegate-modules.adoc:38
#, no-wrap
msgid ""
"  // Use the delegate module to get the actual module from app2\n"
"  const foo = await delegate.get();\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/delegate-modules.adoc:39
#, no-wrap
msgid ""
"  // Use the actual module as usual\n"
"  foo.doSomething();\n"
"}\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/delegate-modules.adoc:40
#, no-wrap
msgid "bootstrap();\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:41
msgid ""
"As you can see, the application does not need to know anything about the "
"remote build that contains the actual module. It only needs to know the name "
"of the remote build that exposes the delegate module. The delegate module "
"takes care of loading and resolving the actual module dynamically."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/delegate-modules.adoc:42
#, no-wrap
msgid "How to use delegate modules"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:43
msgid ""
"Delegate modules are useful when you want to share code across multiple "
"remote builds without having to expose them directly. For example, you may "
"have a common library that is used by several remote builds, but you don't "
"want to expose it as a federated module because it may change frequently or "
"have different versions. Instead, you can expose a delegate module that "
"delegates the loading of the common library to another remote build that is "
"responsible for maintaining and updating it."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:44
msgid "To use delegate modules, you need to follow these steps:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:45
msgid ""
"Create a remote build that contains the actual module you want to share. For "
"example, if you have a common library named `foo`, you can create a remote "
"build named `app2` that exposes it as a federated module."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:46
msgid ""
"Create a delegate module that delegates the loading of the actual module to "
"the remote build that contains it. For example, if you want to delegate the "
"loading of `foo` from `app2`, you can create a `delegate` module named "
"delegate in another remote build named `app1`."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:47
msgid ""
"Expose the delegate module as a federated module in the remote build that "
"contains it. For example, you can expose `delegate` as a federated module in "
"`app1`."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:48
msgid ""
"Consume the delegate module from any application or remote build that has "
"access to the remote build that exposes it. For example, you can consume "
"`delegate` from an application named `host` or another remote build named "
"`app3`."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:49
msgid "By using delegate modules, you can achieve several benefits:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:50
msgid ""
"You can avoid duplication and version conflicts between federated modules. "
"For example, if you have multiple remote builds that depend on `foo`, you "
"don't need to expose and load `foo` multiple times. You only need to load it "
"once through the delegate module."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:51
msgid ""
"You can decouple your remote builds from each other. For example, if you "
"change or update `foo`, you don't need to rebuild or redeploy your other "
"remote builds that depend on it. You only need to rebuild or redeploy "
"`app2`, and the other remote builds will get the latest version of `foo` "
"through the delegate module."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:52
msgid ""
"You can abstract away the details of your remote builds from your consumers. "
"For example, if you want to change the name or type of your remote build "
"that contains `foo`, you don't need to update your consumers that use it. "
"You only need to update your delegate module that points to it."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/delegate-modules.adoc:53
#, no-wrap
msgid "What to watch out for when using delegate modules"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:54
msgid ""
"Delegate modules are powerful and flexible, but they also come with some "
"caveats and limitations that you need to be aware of when using them."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:55
msgid ""
"Delegate modules introduce an extra level of indirection and complexity in "
"your Module Federation setup. You need to make sure that your consumers know "
"how to access and use your delegate modules correctly, and that your "
"delegate modules point to the right remote builds and modules."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:56
msgid ""
"Delegate modules rely on dynamic remotes, which means that they load remote "
"builds at runtime instead of at compile time. This may have some "
"implications for performance and security. For example, you may need to add "
"some caching and prefetching strategies to improve loading speed, and some "
"authentication and authorization mechanisms to prevent unauthorized access."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:57
msgid ""
"Delegate modules may not work well with some types of remote builds or "
"modules. For example, if your remote build uses a different bundler than "
"webpack, or if your module uses some non-standard features or syntax, you "
"may encounter some compatibility issues or errors when loading them through "
"delegate modules."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:58
msgid ""
"Therefore, before using delegate modules, you should carefully evaluate your "
"use case and requirements, and weigh the pros and cons of using them versus "
"other alternatives."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:60
msgid ""
"Delegate modules are a special type of federated module that allow you to "
"dynamically load and resolve other modules from different remote builds at "
"runtime. They enable you to share code across multiple applications without "
"having to rebuild or redeploy them every time you make a change."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:61
msgid ""
"In this guide, you learned everything you need to know about delegate "
"modules, how they work, how to use them, and what benefits they bring to "
"your Module Federation setup. You also learned some of the caveats and "
"limitations of using delegate modules, and what to watch out for when using "
"them."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:62
msgid ""
"Delegate modules are a powerful and flexible feature of webpack that can "
"help you improve your code sharing and decoupling across multiple "
"applications. However, they are not a silver bullet, and they may not suit "
"every use case or scenario. Therefore, you should always test and verify "
"your Module Federation setup before deploying it to production."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:63
msgid ""
"If you want to learn more about Module Federation and delegate modules, you "
"can check out the following resources:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:64
msgid ""
"https://webpack.js.org/concepts/module-federation/[Module Federation "
"documentation]"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:65
msgid ""
"https://webpack.js.org/concepts/module-federation/#dynamic-remotes[Dynamic "
"Remotes documentation]"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:66
msgid ""
"https://github.com/module-federation/module-federation-examples[Module "
"Federation examples]"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/delegate-modules.adoc:67
msgid "https://medium.com/@ScriptedAlchemy[Module Federation blog posts]"
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:1
#, no-wrap
msgid "Using Dynamic Remotes in Module Federation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:2
msgid ""
"This documentation page will discuss how to use dynamic remotes in Module "
"Federation to deploy micro frontend applications across various "
"environments. This guide is intended to provide elaborate and understandable "
"instructions for implementing dynamic remotes in your projects."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:4
msgid ""
"Dynamic remotes enable you to deploy the same micro frontend application in "
"testing, staging, and production environments. They also support on-premise, "
"cloud, and hybrid deployments simultaneously, and allow you to scale "
"multiple teams working on different parts of the architecture. In this "
"guide, we will cover four ways to use dynamic remotes:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:5
msgid "Environment variables"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:6
msgid "Webpack plugin external-remotes-plugin"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:7
msgid "Promise-based dynamic remotes"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:8
msgid "Dynamic remote containers"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:9
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:45
#, no-wrap
msgid "Environment Variables"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:10
msgid ""
"Environment variables provide a straightforward way to use dynamic remotes "
"by replacing localhost in your Webpack config with environment variables."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:11
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:17
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:25
#, no-wrap
msgid "Implementation"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:12
#, no-wrap
msgid ""
"module.exports = (env) => ({\n"
"  // ...\n"
"  plugins: [\n"
"    new ModuleFederationPlugin({\n"
"      name: \"Host\",\n"
"      remotes: {\n"
"        RemoteA: `RemoteA@${env.A_URL}/remoteEntry.js`,\n"
"        RemoteB: `RemoteB@${env.B_URL}/remoteEntry.js`,\n"
"      },\n"
"    }),\n"
"  ],\n"
"});\n"
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:13
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:19
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:30
#, no-wrap
msgid "Advantages and Limitations"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:14
msgid ""
"This approach is simple but requires building a new version for each "
"environment to update the URLs, which may not be ideal for enterprise use "
"cases and multiple deployment models."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:15
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:46
#, no-wrap
msgid "Webpack External Remotes Plugin"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:16
msgid ""
"The https://www.npmjs.com/package/external-remotes-plugin[external-remotes-"
"plugin], developed by Zack Jackson, allows you to resolve URLs at runtime "
"using templating. By defining window.appAUrl and window.appBUrl within your "
"application before loading any code from remote applications, you gain the "
"flexibility to define your URLs as needed."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:18
#, no-wrap
msgid ""
"plugins: [\n"
"  new ModuleFederationPlugin({\n"
"    name: \"Host\",\n"
"    remotes: {\n"
"      RemoteA: \"RemoteA@[window.appAUrl]/remoteEntry.js\",\n"
"      RemoteB: \"RemoteB@[window.appBUrl]/remoteEntry.js\",\n"
"    },\n"
"  }),\n"
"  new ExternalTemplateRemotesPlugin(),\n"
"],\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:20
msgid ""
"All you need to do is define window.appAUrl and window.appBUrl within our "
"application before you load any code from the remote applications."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:21
msgid ""
"Now you have the flexibility to define our URLs however you want. For "
"example, you could maintain a map of the host URLs to remote URLs for each "
"environment, use server-side rendering to allow the backend to define the "
"URLs, create a custom configuration management service, and many other "
"methods."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:22
msgid ""
"This approach is fully dynamic and would solve our use cases, but there is "
"still a slight limitation with this approach. We do not have complete "
"control over the loading lifecycle."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:23
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:47
#, no-wrap
msgid "Promise-Based Dynamic Remotes"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:24
msgid ""
"Module Federation allows you to define remote URLs as promises instead of "
"URL strings. You can use any promise as long as it fits the get/init "
"interface defined by Module Federation. This method offers more control over "
"the loading process but may be difficult to debug or maintain due to the "
"stringified code in the configuration file."
msgstr ""

#. type: Title ====
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:26
#, no-wrap
msgid "Webpack Configuration"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:27
#, no-wrap
msgid ""
"// Webpack config:\n"
"module.exports = {\n"
"  // ...\n"
"  plugins: [\n"
"    new ModuleFederationPlugin({\n"
"      name: \"Host\",\n"
"      remotes: {\n"
"        RemoteA: `promise new Promise(${fetchRemoteA.toString()})`,\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Title ====
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:28
#, no-wrap
msgid "Fetching Remote A Dynamically"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:29
#, no-wrap
msgid ""
"// Fetch Remote A dynamically:\n"
"const fetchRemoteA = (resolve) => {\n"
"  // We define a script tag to use the browser for fetching the remoteEntry.js file\n"
"  const script = document.createElement(\"script\");\n"
"  script.src = window.appAUrl; // This could be defined anywhere\n"
"  // When the script is loaded we need to resolve the promise back to Module Federation\n"
"  script.onload = () => {\n"
"    // The script is now loaded on window using the name defined within the remote\n"
"    const module = {\n"
"      get: (request) => window.RemoteA.get(request),\n"
"      init: (arg) => {\n"
"        try {\n"
"          return window.RemoteA.init(arg);\n"
"        } catch (e) {\n"
"          console.log(\"Remote A has already been loaded\");\n"
"        }\n"
"      },\n"
"    };\n"
"    }\n"
"    resolve(module);\n"
"  }\n"
"  // Lastly we inject the script tag into the document's head to trigger the script load\n"
"  document.head.appendChild(script);\n"
"}\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:31
msgid ""
"In this approach, we create a new script tag and inject it into the DOM to "
"fetch the remote JavaScript file. `window.appAUrl` contains the URL for the "
"remote app. While this method provides control over the loading lifecycle, "
"it is not the easiest to debug or maintain since it involves stringified "
"code within the configuration file."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:32
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:48
#, no-wrap
msgid "Dynamic Remote Containers"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:33
msgid ""
"Dynamic remote containers allow you to load remote applications "
"programmatically without defining any URLs in your Webpack configuration. "
"This enables developers to work on new remote applications that may not yet "
"be defined in the host application or allow partners and customers to inject "
"their remote modules into their deployment of your app."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:34
#, no-wrap
msgid "Implementation "
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:35
msgid "Remove the remotes field from the ModuleFederationPlugin configuration:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:36
#, no-wrap
msgid ""
"plugins: [\n"
"  new ModuleFederationPlugin({\n"
"    name: \"Host\",\n"
"    remotes: {},\n"
"  }),\n"
"],\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:37
msgid ""
"Before loading any remote apps, fetch the remote module using a dynamic "
"script tag and manually initialize the remote container:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:38
#, no-wrap
msgid ""
"(async () => {\n"
"  // Initializes the shared scope. Fills it with known provided modules from this build and all remotes\n"
"  await __webpack_init_sharing__(\"default\");\n"
"  const container = window.someContainer; // or get the container somewhere else\n"
"  // Initialize the container, it may provide shared modules\n"
"  await container.init(__webpack_share_scopes__.default);\n"
"  const module = await container.get(\"./module\");\n"
"})();\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:39
msgid ""
"Here, `container` refers to a remote app configured in the `remotes` field "
"in the host app's Webpack configuration, and module refers to one of the "
"items defined in the `exposes` field in the remote app's Webpack "
"configuration."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:40
msgid ""
"By injecting a script tag to fetch the remote container and storing it in "
"`window.someContainer`, you can ensure the code resolves to the same `get/"
"init` pattern used in earlier examples."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:41
msgid ""
"To use one of the modules exposed by the remote app, call `container."
"get(moduleName)` as demonstrated in the example above."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:42
#, no-wrap
msgid "Summary and Recommendations"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:43
msgid ""
"Using dynamic remotes, you can deploy your micro frontend to fetch remote "
"applications from any URL, allowing for deployment to multiple test "
"environments, on-premises, or in the cloud. Developers can choose whether to "
"use production versions of other remote applications or introduce new ones "
"dynamically."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:44
msgid "The four methods discussed in this guide are:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/dynamic-remotes.adoc:49
msgid ""
"Each method has its advantages and limitations. Choose the one that best "
"suits your project's requirements and complexity."
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/examples-demos.adoc:1
#, no-wrap
msgid "Examples and Demos"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:2
msgid ""
"In this page, you will find a list of examples and demos that showcase how "
"module federation works and how you can use it for various scenarios. These "
"examples and demos are meant to help you understand the concepts and "
"benefits of module federation, as well as provide you with some inspiration "
"and guidance for your own projects."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/examples-demos.adoc:3
#, no-wrap
msgid "How to use the repository"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:4
msgid ""
"The repository is organized into subdirectories, each containing a specific "
"example or demo of Module Federation. Each subdirectories has its own README "
"file that explains the purpose, setup, and configuration of the example or "
"demo. You can browse the subdirectories on GitHub or clone the repository to "
"your local machine."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:5
msgid "To clone the repository, run the following command:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/examples-demos.adoc:6
#, no-wrap
msgid "git clone https://github.com/module-federation/module-federation-examples.git\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:7
msgid ""
"Then, navigate to the subfolder of your choice and follow the instructions "
"in the README file. Most of the examples and demos require you to install "
"dependencies and run a development server using npm or yarn commands. For "
"example:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/examples-demos.adoc:8
#, no-wrap
msgid ""
"cd basic-host-remote # change directory to the example folder\n"
"npm install # install dependencies\n"
"npm start # start the development server\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:9
msgid ""
"You can then open your browser and visit the URLs specified in the README "
"file to see the example or demo in action."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/examples-demos.adoc:10
#, no-wrap
msgid "Examples and demos overview"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:11
#, no-wrap
msgid "**Native Federation**: Demonstrates Module Federation using esBuild, ESM, and Import Maps, with the concept applicable to other bundlers as well. Learn how to implement Module Federation natively without Webpack.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:12
#, no-wrap
msgid "**Native Federation React**: A React-specific example of Module Federation using esBuild, ESM, and Import Maps. Apply the native implementation of Module Federation in a React application.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:13
#, no-wrap
msgid "**Advanced API**: Showcases advanced API usage in Module Federation, highlighting techniques that can be found in other examples. Enhance your knowledge of Module Federation's advanced features.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:14
#, no-wrap
msgid "**Basic Host-Remote**: Illustrates how App 1 consumes remote components from App 2 in a simple host-remote configuration. Understand the fundamental concepts of Module Federation's host-remote architecture.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:15
#, no-wrap
msgid "**Create React App**: Learn how to implement Module Federation within a Create React App (CRA) project. Discover how to adapt CRA to support Module Federation.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:16
#, no-wrap
msgid "**Create React App with React App Rewired**: Implement Module Federation using CRA and React App Rewired, an alternative to ejecting from CRA. Explore a different way to configure CRA for Module Federation without ejecting.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:17
#, no-wrap
msgid "**HMR Remotes**: Demonstrates Hot Module Replacement (HMR) for remotes inside hosts, enabling seamless updates of remote components. Improve development experience with live updates.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:18
#, no-wrap
msgid "**Startup Code**: Features an advanced implementation that attaches initialization code to the remote container. This example is useful for dynamically setting publicPath in the remote, allowing more flexible deployment.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:19
#, no-wrap
msgid "**Dynamic Remotes in Node**: Learn how to load remotes dynamically in a Node.js environment, enabling runtime configuration of remote components.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:20
#, no-wrap
msgid "**Bi-Directional Hosts**: Shows how App 1 and App 2 consume components from each other, creating a bi-directional relationship between host applications. Explore advanced host-remote scenarios.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:21
#, no-wrap
msgid "**Self-Healing**: Implements a fallback mechanism to remote app vendors when a dependency fails to load. Enhance application resilience with self-healing capabilities.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:22
#, no-wrap
msgid "**Server-Side Rendering**: Demonstrates how to implement Server-Side Rendering (SSR) with App 1 and App 2, enabling better SEO and faster initial page loads.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:23
#, no-wrap
msgid "**Server-Side Rendering (Simplified)**: Provides a less complex boilerplate for SSR implementation in Module Federation, making it more accessible to developers.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:24
#, no-wrap
msgid "**Multi UI Framework Federation**: Shows how to federate multiple apps built with different technologies (React, Angular, Vue, etc.), enabling seamless integration across UI frameworks.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:25
#, no-wrap
msgid "**Dynamic System Host**: Teaches how to swap between remotes at runtime, allowing dynamic loading of remote components based on user interaction or other factors.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:26
#, no-wrap
msgid "**Redux Reducer Injection**: Demonstrates injecting Redux reducers dynamically into the host store at runtime, enabling modular and scalable state management.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:27
#, no-wrap
msgid "**Shared Routes**: Illustrates composing federated routes for a seamless user experience, enabling navigation between federated applications.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:28
#, no-wrap
msgid "**Nested Components**: Learn how to use nested remote components in a Module Federation setup, showcasing the flexibility of component composition.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:29
#, no-wrap
msgid "**Shared Context Provider**: Shows how App 1 and App 2 can share a Context Provider, enabling shared state management across federated applications.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:30
#, no-wrap
msgid "**Medusa Example**: Implements Module Federation Dashboard with a single example, demonstrating a practical application of Module Federation.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:31
#, no-wrap
msgid "**Non-UI Module**: Explores the use of Module Federation for non-UI components, such as utility functions or data processing modules.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:32
#, no-wrap
msgid "**Routing**: Teaches how to share router context between federated applications, enabling seamless navigation. An additional example, Routing 2, provides alternative techniques for sharing routing context.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:33
#, no-wrap
msgid "**Version Discrepancy**: Handles different dependency versions in federated apps without side effects. Learn to manage dependencies in federated applications without conflicts or performance issues.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:34
#, no-wrap
msgid "**TypeScript**: Demonstrates streaming TypeScript between module-federation apps, enabling better type safety and developer experience.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:35
#, no-wrap
msgid "**Angular Universal**: Presents a Remote and Host app with Server-Side Rendering (SSR), lazy modules, and components, showcasing Module Federation in an Angular Universal application.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:36
#, no-wrap
msgid "**NextJS Sidecar Build**: Describes a sidecar build enabling Module Federation alongside Next.js codebases, illustrating the integration of Module Federation with Next.js.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:37
#, no-wrap
msgid "**NextJS v12, v13**: Demonstrates the operation of Module Federation with Next.js versions 12 and 13 using the `nextjs-mf` package.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:38
#, no-wrap
msgid "**NextJS**: Showcases Module Federation operation with Next.js, using the `nextjs-mf` package to integrate the two technologies.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:39
#, no-wrap
msgid "**NextJS SSR**: Implements Server-Side Rendering with Next.js powered by software streams, using the `nextjs-ssr` package.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:40
#, no-wrap
msgid "**NextJS SSR via Delegates**: Provides custom glue code for containers and hosts using `nextjs-ssr`, enabling a more tailored integration of Module Federation and Next.js with Server-Side Rendering.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:41
#, no-wrap
msgid "**Building a Plugin-based Workflow Designer**: An external example demonstrating how to build a plugin-based workflow designer using Angular and Module Federation.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:42
#, no-wrap
msgid "**Vue.js**: Offers a simple host/remote example with Vue 3.0, using render functions or Single File Components (SFC). Learn how to integrate Module Federation with Vue 3 applications.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:43
#, no-wrap
msgid "**Vue 2 in Vue 3**: Demonstrates a Vue 3 application loading a remote Vue 2 component, enabling cross-version component sharing in a Vue.js ecosystem.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:44
#, no-wrap
msgid "**Vue2 SSR**: Showcases the use of Module Federation as a service in a Server-Side Rendering scenario with Vue 2.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:45
#, no-wrap
msgid "**React & NextJS Host/Remote**: Presents examples of React and NextJS as host/remote, illustrating Module Federation capabilities in both React and NextJS applications.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:46
#, no-wrap
msgid "**Different React Versions in Isolation**: Offers a simple host/remote example where the apps have different React and ReactDOM versions and don't share any dependencies. Learn how to handle version discrepancies without conflicts.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:47
#, no-wrap
msgid "**CSS Isolated Host and Remote**: Demonstrates preventing CSS leakage between federated applications, ensuring styling remains isolated to the intended components.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:48
#, no-wrap
msgid "**vue3-demo-federation-with-vite**: Showcases integrated projects with Webpack and Vite Federation, where both Webpack and Vite play the roles of host and remote.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:49
#, no-wrap
msgid "**quasar-cli-vue3-webpack-javascript**: Teaches how to integrate Module Federation with Quasar apps running Vue 3 using Quasar CLI (JavaScript).\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:50
#, no-wrap
msgid "**UMD Federation**: Demonstrates support for importing UMD remote modules, broadening the range of supported module formats.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:51
#, no-wrap
msgid "**Modernjs**: Provides an example of basic Module Federation usage in the Modern.js framework.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:52
#, no-wrap
msgid "**Modernjs Medusa**: Illustrates the use of Medusa in the Modern.js framework, demonstrating integration with a popular Module Federation dashboard.\n"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/examples-demos.adoc:53
#, no-wrap
msgid "Summary and conclusion"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:54
msgid ""
"In this documentation page, you have learned how to use the Module "
"Federation GitHub repository, which contains a collection of examples and "
"demos for different use cases and scenarios of Module Federation. You have "
"also learned about the various aspects and features of Module Federation, "
"such as sharing modules, dynamic loading, communication, error handling, "
"optimization, testing, debugging, and deployment. You have also found links "
"to other resources and tutorials that will help you get started with Module "
"Federation."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/examples-demos.adoc:55
msgid ""
"We hope you find this documentation page useful and informative. If you have "
"any questions, feedback, or suggestions, please feel free to open an issue "
"or a pull request on the [repository](https://github.com/module-federation/"
"module-federation-examples). Happy coding! 😊"
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:1
#, no-wrap
msgid "Module Federation: Getting Started: The Practical Part"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:2
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:2
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:2
#, no-wrap
msgid "Introduction"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:3
msgid ""
"This guide will walk you through the practical steps of getting started with "
"Module Federation. We will build two separate Single Page Applications "
"(SPAs) that use Module Federation to share components during runtime."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:4
#, no-wrap
msgid "Setting Up the Environment"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:5
msgid ""
"First, we need to set up our environment. We will be using a yarn mono-repo "
"structure for simplicity. Start by creating a new project folder with the "
"following `package.json` to allow us to run our two SPAs at the same time:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:6
#, no-wrap
msgid ""
"{\n"
"  \"name\": \"federation-example\",\n"
"  \"private\": true,\n"
"  \"workspaces\": [\n"
"    \"packages/*\"\n"
"  ],\n"
"  \"scripts\": {\n"
"    \"start\": \"wsrun --parallel start\",\n"
"    \"build\": \"yarn workspaces run build\",\n"
"    \"dev\": \"wsrun --parallel dev\"\n"
"  },\n"
"  \"devDependencies\": {\n"
"    \"wsrun\": \"^5.2.0\"\n"
"  }\n"
"}\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:7
msgid ""
"Next, create two directories for our SPAs to live in under a new packages "
"directory called `application-a` and `application-b`. These will "
"respectively contain the following `package.json` files:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:8
#, no-wrap
msgid ""
"// packages/application-a/package.json\n"
"{\n"
"  \"name\": \"application-a\",\n"
"  \"version\": \"1.0.0\",\n"
"  \"private\": true,\n"
"  \"scripts\": {\n"
"    \"start\": \"serve dist -p 3001\",\n"
"    \"build\": \"webpack --mode production\",\n"
"    \"dev\": \"concurrently \\\"webpack --watch\\\" \\\"serve dist -p 3001\\\"\"\n"
"  },\n"
"  \"dependencies\": {\n"
"    \"react\": \"^16.13.1\",\n"
"    \"react-dom\": \"^16.13.1\"\n"
"  },\n"
"  \"devDependencies\": {\n"
"    \"@babel/core\": \"^7.8.6\",\n"
"    \"@babel/preset-react\": \"^7.8.3\",\n"
"    \"babel-loader\": \"^8.0.6\",\n"
"    \"concurrently\": \"^5.1.0\",\n"
"    \"html-webpack-plugin\": \"git://github.com/ScriptedAlchemy/html-webpack-plugin#master\",\n"
"    \"serve\": \"^11.3.0\",\n"
"    \"webpack\": \"git://github.com/webpack/webpack.git#dev-1\",\n"
"    \"webpack-cli\": \"^3.3.11\"\n"
"  }\n"
"}\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:9
#, no-wrap
msgid ""
"// packages/application-b/package.json\n"
"{\n"
"  \"name\": \"application-b\",\n"
"  \"version\": \"1.0.0\",\n"
"  \"private\": true,\n"
"  \"scripts\": {\n"
"    \"start\": \"serve dist -p 3002\",\n"
"    \"build\": \"webpack --mode production\",\n"
"    \"dev\": \"concurrently \\\"webpack --watch\\\" \\\"serve dist -p 3002\\\"\"\n"
"  },\n"
"  \"dependencies\": {\n"
"    \"react\": \"^16.13.1\",\n"
"    \"react-dom\": \"^16.13.1\"\n"
"  },\n"
"  \"devDependencies\": {\n"
"    \"@babel/core\": \"^7.8.6\",\n"
"    \"@babel/preset-react\": \"^7.8.3\",\n"
"    \"babel-loader\": \"^8.0.6\",\n"
"    \"concurrently\": \"^5.1.0\",\n"
"    \"html-webpack-plugin\": \"git://github.com/ScriptedAlchemy/html-webpack-plugin#master\",\n"
"    \"serve\": \"^11.3.0\",\n"
"    \"webpack\": \"git://github.com/webpack/webpack.git#dev-1\",\n"
"    \"webpack-cli\": \"^3.3.11\"\n"
"  }\n"
"}\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:10
msgid "Install the dependencies with `yarn`."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:11
#, no-wrap
msgid "Bootstrapping the SPAs"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:12
msgid ""
"Next, we need to bootstrap our SPA React applications. Create a `src` "
"directory in each of our packages that contain the following files:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:13
#, no-wrap
msgid ""
"// packages/application-{a,b}/src/index.js\n"
"import('./bootstrap');\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:14
#, no-wrap
msgid ""
"// packages/application-{a,b}/src/bootstrap.jsx\n"
"import React from 'react';\n"
"import ReactDOM from 'react-dom';\n"
"import App from './app';\n"
"ReactDOM.render(<App />, document.getElementById('root'));\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:15
msgid ""
"We also need a `public` directory in each of the packages with the following "
"HTML template:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:16
#, no-wrap
msgid ""
"// packages/application-{a,b}/public/index.html\n"
"<!DOCTYPE html>\n"
"<html lang=\"en\">\n"
"  <head>\n"
"  </head>\n"
"  <body>\n"
"    <div id=\"root\"></div>\n"
"  </body>\n"
"</html>\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:17
msgid ""
"Now we can implement our two `app.jsx` files for each application that will "
"house our shared components:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:18
#, no-wrap
msgid ""
"// packages/application-a/src/app.jsx\n"
"const HtmlWebpackPlugin = require('html-webpack-plugin');\n"
"const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:19
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:27
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:33
#, no-wrap
msgid "const mode = process.env.NODE_ENV || 'production';\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:20
#, no-wrap
msgid ""
"module.exports = {\n"
"  mode,\n"
"  entry: './src/index',\n"
"  devtool: 'source-map',\n"
"  optimization: {\n"
"    minimize: mode === 'production',\n"
"  },\n"
"  resolve: {\n"
"    extensions: ['.jsx', '.js', '.json'],\n"
"  },\n"
"  module: {\n"
"    rules: [\n"
"      {\n"
"        test: /\\.jsx?$/,\n"
"        loader: require.resolve('babel-loader'),\n"
"        options: {\n"
"          presets: [require.resolve('@babel/preset-react')],\n"
"        },\n"
"      },\n"
"    ],\n"
"  },\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:21
#, no-wrap
msgid ""
"  plugins: [\n"
"    new HtmlWebpackPlugin({\n"
"      template: './public/index.html',\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:22
msgid ""
"From the root of the application, you should now be able to access your two "
"SPAs on http://localhost:3001 and http://localhost:3002 when running `yarn "
"dev`."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:23
#, no-wrap
msgid "Start Federating"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:24
msgid ""
"Now that we have two independent SPAs running, let's go ahead and make each "
"of the SPAs a Federated Container as well as Consumer. We accomplish this by "
"utilizing the new `ModuleFederationPlugin` that is part of the Webpack 5 "
"Core."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:25
msgid "We'll start by adding the `ModuleFederationPlugin` to Application A:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:26
#, no-wrap
msgid ""
"// packages/application-a/webpack.config.js\n"
"const HtmlWebpackPlugin = require('html-webpack-plugin');\n"
"const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:28
#, no-wrap
msgid ""
"module.exports = {\n"
"  mode,\n"
"  entry: './src/index',\n"
"  output: {\n"
"    publicPath: 'http://localhost:3001/', // New\n"
"  },\n"
"  devtool: 'source-map',\n"
"  optimization: {\n"
"    minimize: mode === 'production',\n"
"  },\n"
"  resolve: {\n"
"    extensions: ['.jsx', '.js', '.json'],\n"
"  },\n"
"  module: {\n"
"    rules: [\n"
"      {\n"
"        test: /\\.jsx?$/,\n"
"        loader: require.resolve('babel-loader'),\n"
"        options: {\n"
"          presets: [require.resolve('@babel/preset-react')],\n"
"        },\n"
"      },\n"
"    ],\n"
"  },\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:29
#, no-wrap
msgid ""
"  plugins: [\n"
"    // New\n"
"    new ModuleFederationPlugin({\n"
"      name: 'application_a',\n"
"      library: { type: 'var', name: 'application_a' },\n"
"      filename: 'remoteEntry.js',\n"
"      exposes: {\n"
"        'SayHelloFromA': './src/app',\n"
"      },\n"
"      remotes: {\n"
"        'application_b': 'application_b',\n"
"      },\n"
"      shared: ['react', 'react-dom'],\n"
"    }),\n"
"    new HtmlWebpackPlugin({\n"
"      template: './public/index.html',\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:30
msgid ""
"This specifies that Application A exposes its `App` component to the world "
"as a Federated Module called `SayHelloFromA`, while whenever you import from "
"`application_b`, those modules should come from Application B at runtime."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:31
msgid ""
"We will do the same thing for Application B, specifying that it exposes its "
"`App` component as `SayHelloFromB` and whenever we import from "
"`application_a`, those modules should come from Application A at runtime:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:32
#, no-wrap
msgid ""
"// packages/application-b/webpack.config.js\n"
"const HtmlWebpackPlugin = require('html-webpack-plugin');\n"
"const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:34
#, no-wrap
msgid ""
"module.exports = {\n"
"  mode,\n"
"  entry: './src/index',\n"
"  output: {\n"
"    publicPath: 'http://localhost:3002/', // New\n"
"  },\n"
"  devtool: 'source-map',\n"
"  optimization: {\n"
"    minimize: mode === 'production',\n"
"  },\n"
"  resolve: {\n"
"    extensions: ['.jsx', '.js', '.json'],\n"
"  },\n"
"  module: {\n"
"    rules: [\n"
"      {\n"
"        test: /\\.jsx?$/,\n"
"        loader: require.resolve('babel-loader'),\n"
"        options: {\n"
"          presets: [require.resolve('@babel/preset-react')],\n"
"        },\n"
"      },\n"
"    ],\n"
"  },\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:35
#, no-wrap
msgid ""
"  plugins: [\n"
"    // New\n"
"    new ModuleFederationPlugin({\n"
"      name: 'application_b',\n"
"      library: { type: 'var', name: 'application_b' },\n"
"      filename: 'remoteEntry.js',\n"
"      exposes: {\n"
"        'SayHelloFromB': './src/app',\n"
"      },\n"
"      remotes: {\n"
"        'application_a': 'application_a',\n"
"      },\n"
"      shared: ['react', 'react-dom'],\n"
"    }),\n"
"    new HtmlWebpackPlugin({\n"
"      template: './public/index.html',\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:36
msgid ""
"The last step before we can start to utilize the exposed components is to "
"specify for the runtime where the Remote Entries for the Containers you wish "
"to consume are located. We do this by adding a script tag to the HTML "
"template of the remotes you wish to consume."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:37
#, no-wrap
msgid ""
"// packages/application-a/public/index.html\n"
"<head>\n"
"  <!-- The remote entry for Application B -->\n"
"  <script src=\"http://localhost:3002/remoteEntry.js\"></script>    \n"
"</head>\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:38
#, no-wrap
msgid ""
"// packages/application-b/public/index.html\n"
"<head>\n"
"  <!-- The remote entry for Application A -->\n"
"  <script src=\"http://localhost:3001/remoteEntry.js\"></script>    \n"
"</head>\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:39
msgid ""
"The remote entry files are tiny mappings for Webpack to resolve the "
"individually imported modules without transferring unnecessary information. "
"They are also responsible for enabling the sharing of libraries that the "
"packages use, in this case, when Application A requests Application B's "
"`SayHelloFromB` component, we do not send the React or ReactDOM over the "
"wire as Application A already has a copy of it."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:40
#, no-wrap
msgid "Consuming Federated Components"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:41
msgid ""
"Now that our two SPA applications are Container Hosts and Consumers, we can "
"start to consume the shared components. In the Цebpack config we had "
"specified the names of the containers as `application_a` and "
"`application_b`, so that is where we will import the components from."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:42
msgid ""
"Starting with Application A, we can render the `SayHelloFromB` component "
"like so from within the bootstrap file:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:43
#, no-wrap
msgid ""
"// packages/application-a/src/bootstrap.jsx\n"
"import React from 'react';\n"
"import ReactDOM from 'react-dom';\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:44
#, no-wrap
msgid "import SayHelloFromB from 'application_b/SayHelloFromB';\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:45
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:50
#, no-wrap
msgid "import App from './app';\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:46
#, no-wrap
msgid ""
"ReactDOM.render(\n"
"  <>\n"
"      <App />\n"
"      <SayHelloFromB />\n"
"  </>,\n"
"  document.getElementById('root')\n"
");\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:47
msgid ""
"Application B will look very similar, just importing from `application_a` "
"instead:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:48
#, no-wrap
msgid ""
"// packages/application-b/src/bootstrap.jsx\n"
"import React from 'react';\n"
"import ReactDOM from 'react-dom';\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:49
#, no-wrap
msgid "import SayHelloFromA from 'application_a/SayHelloFromA';\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:51
#, no-wrap
msgid ""
"ReactDOM.render(\n"
"  <>\n"
"    <App />\n"
"    <SayHelloFromA />\n"
"  </>,\n"
"  document.getElementById('root')\n"
");\n"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:52
#, no-wrap
msgid "Additional Notes"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:53
msgid ""
"Looking at the network log for Application A you will see that we load two "
"files from Application B, the remoteEntry.js file, then the 977.js that "
"contains the SayHelloFromB component."
msgstr ""

#. TODO: image
#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:54
msgid ""
"Visiting Application B for the first time, you’ll notice we have already "
"cached the remoteEntries for both Application B and Application A."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started-practical.adoc:56
msgid ""
"Congratulations! You have just created your first Webpack 5 Federated "
"projects. Now go out and build something awesome!"
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/getting-started.adoc:1
#, no-wrap
msgid "What is Module Federation?"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started.adoc:2
msgid ""
"Module Federation is a concept that allows developers to share code and "
"resources across multiple JavaScript applications, or micro-frontends. In a "
"traditional web application, all the code for a single page is usually "
"contained within a single codebase. This can lead to monolithic applications "
"that are difficult to maintain and scale."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started.adoc:3
msgid ""
"With Module Federation, code can be split into smaller, independently "
"deployable modules that can be loaded on demand when they are needed. This "
"allows micro-frontends to be developed and deployed independently, which "
"reduces coordination between teams and allows for faster development cycles."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started.adoc:4
msgid ""
"At its core, Module Federation is based on the idea of remote loading of "
"JavaScript modules. This means that instead of having all the code for a "
"single application loaded at once, the code can be split into smaller, "
"independently deployable modules that can be loaded on demand when they are "
"needed."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started.adoc:5
msgid ""
"Module Federation is implemented using the Webpack module bundler. Webpack "
"is a tool that allows developers to bundle JavaScript modules into a single "
"file that can be loaded by a web browser. With Module Federation, Webpack is "
"extended to allow modules to be loaded from other applications, rather than "
"just from within the same application."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started.adoc:6
msgid ""
"To use Module Federation, developers need to configure their Webpack builds "
"to expose certain modules to other applications and to consume modules from "
"other applications. This can be done using the `exposes` and `remotes` "
"options in the Webpack configuration."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started.adoc:7
msgid ""
"The `exposes` option is used to expose certain modules from an application "
"to other applications. This tells Webpack which modules should be available "
"to other applications when they are loaded remotely."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started.adoc:8
msgid ""
"The `remotes` option is used to consume modules from other applications. "
"This tells Webpack which modules should be loaded remotely from other "
"applications when they are needed."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started.adoc:9
msgid ""
"Once the Webpack configurations for each application have been set up, the "
"applications can be deployed independently. When a user visits a page that "
"includes multiple micro-frontends, the micro-frontends will dynamically load "
"the code they need from other micro-frontends using the `exposes` and "
"`remotes` options."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started.adoc:11
msgid ""
"In summary, Module Federation allows developers to share code and resources "
"across micro-frontends, which reduces duplication and improves code "
"maintainability. By allowing micro-frontends to be developed and deployed "
"independently, Module Federation reduces the need for coordination between "
"teams and allows for faster development cycles."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/getting-started.adoc:12
msgid ""
"Having built a necessary theoretical foundation of Module Federation, let us "
"now pivot towards the practical aspect and embark on the journey of actual "
"implementation, exploring the possibilities Module Federation has to offer: "
"xref:getting-started-practical.adoc[Getting Started with Module Federation]"
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/history.adoc:1
#, no-wrap
msgid "History of Module Federation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/history.adoc:2
msgid ""
"Module Federation is a relatively new feature in the world of web "
"development, first introduced in Webpack 5. In this guide, we'll explore the "
"history of Module Federation, including its origins, evolution, and the "
"major milestones that led to its development."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/history.adoc:3
#, no-wrap
msgid "Origins of Module Federation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/history.adoc:4
msgid ""
"The idea of sharing code between multiple applications is not a new one. In "
"fact, it has been a common practice in software development for many years. "
"However, the rise of microservices and the need for highly modular and "
"scalable architectures in web development created a new demand for code "
"sharing across multiple applications."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/history.adoc:5
msgid ""
"The first attempts to solve this problem involved using iframes or server-"
"side includes to embed code from one application into another. However, "
"these approaches had significant limitations in terms of performance, "
"flexibility, and security."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/history.adoc:6
#, no-wrap
msgid "Webpack 5 and the Birth of Module Federation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/history.adoc:7
msgid ""
"In 2020, Webpack 5 was released with a new feature called \"Module "
"Federation\". This feature was a significant step forward in the evolution "
"of code sharing in web development."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/history.adoc:8
msgid ""
"Module Federation allowed developers to share entire modules between "
"multiple applications, not just Redux-related code. This was accomplished by "
"extending the Webpack module bundler to support remote loading of modules "
"and using a runtime called the \"Module Federation Runtime\" to handle the "
"loading and dependency resolution of remote modules."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/history.adoc:9
#, no-wrap
msgid "Evolution of Module Federation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/history.adoc:10
msgid ""
"Since its introduction in Webpack 5, Module Federation has continued to "
"evolve and improve. In Webpack 5, it was limited to sharing modules between "
"applications built with Webpack. However, in Webpack 5.1, support was added "
"for sharing modules between applications built with different module "
"bundlers, such as Rollup or Parcel."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/history.adoc:11
msgid ""
"In addition, the community has developed a number of tools and plugins to "
"extend the capabilities of Module Federation, including the \"Module "
"Federation Plugin\" for Next.js, and the \"Federation Plugin\" for Snowpack."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/history.adoc:12
#, no-wrap
msgid "Future of Module Federation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/history.adoc:13
msgid ""
"Module Federation has the potential to significantly change the way we "
"approach code sharing in web development. As it continues to evolve and "
"improve, it is likely that we will see more widespread adoption and "
"integration with other tools and frameworks."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/history.adoc:14
msgid "Some potential future directions for Module Federation include:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/history.adoc:15
msgid "Improved support for sharing dynamic and asynchronous modules."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/history.adoc:16
msgid "Integration with serverless functions and other backend services."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/history.adoc:17
msgid ""
"Support for sharing modules across multiple programming languages and "
"environments."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/history.adoc:18
msgid ""
"As Module Federation continues to evolve, we will continue updating "
"documentation, to provide you with the best techniques on how to adopt and "
"integrate with other tools and frameworks."
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:1
#, no-wrap
msgid "Implementing Module Federation in Rollup.JS"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:3
msgid ""
"Rollup.JS, a popular JavaScript module bundler, is known for its efficiency "
"and flexibility. With the advent of Module Federation in Webpack 5, it's "
"time to bring this powerful feature into the Rollup.JS ecosystem. This guide "
"will walk you through the process of implementing Module Federation in "
"Rollup.JS, allowing you to share code between independently bundled "
"applications seamlessly."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:4
#, no-wrap
msgid "Enabling Hosts in Rollup.JS"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:5
msgid ""
"The first step in integrating Module Federation with Rollup.JS is to enable "
"your Rollup.JS bundle to act as a Host. This capability allows your bundle "
"to consume modules from Remotes built with Webpack. This feature is "
"facilitated by the `@module-federation/rollup-federation` plugin, which is "
"available directly from the Module Federation Organization."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:6
msgid ""
"You can find the plugin on https://www.npmjs.com/package/@module-federation/"
"rollup-federation[npm] and an example of its usage in https://github.com/"
"module-federation/module-federation-examples/tree/master/rollup-federation-"
"demo[module-federation-examples] repository."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:7
#, no-wrap
msgid "Consuming a Remote"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:8
msgid ""
"Let's assume we have a Webpack Remote located at `http://localhost:8081/"
"remote-entry.js` that was built to target SystemJS and exposes a `./hello` "
"module that exports a default function. We can consume this remote in a "
"Rollup.JS build with the following setup:"
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:9
#, no-wrap
msgid "rollup.config.js"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:10
msgid ""
"In this example, we configure the `@module-federation/rollup-federation` "
"plugin and alias the remote as `webpack_remote`. The key is the name we will "
"be importing from in our JavaScript modules, and the value is the name in "
"our SystemJS import map."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:11
#, no-wrap
msgid "import federation from '@module-federation/rollup-federation';\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:12
#, no-wrap
msgid ""
"export default {\n"
"  input: './src/index.js',\n"
"  output: {\n"
"    format: 'system',\n"
"    dir: './dist'\n"
"  },\n"
"  plugins: [\n"
"    federation({\n"
"      remotes: {\n"
"        'webpack_remote': 'webpack_remote'\n"
"      },\n"
"    })\n"
"  ]\n"
"};\n"
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:13
#, no-wrap
msgid "src/index.js"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:14
msgid ""
"Next, we dynamically import the remote `hello` module from the Webpack "
"Remote we have aliased as `webpack_remote` in the plugin."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:15
#, no-wrap
msgid ""
"(async () => {\n"
"  // Import the hello module from the remote\n"
"  const hello = await import('webpack_remote/hello');\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:16
#, no-wrap
msgid ""
"  // Call the default export of the remote hello module\n"
"  hello.default();\n"
"})();\n"
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:17
#, no-wrap
msgid "index.html"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:18
msgid ""
"Finally, we configure the SystemJS import map to recognize where "
"`webpack_remote` is located and start our app by importing the main entry "
"point."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:19
#, no-wrap
msgid ""
"<!doctype html>\n"
"<html>\n"
"<body>\n"
"  <script src=\"https://cdn.jsdelivr.net/npm/systemjs/dist/system.js\"></script>\n"
"  <script type=\"systemjs-importmap\">\n"
"    {\n"
"      \"webpack_remote\": \"http://localhost:8081/remote-entry.js\",\n"
"      \"main\": \"./dist/main.js\"\n"
"    }\n"
"  </script>\n"
"  <script type=\"systemjs-module\" src=\"import:main\"></script>\n"
"</body>\n"
"</html>\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:20
msgid "Congratulations! You are now consuming Federated Modules in Rollup.JS."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:21
msgid ""
"For more advanced use-cases, check out the Module Federation Examples "
"repository located at https://github.com/module-federation//tree/master/"
"rollup-federation-demo[module-federation-examples] repository."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:22
#, no-wrap
msgid "Limitations and Future Work"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:23
msgid ""
"As of now, a Rollup.JS bundle can only act as a Host, meaning it can consume "
"federated modules and share runtime vendor dependencies with the Remotes it "
"consumes. The potential to act as a Remote, and thereby enable Bidirectional-"
"Hosts, is being considered for future development based on community "
"interest."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:24
msgid ""
"For any questions or suggestions, feel free to reach out on Twitter "
"@ebey_jacob. Contributions to the examples repo for AMD, fixes, or additions "
"to the plugin are always welcome!"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:25
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:122
msgid "## Conclusion"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-rollupjs.adoc:26
msgid ""
"Integrating Module Federation into Rollup.JS opens up new possibilities for "
"code sharing between independently bundled applications. By following the "
"steps outlined in this guide, you can leverage the power of Module "
"Federation in your Rollup.JS projects, enhancing efficiency and "
"collaboration."
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:1
#, no-wrap
msgid "Module Federation: SplitChunksPlugin & Sharing and Bundling Multiple Vendor Bundles Into One Vendor Bundle"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:3
msgid ""
"The following guide is based on a project that used Webpack's "
"ModuleFederationPlugin to share both component and vendor library modules "
"between two web applications. The challenge was to share two-digit-number of "
"different vendor modules, but bundle them into one common vendors chunk to "
"reduce the network load of having dozens of different requests "
"simultaneously. The solution was to bundle all different vendor bundles into "
"one using `SplitChunksPlugin`, resulting in only one request from the host "
"app to the remote app when the vendor library is needed."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:4
msgid ""
"This guide will demonstrate how to use Webpack's `ModuleFederationPlugin` to "
"share modules between two simple web applications, and how to bundle "
"supplementary vendor libraries' bundles into one bundle using Webpack's "
"`SplitChunksPlugin`, so that they can be shared between the remote and host "
"applications as one chunk and improve performance."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:5
#, no-wrap
msgid "Project Structure"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:6
msgid ""
"The project consists of the host app (app1), which loads a shared function, "
"a shared component, and a vendors bundle from the remote app (app2). This is "
"a simple demonstration of the work of Webpack's ModuleFederationPlugin and "
"SplitChunksPlugin."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:7
#, no-wrap
msgid "Setup"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:8
msgid ""
"After creating two directories, one for the host and one for the remote app, "
"navigate into the `Remote_App` directory. Initialize an npm project and "
"install webpack to produce bundles of our code."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:9
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:18
#, no-wrap
msgid ""
"npm init\n"
"npm i webpack webpack-cli --save-dev\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:10
msgid ""
"Create the `src` directory which will hold our shared modules. Create a new "
"file called `bootstrap.js` and another directory - `sharedModules`. In the "
"`sharedModules` directory, create our first shared function - "
"`mySharedFunction.js`. Leave this file empty for now."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:11
msgid "Populate `bootstrap.js` with the following line:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:12
#, no-wrap
msgid "import('./sharedModules/mySharedFunction');\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:13
msgid ""
"For the Module Federation to work, the best way to implement the sharing "
"between code is through dynamic imports like in example above, although "
"sharing through eager consumption of modules is also possible and static "
"imports of shared modules are supported as well. This is because the shared "
"components/vendors are loaded at runtime and it's best to have them "
"asynchronously imported."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:14
msgid ""
"Now, navigate back out of the source directory and create a `webpack."
"configuration.js` file which is the configuration file for using Webpack "
"with our remote app:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:15
#, no-wrap
msgid ""
"const path = require('path');\n"
"module.exports = {\n"
" entry: './src/bootstrap.js',\n"
" output: {\n"
"   filename: '[name].bundle.js',\n"
"   path: path.resolve(__dirname, 'dist'),\n"
"   clean: true\n"
" },\n"
" mode: 'development'\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:16
msgid ""
"The entry point would be our `bootstrap.js` file. This file would act as an "
"entry point for the dynamic imports of all the shared modules you could "
"have. Every bundle will be outputted to the `dist` directory."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:17
msgid ""
"Repeat the same process for the host app. Initialize an npm project and "
"install webpack."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:19
msgid ""
"Create a `bootstrap.js` file and an empty `mainLogic.js` file. This file "
"will later on contain dynamic imports of the shared modules."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:20
#, no-wrap
msgid "import('./mainLogic');\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:21
msgid ""
"You can copy-paste the configuration file for Webpack in this host app from "
"the remote app. It contains almost the same configuration, except for the "
"filename prop, it will be only called `bundle.js` as we will have only that "
"one app-related bundle."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:22
#, no-wrap
msgid "filename: 'bundle.js'\n"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:23
#, no-wrap
msgid "Hosting the Apps"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:24
msgid ""
"To host the apps, we use `webpack-dev-server`, a CLI-based tool for starting "
"a static server for your assets. Besides installing `webpack-dev-server`, we "
"also need the `HtmlWebpackPlugin` so we can render HTML files. Therefore, "
"you need to navigate into both host and remote app directories and run the "
"following commands:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:25
#, no-wrap
msgid ""
"npm i webpack-dev-server --save-dev\n"
"npm i html-webpack-plugin --save-dev\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:26
msgid ""
"Next, we need to extend both webpack configuration files, of the host app as "
"well as the remote:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:27
#, no-wrap
msgid ""
"devServer: {\n"
" static: path.join(__dirname,'dist'),\n"
" port: 3001\n"
"},\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:28
msgid ""
"After including this option in our webpack configuration file of the host, "
"the content from the `dist` directory will be rendered on port 3001. Let's "
"create one HTML page now:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:29
#, no-wrap
msgid ""
"<!DOCTYPE html>\n"
"<html lang=\"en\">\n"
"<head>\n"
"    <meta charset=\"UTF-8\">\n"
"    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n"
"    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n"
"    <title><%= htmlWebpackPlugin.options.title %> </title>\n"
"</head>\n"
"<body>\n"
"    HOST APP\n"
"</body>\n"
"</html>\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:30
msgid ""
"The `htmlWebpackPlugin.options.title` comes from the title property of the "
"`HtmlWebpackPlugin` we define in the next step."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:31
msgid ""
"At the top of the `webpack.configuration.js` file, we need an import for the "
"plugin:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:32
#, no-wrap
msgid "const HtmlWebpackPlugin = require('html-webpack-plugin');\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:33
msgid ""
"We also create a plugins prop in the webpack configuration file containing "
"our `HtmlWebpackPlugin` setup like the following:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:34
#, no-wrap
msgid ""
"plugins: [\n"
"    new HtmlWebpackPlugin({\n"
"      title: 'Host app',\n"
"      template: path.resolve(__dirname, './src/template.html')\n"
"    })\n"
"  ]\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:35
msgid ""
"Now you can add this command to your npm scripts which will start the "
"server. In the `package.json`, under scripts add `\"start\": \"webpack serve "
"--open\"`. Now if you execute `npm start` in the terminal, the server should "
"be started at port `localhost:3001`. Only a white background will be shown "
"with the text \"HOST APP\" written on the screen."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:36
msgid ""
"The same steps are replicated in the remote app. Firstly, install the "
"required npm packages, then create a `template.html` and add the npm script "
"for starting the server in the `package.json`."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:37
msgid ""
"Update the `webpack.configuration.js` file of the remote app to look like "
"the following:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:38
#, no-wrap
msgid ""
"const HtmlWebpackPlugin = require('html-webpack-plugin');\n"
"const path = require('path');\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:39
#, no-wrap
msgid ""
"module.exports = {\n"
"  entry: './src/bootstrap.js',\n"
"  output: {\n"
"    filename: '[name].bundle.js',\n"
"    path: path.resolve(__dirname, 'dist'),\n"
"    clean: true\n"
"  },\n"
"  mode: 'development',\n"
"  devServer: {\n"
"    static: path.join(__dirname,'dist'),\n"
"    port: 3000\n"
"  },\n"
"  plugins: [\n"
"    new HtmlWebpackPlugin({\n"
"      title: 'Remote app',\n"
"      template: path.resolve(__dirname, './src/template.html')\n"
"    })\n"
"  ]\n"
"}; \n"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:40
#, no-wrap
msgid "Using Module Federation & Adding Vendor Libraries"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:41
msgid ""
"Until this point, we only set up the starting code for both apps and hosted "
"them on different ports. Now we need to truly utilize Webpack's module "
"federation plugin, and the next thing which we would do is share two modules "
"- an ordinary JS function which uses a feature from our first shared vendor "
"library - Lodash and a button styled with the D3 library (D3 is a JS library "
"for manipulating documents based on data, but in our case, for the sake of "
"simplicity we will use it to style the button only)."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:42
msgid ""
"Let's start with the remote. Firstly, install the Lodash and D3 libraries:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:43
#, no-wrap
msgid "npm install lodash d3\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:44
msgid ""
"The function which will be shared is called `myFunction()`. It will use the "
"`sortedUniq()` method from Lodash to remove duplicates from an array of "
"numbers:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:45
#, no-wrap
msgid "import _ from 'lodash';\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:46
#, no-wrap
msgid ""
"export const myFunction = () => {\n"
"    let sampleArray = [1,1,2,2,2,3,4,5,5,6];\n"
"    let sortedArray = _.sortedUniq(sampleArray);\n"
"    console.log('My resulting array: ' + sortedArray);\n"
"}\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:47
msgid ""
"Next, create a button and use D3 to change the internal text color of it:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:48
#, no-wrap
msgid ""
"import * as d3 from 'd3'; \n"
"// create button & fill with text and id param\n"
"let d3Btn = document.createElement('button');\n"
"d3Btn.setAttribute('id','btn-d3');\n"
"d3Btn.appendChild(document.createTextNode('D3 Button'));\n"
"// append to the body\n"
"let container = document.getElementsByTagName('body');\n"
"container[0].appendChild(d3Btn);\n"
"// use d3\n"
"// change color of text to orange\n"
"d3.select('#btn-d3').style('color','orange'); \n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:49
msgid ""
"Next step is to import the modules dynamically, so the `bootstrap.js` file "
"would look like the following:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:50
#, no-wrap
msgid ""
"import('./sharedModules/mySharedFunction');\n"
"import('./sharedModules/mySharedButton');\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:51
msgid ""
"To enable the usage of the `ModuleFederationPlugin` we need to register it "
"in the configuration file. Import at the top of the file:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:52
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:58
#, no-wrap
msgid "const { ModuleFederationPlugin } = require('webpack').container;\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:53
msgid "In the plugins section of the configuration we register the plugin:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:54
#, no-wrap
msgid ""
"new ModuleFederationPlugin({\n"
"      name: 'remoteApp_oneVendorsBundle',\n"
"      library: {\n"
"        type: 'var',\n"
"        name: 'remoteApp_oneVendorsBundle'\n"
"      },\n"
"      filename: 'remoteEntry.js',\n"
"      exposes: {\n"
"        './mySharedFunction':'./src/sharedModules/mySharedFunction.js',\n"
"        './mySharedButton':'./src/sharedModules/mySharedButton.js'\n"
"      },\n"
"      shared: [\n"
"        'lodash', 'd3'\n"
"      ]\n"
"    })\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:55
msgid ""
"We register a name for our application - it would be used by the host app to "
"connect with the remote. We also register a script by the name of "
"`remoteEntry.js`. This will be the script which enables the sharing of "
"modules between our two apps, and will be automatically generated when "
"building our app."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:56
msgid ""
"We also need to have a shared section where we put the vendor libraries to "
"be shared with the host app."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:57
msgid ""
"The only thing we need to do in the host application is to add some code to "
"configure the ModuleFederationPlugin to work with the remote app. First, we "
"require the plugin:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:59
msgid "And in the plugins section we should have the following code:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:60
#, no-wrap
msgid ""
"new ModuleFederationPlugin({\n"
"      name: 'hostApp_oneVendorsBundle',\n"
"      library: {\n"
"        type: 'var',\n"
"        name: 'hostApp_oneVendorsBundle'\n"
"      },\n"
"      remotes: {\n"
"        remoteApp: 'remoteApp_oneVendorsBundle'\n"
"      },\n"
"      shared: [\n"
"        'lodash', 'd3'\n"
"      ]\n"
"    })\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:61
msgid ""
"Here we need to register the remote app in order to share modules. In our "
"host app we would reference the remote by the name `remoteApp`."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:62
msgid ""
"We also need the Lodash and D3 to be shared. The vendor bundles will be "
"loaded together with the bundle for the shared function and button."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:63
msgid ""
"Proceed to the `template.html` of the `Host_App`, and add the following "
"`<script>` tag in the head of the `temlplate.html`:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:64
#, no-wrap
msgid "<script src='http://localhost:3000/remoteEntry.js'></script>\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:65
msgid ""
"The shared `myFunction()` will be loaded with a click of a button, and we "
"need a `<div>` which will act as a container for rendering the button, "
"that's why we need this code in the `<body>`:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:66
#, no-wrap
msgid ""
"<button id=\"btn-shared-modules-loader\" \n"
"  style=\"display: block; margin-top: 10px;\">Load shared modules</button>\n"
"<div id='shared-btn-container' style=\"margin-top: 10px;\"></div>  \n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:67
msgid ""
"By `document.getElementById()` we get the button from the `template.html` "
"and we add an onClick event listener which dynamically loads the shared "
"function and button bundle:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:68
#, no-wrap
msgid ""
"let loadSharedModulesBtn = document.getElementById('btn-shared-modules-loader');\n"
"loadSharedModulesBtn.addEventListener('click', async () => {\n"
"    let sharedFunctionModule = await import('remoteApp/mySharedFunction');\n"
"    sharedFunctionModule.myFunction();\n"
"    let sharedButtonModule = await import('remoteApp/mySharedButton');\n"
"    let sharedButton = document.createElement(sharedButtonModule.name);\n"
"    let sharedButtonContainer = document.getElementById('shared-btn-container');\n"
"    sharedButtonContainer.appendChild(sharedButton);\n"
"})\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:69
msgid ""
"It's now time to package our code for deployment. To do so, we'll need to "
"incorporate an npm script in the `package.json` of both our applications. "
"Please add the following line of code: `\"build\": \"webpack --config "
"webpack.config.js\"`. Once added, you should then run the command `npm run "
"build` within both applications. Upon execution, the `dist` directories in "
"each app will showcase the array of bundles generated by Webpack."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:70
msgid ""
"Upon launching both applications, and pressing the 'Load shared modules' "
"button in the host application, the D3 button will become visible. "
"Additionally, the console log will present the filtered array from the "
"shared function, and the vendor bundles will be accessed from the remote "
"app. Note that it's essential to initiate the remote app prior to the host, "
"or alternatively, reload the host if you started the applications in a "
"different sequence."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:71
msgid ""
"If you take a peek at the browser's developer tools and navigate to the "
"network tab, you'll observe that the Lodash, D3, and shared module bundles "
"are not loaded until the button is clicked. Post-click, all the bundles are "
"loaded, and we receive a console message from `myFunction()` from the "
"remote, along with the display of the shared button. Hovering over the "
"bundle names will reveal their origin: they are fetched from the remote, "
"specifically from `localhost:3000.`"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:72
#, no-wrap
msgid "Bundling Vendor Libraries"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:73
msgid ""
"Webpack's `SplitChunksPlugin` is traditionally employed to accomplish code "
"splitting - the process of segmenting code into smaller, manageable bundles "
"and regulating resource loading. However, in my scenario, I've deviated from "
"the standard use and innovatively used this tool to aggregate all vendor "
"code into a singular bundle."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:74
msgid ""
"In this demonstration, we're dealing with a limited number of vendor "
"bundles, but this strategy can be immensely advantageous and performance-"
"enhancing when operating at a larger scale with numerous smaller vendor "
"modules. This holds particularly true if the requirement arises to load all "
"vendor bundles simultaneously."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:75
msgid ""
"We need to add the `optimization` property to the `webpack.configuration.js` "
"file of the remote app:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:76
#, no-wrap
msgid ""
"optimization: {\n"
"    splitChunks: {\n"
"      cacheGroups: {\n"
"        commons: {\n"
"          test: /[\\\\/]node_modules[\\\\/](lodash|d3|delaunator|internmap|robust-predicates)/,\n"
"          name: 'Vendors_Lodash_D3',\n"
"          chunks: 'all'\n"
"        }\n"
"      }\n"
"    }\n"
"}\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:77
msgid ""
"You might be curious about 'delaunator' and 'internmap'. These are modules "
"incorporated during the D3 installation. If they're excluded from the "
"regular expression (regex), they will independently generate separate vendor "
"modules within the 'dist' directory, which diverges from our original "
"intent. This situation can be bypassed by employing a more selective import "
"of D3, avoiding the use of import * as d3 from d3."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:78
msgid ""
"Upon executing npm run build within the remote application, a unified vendor "
"bundle titled Vendors_Lodash_D3.bundle.js will be produced in the 'dist' "
"directory."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:79
msgid ""
"To culminate, if you launch both applications, the remote will independently "
"load the entire Vendors_Lodash_D3 bundle and refrain from loading any other "
"vendor modules:"
msgstr ""

#. TODO: [!image]
#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:80
msgid ""
"Upon selecting the 'load shared modules' button in the host application, it "
"will not only load both the shared function and the shared D3 button "
"bundles, but also exclusively load a single vendor bundle, specifically, the "
"Vendors_Lodash_D3 bundle."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:82
msgid ""
"In this guide we have shown how to bundle two vendor libraries' bundles into "
"one bundle using Webpack's SplitChunksPlugin, so that they can be shared "
"between the remote and host applications as one chunk and improve "
"performance."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:83
msgid ""
"This is a powerful feature of Webpack that can be used to optimize the "
"performance of your applications by reducing the number of requests and the "
"size of the bundles. It also allows for better code organization and "
"separation of concerns by allowing you to share modules between different "
"applications."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:84
#, no-wrap
msgid "Additional Information on SplitChunksPlugin"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-split-chunks.adoc:85
msgid ""
"https://webpack.js.org/plugins/split-chunks-plugin/[Official Webpack 5 "
"SplitChunksPlugin Documentation] https://indepth.dev/posts/1490/webpack-an-"
"in-depth-introduction-to-splitchunksplugin[Webpack: An in-depth introduction "
"to SplitChunksPlugin]"
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/mf-ssr.adoc:1
#, no-wrap
msgid "Setting up Module Federation with Server-Side Rendering"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:2
msgid ""
"In this guide, we will walk you through setting up Module Federation with "
"Server-Side Rendering (SSR) in a framework-agnostic manner. We assume you "
"already have a basic understanding of Module Federation and have set it up "
"in your project. If you need a refresher, please refer to the Module "
"Federation setup guide. This guide focuses on the steps required to enable "
"SSR with Module Federation.  Table of Contents"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/mf-ssr.adoc:3
#: src/en/modules/ROOT/pages/mf-ssr.adoc:9
#, no-wrap
msgid "Understanding the Challenges with SSR and Module Federation"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/mf-ssr.adoc:4
#: src/en/modules/ROOT/pages/mf-ssr.adoc:12
#, no-wrap
msgid "Server-Side Bundle Configuration"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/mf-ssr.adoc:5
#: src/en/modules/ROOT/pages/mf-ssr.adoc:18
#, no-wrap
msgid "Loading Remote Modules on the Server"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/mf-ssr.adoc:6
#: src/en/modules/ROOT/pages/mf-ssr.adoc:25
#, no-wrap
msgid "Rendering Federated Modules on the Server"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/mf-ssr.adoc:7
#: src/en/modules/ROOT/pages/mf-ssr.adoc:38
#, no-wrap
msgid "Hydrating the Client-Side Application"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:10
msgid ""
"Server-Side Rendering (SSR) is a technique used to improve the initial load "
"time and SEO of web applications by rendering the HTML on the server and "
"sending it to the client. Module Federation, on the other hand, is a feature "
"introduced in Webpack 5 that allows sharing code and dependencies across "
"multiple applications at runtime."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:11
msgid ""
"While both techniques offer significant benefits, integrating them can be "
"challenging. Module Federation relies on dynamic imports, which are not "
"natively supported during server-side rendering. This guide will demonstrate "
"how to overcome these challenges and set up Module Federation with SSR."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:13
msgid ""
"To enable SSR with Module Federation, you need to create a separate Webpack "
"configuration for the server-side bundle. This bundle should include the "
"ModuleFederationPlugin with the appropriate settings for server-side "
"rendering."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:14
msgid ""
"Create a new webpack.server.config.js file with the following configuration:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-ssr.adoc:15
#, no-wrap
msgid ""
"const path = require('path');\n"
"const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-ssr.adoc:16
#, no-wrap
msgid ""
"module.exports = {\n"
"  target: 'node',\n"
"  mode: 'production',\n"
"  entry: './src/server.js',\n"
"  output: {\n"
"    path: path.resolve(__dirname, 'dist'),\n"
"    filename: 'server.js',\n"
"    libraryTarget: 'commonjs2',\n"
"  },\n"
"  plugins: [\n"
"    new ModuleFederationPlugin({\n"
"      name: 'serverApp',\n"
"      library: { type: 'commonjs2' },\n"
"      filename: 'remoteServerEntry.js',\n"
"      exposes: {\n"
"        './serverComponent': './src/serverComponent',\n"
"      },\n"
"      shared: ['react', 'react-dom'],\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:17
msgid ""
"This configuration specifies the `target` as `node` and sets the "
"`libraryTarget` to `commonjs2` since we are targeting a Node.js environment. "
"Make sure to expose the relevant server components in the `exposes` object."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:19
msgid ""
"With the server-side bundle configuration in place, the next step is to load "
"the remote modules on the server. We'll use the require function to import "
"the remote entry file generated by Webpack."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:20
msgid ""
"In your `src/server.js` file, add the following code to load the remote "
"entry:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-ssr.adoc:21
#, no-wrap
msgid ""
"const path = require('path');\n"
"const { ModuleFederationPlugin } = require('webpack/lib/container/ModuleFederationPlugin');\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-ssr.adoc:22
#, no-wrap
msgid "const remoteEntryPath = path.resolve(__dirname, 'dist/remoteServerEntry.js');\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-ssr.adoc:23
#, no-wrap
msgid "require(remoteEntryPath);\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-ssr.adoc:24
#, no-wrap
msgid "// Your server-side rendering logic goes here\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:26
msgid ""
"Now that we have loaded the remote modules, we need to render them on the "
"server. Since this guide is framework-agnostic, we will provide a general "
"approach that you can adapt to your specific framework."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:27
msgid "Import the federated module in your server-side rendering code:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-ssr.adoc:28
#, no-wrap
msgid "const serverComponent = require('serverApp/serverComponent');\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:29
msgid "Render the imported federated module to HTML:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:30
msgid ""
"This step will depend on your specific framework. Most frameworks provide a "
"method to render components to an HTML string on the server. Use that method "
"to render the imported federated module."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:31
msgid ""
"Here's an example of how you might render the federated module using a "
"hypothetical renderToString function:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-ssr.adoc:32
#, no-wrap
msgid "const renderedHTML = renderToString(serverComponent);\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:33
msgid "Send the rendered HTML to the client:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:34
msgid ""
"Once you have the rendered HTML, send it as part of the response to the "
"client. This step will also depend on your specific framework and server "
"setup."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:35
msgid "Here's an example using Express.js:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-ssr.adoc:36
#, no-wrap
msgid ""
"app.get('/', (req, res) => {\n"
"  res.send(`\n"
"    <!DOCTYPE html>\n"
"    <html>\n"
"      <head>\n"
"        <title>SSR with Module Federation</title>\n"
"      </head>\n"
"      <body>\n"
"        <div id=\"root\">${renderedHTML}</div>\n"
"        <script src=\"/remoteEntry.js\"></script>\n"
"        <script src=\"/client.js\"></script>\n"
"      </body>\n"
"    </html>\n"
"  `);\n"
"});\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:37
msgid ""
"In this example, we've included the `remoteEntry.js` and `client.js` files "
"to load the federated modules on the client side."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:39
msgid ""
"With the server-side rendering complete, the final step is to hydrate the "
"client-side application. Hydration is the process of attaching event "
"listeners and initializing the state of the client-side application based on "
"the server-rendered HTML."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:40
msgid "Load the remote entry file in your client-side `index.html`:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-ssr.adoc:41
#, no-wrap
msgid "<script src=\"/remoteEntry.js\"></script>\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:42
msgid "Import the federated module in your client-side application:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-ssr.adoc:43
#: src/en/modules/ROOT/pages/shared-api.adoc:35
#, no-wrap
msgid "import('./bootstrap.js');\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:44
msgid "Hydrate the client-side application:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:45
msgid ""
"This step will depend on your specific framework. Most frameworks provide a "
"method to hydrate a client-side application based on the server-rendered "
"HTML. Use that method to hydrate your application with the imported "
"federated module."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:46
msgid ""
"Here's an example of how you might hydrate the client-side application using "
"a hypothetical `hydrate` function:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-ssr.adoc:47
#, no-wrap
msgid ""
"import { hydrate } from 'your-framework';\n"
"import ClientComponent from './ClientComponent';\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/mf-ssr.adoc:48
#, no-wrap
msgid "hydrate(<ClientComponent />, document.getElementById('root'));\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:50
msgid ""
"In this guide, we've shown you how to set up Module Federation with Server-"
"Side Rendering in a framework-agnostic manner. By following these steps, you "
"can enjoy the benefits of both Module Federation and SSR, enabling a better "
"user experience, improved initial load times, and enhanced SEO."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:51
msgid ""
"Remember that the exact implementation will depend on your specific "
"framework and server setup. Always consult the framework's documentation for "
"detailed guidance and best practices."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:52
msgid ""
"For non-framework-agnostic guides, please refer to the following resources:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:53
msgid "React: Module Federation with Server-Side Rendering"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:54
msgid "Vue.js: Module Federation with Server-Side Rendering"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:55
msgid "Angular: Module Federation with Server-Side Rendering"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:56
msgid "Svelte: Module Federation with Server-Side Rendering"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/mf-ssr.adoc:57
msgid ""
"These guides will provide you with specific instructions and examples "
"tailored to each respective framework."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:1
#, no-wrap
msgid "Naming conventions for modules and their exports to avoid naming collisions"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:2
msgid ""
"When using Module Federation you may face some challenges when it comes to "
"naming your modules and their exports. Since you are loading modules from "
"different sources, you need to make sure that they don't conflict with each "
"other or with the host application. Otherwise, you might end up with "
"unexpected behavior, errors, or broken functionality."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:3
msgid ""
"In this guide, we will show you some best practices for naming your modules "
"and their exports when using Module Federation. We will also explain how "
"Webpack handles naming collisions and how you can customize it to suit your "
"needs."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:4
#, no-wrap
msgid "Naming your modules"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:5
msgid ""
"A module is a unit of code that can be loaded by Webpack. It can be a "
"JavaScript file, a CSS file, an image, or any other type of asset. When "
"using Module Federation, you can expose some of your modules to other "
"bundles or applications by using the `exposes` option in your Webpack "
"configuration."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:6
msgid ""
"For example, suppose you have a module called `utils.js` that contains some "
"utility functions. You can expose it to other bundles by adding this to your "
"Webpack configuration:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:7
#, no-wrap
msgid ""
"module.exports = {\n"
"  // ...\n"
"  plugins: [\n"
"    new ModuleFederationPlugin({\n"
"      // ...\n"
"      exposes: {\n"
"        \"./utils\": \"./src/utils.js\",\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:8
msgid ""
"The key of the `exposes` object is the name of the module that you want to "
"expose. The value is the path to the module file relative to your project "
"root. In this case, we are exposing the module as `./utils` and pointing it "
"to `./src/utils.js`."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:9
msgid ""
"When you expose a module, you need to follow some naming conventions to "
"avoid collisions with other modules. Here are some tips:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:10
msgid ""
"Use a unique prefix for your modules. This can be based on your project "
"name, domain name, or any other identifier that distinguishes your modules "
"from others. For example, if your project is called `my-app`, you can prefix "
"your modules with `my-app/`, like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:11
#, no-wrap
msgid ""
"module.exports = {\n"
"  // ...\n"
"  plugins: [\n"
"    new ModuleFederationPlugin({\n"
"      // ...\n"
"      exposes: {\n"
"        \"my-app/utils\": \"./src/utils.js\",\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:12
msgid ""
"Avoid using generic or common names for your modules. For example, don't "
"expose a module as `./react` or `./lodash`, as these might conflict with "
"other bundles that use the same libraries. Instead, use more specific names "
"that reflect the purpose or content of your modules. For example, if you "
"have a custom React component library, you can expose it as `my-app/"
"components`, like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:13
#, no-wrap
msgid ""
"module.exports = {\n"
"  // ...\n"
"  plugins: [\n"
"    new ModuleFederationPlugin({\n"
"      // ...\n"
"      exposes: {\n"
"        \"my-app/components\": \"./src/components/index.js\",\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:14
msgid ""
"Use consistent naming conventions across your modules. For example, if you "
"use camelCase for your module names, stick to it throughout your project. "
"Don't mix it with snake_case or kebab-case. This will make your modules "
"easier to find and import."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:15
#, no-wrap
msgid "Naming your exports"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:16
msgid ""
"An export is a value or a function that a module provides to other modules. "
"When using Module Federation, you can import exports from other bundles or "
"applications by using the `import` statement or the `import()` function."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:17
msgid ""
"For example, suppose you want to import the `utils` module that we exposed "
"earlier from another bundle. You can do it like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:18
#, no-wrap
msgid "import utils from \"my-app/utils\";\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:19
msgid "Or like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:20
#, no-wrap
msgid ""
"import(\"my-app/utils\").then((utils) => {\n"
"  // ...\n"
"});\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:21
msgid ""
"The name of the export that you import is the same as the name of the module "
"that you expose. In this case, we are importing the default export of the "
"`utils` module as `utils`."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:22
msgid ""
"When you export values or functions from your modules, you need to follow "
"some naming conventions to avoid collisions with other exports. Here are "
"some tips:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:23
msgid ""
"Use descriptive and meaningful names for your exports. For example, don't "
"export a function as `foo` or `bar`, as these might conflict with other "
"functions that have the same name. Instead, use more specific names that "
"reflect what the function does or returns. For example, if you have a "
"function that calculates the area of a circle, you can export it as "
"`calculateCircleArea`, like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:24
#, no-wrap
msgid ""
"export function calculateCircleArea(radius) {\n"
"  return Math.PI * radius * radius;\n"
"}\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:25
msgid ""
"Use consistent naming conventions across your exports. For example, if you "
"use camelCase for your export names, stick to it throughout your project. "
"Don't mix it with snake_case or kebab-case. This will make your exports "
"easier to find and import."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:26
msgid ""
"Avoid using default exports for your modules. Default exports are anonymous "
"and can be imported with any name. This can lead to confusion and "
"inconsistency when importing modules from different sources. For example, if "
"you have a module that exports a React component as the default export, you "
"can import it like this:"
msgstr ""

#. type: Labeled list
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:27
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:43
#, no-wrap
msgid "Approach 1"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:28
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:35
#, no-wrap
msgid "import MyComponent from \"my-app/components\";\n"
msgstr ""

#. type: Labeled list
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:29
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:45
#, no-wrap
msgid "Approach 2"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:30
#, no-wrap
msgid "import Foo from \"my-app/components\";\n"
msgstr ""

#. type: Labeled list
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:31
#, no-wrap
msgid "Approach 3"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:32
#, no-wrap
msgid "import Bar from \"my-app/components\";\n"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:33
msgid ""
"As you can see, the name of the import does not match the name of the module "
"or the component. This can make it hard to track where the component comes "
"from and what it does. Instead, use named exports for your modules and "
"import them with the same name. For example, if you have a module that "
"exports a React component as a named export, you can export and import it "
"like the following:"
msgstr ""

#. type: Labeled list
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:34
#, no-wrap
msgid "Export"
msgstr ""

#. type: Labeled list
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:36
#, no-wrap
msgid "Import"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:37
#, no-wrap
msgid "import { MyComponent } from \"my-app/components\";\n"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:38
msgid ""
"This way, the name of the import matches the name of the module and the "
"component. This will make your code more readable and maintainable."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:39
#, no-wrap
msgid "Handling naming collisions"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:40
msgid ""
"Sometimes, despite following the naming conventions, you might encounter "
"naming collisions with other modules or exports. This can happen when you "
"import modules from different sources that use the same or similar names for "
"their modules or exports."
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:41
msgid ""
"Webpack provides some options to handle naming collisions and resolve them "
"in a way that suits your needs. Here are some of them:"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:42
msgid ""
"Use aliases to rename modules or exports when importing them. Aliases are "
"alternative names that you can assign to modules or exports when importing "
"them. This can help you avoid conflicts and confusion when dealing with "
"modules or exports that have the same or similar names. For example, suppose "
"you want to import two modules that both expose a `utils` module. You can "
"use aliases to rename one of them when importing it, like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:44
#, no-wrap
msgid ""
"import utils from \"my-app/utils\"; // Import utils from my-app\n"
"import otherUtils as \"other-app/utils\"; // Import utils from other-app and rename it as otherUtils\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:46
#, no-wrap
msgid ""
"import { utils as myUtils } from \"my-app/utils\"; // Import utils from my-app and rename it as myUtils\n"
"import { utils as otherUtils } from \"other-app/utils\"; // Import utils from other-app and rename it as otherUtils\n"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:47
msgid ""
"This way, you can avoid naming collisions and use both modules without "
"confusion."
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:48
msgid ""
"Use scopes to group modules or exports under a common namespace. Scopes are "
"prefixes that you can add to your module or export names to create a "
"hierarchy or a category for them. This can help you organize your modules or "
"exports and avoid conflicts with other sources that use the same or similar "
"names. For example, suppose you want to expose some modules under a scope "
"called `my-app`. You can add the scope to your module names when exposing "
"them, like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:49
#, no-wrap
msgid ""
"module.exports = {\n"
"  // ...\n"
"  plugins: [\n"
"    new ModuleFederationPlugin({\n"
"      // ...\n"
"      exposes: {\n"
"        \"my-app/utils\": \"./src/utils.js\",\n"
"        \"my-app/components\": \"./src/components/index.js\",\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:50
msgid "Then, you can import them with the scope included, like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:51
#, no-wrap
msgid ""
"import utils from \"my-app/utils\"; // Import utils from my-app scope\n"
"import components from \"my-app/components\"; // Import components from my-app scope\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:52
msgid ""
"This way, you can avoid naming collisions and use your modules without "
"confusion."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:53
msgid ""
"Use remotes to specify where to load modules from. Remotes are references to "
"other bundles or applications that expose modules using Module Federation. "
"You can use remotes to specify where to load modules from when importing "
"them. This can help you avoid conflicts and confusion when dealing with "
"modules that have the same or similar names but come from different sources. "
"For example, suppose you want to import a module called `utils` from another "
"bundle called `other-app`. You can use remotes to specify where to load the "
"module from, like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:54
#, no-wrap
msgid ""
"module.exports = {\n"
"  // ...\n"
"  plugins: [\n"
"    new ModuleFederationPlugin({\n"
"      // ...\n"
"      remotes: {\n"
"        // Define a remote called other-app that points to the URL of the other bundle\n"
"        other-app: \"other-app@https://other-app.com/remoteEntry.js\",\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:55
msgid ""
"Then, you can import the module with the remote name included, like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:56
#, no-wrap
msgid "import utils from \"other-app/utils\"; // Import utils from other-app remote\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:57
msgid ""
"This way, you can avoid naming collisions and use the module without "
"confusion."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/naming-convention-tips.adoc:59
msgid ""
"Naming your modules and their exports when using Module Federation is an "
"important aspect of creating micro-frontends, sharing code across "
"applications, and optimizing performance and scalability. By following some "
"best practices and conventions, you can avoid naming collisions and ensure "
"that your modules and exports are clear, consistent, and easy to use. You "
"can also leverage Webpack's options to handle naming collisions and resolve "
"them in a way that suits your needs."
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/pros-cons.adoc:1
#, no-wrap
msgid "Pros and Cons of Module Federation: A Comprehensive Overview"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/pros-cons.adoc:2
msgid ""
"Module Federation is a relatively new feature in web development that allows "
"developers to share entire modules between multiple applications. While it "
"has the potential to significantly improve code sharing and reduce "
"duplication, there are also potential drawbacks and limitations to using "
"Module Federation. In this guide, we'll explore the pros and cons of Module "
"Federation, including its benefits and limitations."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/pros-cons.adoc:3
#, no-wrap
msgid "Pros of Module Federation"
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/pros-cons.adoc:4
#, no-wrap
msgid "Reduced Code Duplication"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/pros-cons.adoc:5
msgid ""
"One of the primary benefits of Module Federation is that it can "
"significantly reduce code duplication between applications. Instead of "
"duplicating code across multiple applications, developers can share modules "
"between them, reducing the size and complexity of each application."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/pros-cons.adoc:6
#, no-wrap
msgid "Improved Collaboration"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/pros-cons.adoc:7
msgid ""
"Module Federation can also improve collaboration between development teams. "
"By allowing multiple applications to share the same codebase, developers can "
"work more closely together, sharing knowledge and expertise and working more "
"efficiently."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/pros-cons.adoc:8
#, no-wrap
msgid "Greater Flexibility"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/pros-cons.adoc:9
msgid ""
"Module Federation also provides greater flexibility and modularity in "
"application design. By breaking applications down into smaller, more "
"manageable modules, developers can more easily swap out and replace modules "
"as needed, without having to rewrite entire applications."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/pros-cons.adoc:10
#, no-wrap
msgid "Improved Performance"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/pros-cons.adoc:11
msgid ""
"In some cases, Module Federation can also improve application performance. "
"By reducing the amount of code that needs to be loaded and executed by each "
"application, Module Federation can help to reduce load times and improve "
"overall performance."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/pros-cons.adoc:12
#, no-wrap
msgid "Improved Scalability"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/pros-cons.adoc:13
msgid ""
"Module Federation can also improve scalability by allowing developers to "
"distribute functionality across multiple applications. This approach can "
"help to reduce the size and complexity of individual applications, making "
"them easier to maintain and scale."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/pros-cons.adoc:14
#, no-wrap
msgid "Cons of Module Federation"
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/pros-cons.adoc:15
#, no-wrap
msgid "Increased Complexity"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/pros-cons.adoc:16
msgid ""
"One of the primary drawbacks of Module Federation is that it can increase "
"the complexity of application development. Sharing modules between "
"applications requires careful management of dependencies and versioning, "
"which can be challenging to implement and maintain."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/pros-cons.adoc:17
#, no-wrap
msgid "Security Risks"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/pros-cons.adoc:18
msgid ""
"Module Federation also introduces potential security risks. Sharing code "
"between applications can create vulnerabilities, particularly if proper "
"security measures are not in place."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/pros-cons.adoc:19
#, no-wrap
msgid "Increased Coupling"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/pros-cons.adoc:20
msgid ""
"Module Federation can also increase coupling between applications, making it "
"more difficult to make changes to individual applications without affecting "
"others. This can lead to a loss of flexibility and modularity in application "
"design."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/pros-cons.adoc:21
#, no-wrap
msgid "Potential Performance Issues"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/pros-cons.adoc:22
msgid ""
"In some cases, Module Federation can also introduce potential performance "
"issues. Remote loading of modules can introduce additional latency and "
"increase load times, particularly if modules are large or complex."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/pros-cons.adoc:24
msgid ""
"Module Federation is a powerful feature that offers many benefits for web "
"developers, including increased code reusability, improved scalability, "
"reduced development time, and improved performance. However, there are also "
"potential drawbacks to consider, including increased complexity, potential "
"security risks and possible performance overhead."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/pros-cons.adoc:25
msgid ""
"Advanced users should carefully weigh the pros and cons of Module Federation "
"when deciding whether to use this feature in their applications. They should "
"also take appropriate measures to mitigate any risks and ensure that their "
"applications are secure, performant, and maintainable."
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:1
#, no-wrap
msgid "Setting the Dynamic Public Path "
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:2
msgid ""
"In this guide, we'll cover how to set the public path dynamically for Module "
"Federation. This is particularly useful when deploying federated modules to "
"different environments with varying public paths."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:3
msgid ""
"One of the challenges of using Module Federation is to configure the public "
"path of each Webpack build correctly, so that it can load remote modules "
"from other builds at runtime. The public path is the base URL for all assets "
"(including JavaScript files) in a Webpack build. By default, Webpack sets "
"the public path to the current HTML document's base URL or location. "
"However, this may not work well for Module Federation scenarios, where the "
"public path needs to point to the location of the remote container that "
"exposes the modules."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:4
msgid ""
"There are three ways to set the public path dynamically for Module "
"Federation: using an inline script tag, using a custom entry point, or using "
"startup code."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:5
#, no-wrap
msgid "Using an inline script tag"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:6
msgid ""
"One way to set the public path dynamically is to use an inline script tag in "
"the HTML document that hosts the Webpack build. The script tag should assign "
"the `__webpack_public_path__` variable to the desired public path before "
"loading the main JavaScript file."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:8
#, no-wrap
msgid ""
"<script>\n"
"  // Set the public path to the location of the remote container\n"
"  __webpack_public_path__ = \"https://example.com/remote/\";\n"
"</script>\n"
"<script src=\"main.js\"></script>\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:9
msgid ""
"This approach has the advantage of being simple and straightforward, but it "
"has some drawbacks:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:10
msgid ""
"It requires modifying the HTML document for each webpack build, which may "
"not be feasible or desirable in some cases."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:11
msgid ""
"It may not work well with code splitting or lazy loading, as the public path "
"needs to be set before any JavaScript file is loaded."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:12
msgid ""
"It may cause issues with caching or content delivery networks (CDNs), as the "
"public path is hard-coded in the HTML document and cannot be changed "
"dynamically."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:13
#, no-wrap
msgid "Using a custom entry point"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:14
msgid ""
"Another way to set the public path dynamically is to use a custom entry "
"point in the webpack configuration. The custom entry point should import a "
"module that sets the `__webpack_public_path__` variable to the desired "
"public path based on some logic or environment variables."
msgstr ""

#. type: Labeled list
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:16
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:32
#, no-wrap
msgid "entry.js"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:17
#, no-wrap
msgid ""
"// entry.js\n"
"// Import a module that sets the public path\n"
"import \"./set-public-path.js\";\n"
"// Import other modules as usual\n"
"import \"./app.js\";\n"
msgstr ""

#. type: Labeled list
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:18
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:34
#, no-wrap
msgid "set-public-path.js"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:19
#, no-wrap
msgid ""
"// set-public-path.js\n"
"// Set the public path based on some logic or environment variables\n"
"__webpack_public_path__ = process.env.PUBLIC_PATH || \"https://example.com/remote/\";\n"
msgstr ""

#. type: Labeled list
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:20
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:36
#, no-wrap
msgid "webpack.config.js"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:21
#, no-wrap
msgid ""
"// webpack.config.js\n"
"module.exports = {\n"
"  // Use the custom entry point\n"
"  entry: \"./entry.js\",\n"
"  // Other configuration options...\n"
"};\n"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:22
msgid ""
"This approach has the advantage of being more flexible and robust, as it "
"allows setting the public path based on any logic or environment variables. "
"It also works well with code splitting or lazy loading, as the public path "
"is set before any remote module is loaded. However, it has some drawbacks:"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:23
msgid ""
"It requires creating a custom entry point and a module that sets the public "
"path, which may add some complexity and overhead to the webpack "
"configuration."
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:24
msgid ""
"It may not work well with hot module replacement (HMR), as changing the "
"public path may require reloading the entire application."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:25
#, no-wrap
msgid "Using startup code"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:26
msgid ""
"Startup code is an implementation tactic to attach additional runtime code "
"to a remote container startup sequence. This is useful for scenarios where "
"the public path needs to be set based on some logic or environment variables "
"that are not available at build time."
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:27
msgid "To use startup code, we need to do the following steps:"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:28
msgid ""
"Create an entry point with the same name as the name we place in "
"ModuleFederationPlugin. This merges the two \"chunks\" together. When a "
"remoteEntry is placed on the page, the code in this entry point will execute "
"as part of the `remoteEntry` startup."
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:29
msgid ""
"In the entry point, import a module that sets the `__webpack_public_path__` "
"variable to the desired public path based on some logic or environment "
"variables."
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:30
msgid ""
"Exclude the entry point chunk from the HTML document, as it will be loaded "
"by the `remoteEntry`."
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:31
msgid ""
"For example, let's say we have a remote container named \"app1\" that "
"exposes some modules. We want to set its public path based on an environment "
"variable called `PUBLIC_PATH`. Here is how we can use startup code to "
"achieve this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:33
#, no-wrap
msgid ""
"// entry.js\n"
"// Import a module that sets the public path\n"
"import \"./set-public-path.js\";\n"
"// Import other modules as usual import \"./app.js\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:35
#, no-wrap
msgid ""
"// set-public-path.js\n"
"// Set the public path based on an environment variable\n"
"__webpack_public_path__ = process.env.PUBLIC_PATH || \"https://example.com/remote/\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:37
#, no-wrap
msgid ""
"// webpack.config.js\n"
"module.exports = {\n"
"  // Use the custom entry point\n"
"  entry: {\n"
"    // we add an entrypoint with the same name as our name in ModuleFederationPlugin.\n"
"    // This merges the two \"chunks\" together. When a remoteEntry is placed on the page,\n"
"    // the code in this app1 entrypoint will execute as part of the remoteEntry startup.\n"
"    app1: \"./src/set-public-path.js\",\n"
"    main: \"./src/index.js\",\n"
"  },\n"
"  mode: \"development\",\n"
"  output: {\n"
"    // public path can be what it normally is, not a absolute, hardcoded url\n"
"    publicPath: \"/\",\n"
"  },\n"
"  plugins: [\n"
"    new ModuleFederationPlugin({\n"
"      name: \"app1\",\n"
"      remotes: {\n"
"        app2: \"app2@http://localhost:3002/remoteEntry.js\",\n"
"      },\n"
"      shared: {\n"
"        react: {\n"
"          singleton: true,\n"
"        },\n"
"        \"react-dom\": {\n"
"          singleton: true,\n"
"        },\n"
"      },\n"
"    }),\n"
"    new HtmlWebpackPlugin({\n"
"      template: \"./public/index.html\",\n"
"      // exclude app1 chunk, just incase HTML webpack plugin tries to do something silly.\n"
"      // It doesn't have the best MF support right now when it comes to advanced implementations\n"
"      excludeChunks: [\"app1\"],\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:38
msgid ""
"This way, we can set the public path of app1 dynamically at runtime based on "
"the PUBLIC_PATH environment variable. If it is not defined, we fall back to "
"a default value of \"https://example.com/remote/\"."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:39
#, no-wrap
msgid "Additional Reading"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:40
msgid ""
"https://github.com/module-federation/module-federation-examples/tree/master/"
"startup-code[Basic host remote example, with startup code that sets the "
"remotes public path dynamically.]"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:41
msgid ""
"https://github.com/module-federation/module-federation-examples/"
"issues/102[Dicscussion on GitHub related to Dynamic publicPath]"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:42
msgid ""
"https://scriptedalchemy.medium.com/micro-fe-architecture-webpack-5-module-"
"federation-and-custom-startup-code-9cb3fcd066c[Micro-FE Architecture: "
"Webpack 5, Module Federation, and custom startup code by Zack Jackson]"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:43
msgid ""
"https://dev.to/waldronmatt/tutorial-a-guide-to-module-federation-for-"
"enterprise-n5[Tutorial - A Guide to Module Federation for Enterprise ]"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:45
msgid ""
"Setting the public path dynamically for Module Federation is an important "
"step to ensure that remote modules can be loaded correctly at runtime. There "
"are three ways to do this: using an inline script tag, using a custom entry "
"point, or using startup code. Each approach has its own advantages and "
"disadvantages, and developers should choose the one that suits their needs "
"and preferences best."
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/public-path-dynamic.adoc:46
msgid ""
"Using an inline script tag is simple and straightforward, but it may not "
"work well with code splitting or lazy loading, and it may cause issues with "
"caching or CDNs. Using a custom entry point is more flexible and robust, but "
"it may add some complexity and overhead to the webpack configuration, and it "
"may not work well with HMR. Using startup code is a powerful and advanced "
"technique that allows injecting custom code into the webpack runtime, but it "
"may require some familiarity with webpack internals and Module Federation."
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:1
#, no-wrap
msgid "Improving Resiliency and Failovers with Module Federation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:2
msgid ""
"Module Federation is a feature of Webpack that allows you to dynamically "
"load modules from different bundles at runtime. This can help you improve "
"the resiliency and failover capabilities of your web applications by "
"reducing the impact of network failures, server errors, or code bugs."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:3
msgid ""
"Resiliency is the ability of a system to recover from failures and continue "
"to function. Failovers are the mechanisms that allow a system to switch to a "
"backup or alternative mode of operation when a failure occurs."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:4
msgid "In this guide, you will learn how to use Module Federation to:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:5
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:124
msgid "Load modules from remote sources with fallbacks"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:6
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:125
msgid "Handle errors and retries when loading modules"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:7
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:126
msgid "Implement a circuit breaker pattern to avoid cascading failures"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:8
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:127
msgid "Use service workers to cache modules and serve them offline"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:9
#: src/en/modules/ROOT/pages/setup.adoc:3
#, no-wrap
msgid "Prerequisites"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:10
msgid "To follow this guide, you need to have:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:11
msgid "A basic understanding of Webpack and Module Federation"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:14
#, no-wrap
msgid "Setting up the project"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:15
msgid ""
"To demonstrate how Module Federation works, we will create a simple web "
"application that consists of two parts: a host app and a remote app. The "
"host app will load a module from the remote app and display its content on "
"the page. The remote app will expose a module that returns a greeting "
"message."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:16
msgid "To set up the project, follow these steps:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:17
msgid ""
"Create a new folder called `module-federation-demo` and navigate to it in "
"your terminal."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:18
msgid "Run `npm init -y` to create a `package.json` file with default values."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:19
msgid ""
"Run `npm install webpack webpack-cli webpack-dev-server html-webpack-plugin` "
"to install the dependencies."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:20
msgid ""
"Create two subfolders called `host` and `remote` inside the `module-"
"federation-demo` folder. These will contain the source code for the host app "
"and the remote app respectively."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:21
msgid ""
"Create a `webpack.config.js` file in each subfolder with the following "
"content:"
msgstr ""

#. type: Labeled list
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:22
#, no-wrap
msgid "host webpack.config"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:23
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:70
#, no-wrap
msgid ""
"// webpack.config.js for host app\n"
"const HtmlWebpackPlugin = require(\"html-webpack-plugin\");\n"
"const { ModuleFederationPlugin } = require(\"webpack\").container;\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:24
#, no-wrap
msgid ""
"module.exports = {\n"
"  mode: \"development\",\n"
"  devServer: {\n"
"    port: 3000,\n"
"  },\n"
"  plugins: [\n"
"    new HtmlWebpackPlugin({\n"
"      template: \"./src/index.html\",\n"
"    }),\n"
"    new ModuleFederationPlugin({\n"
"      name: \"host\",\n"
"      remotes: {\n"
"        remote: \"remote@http://localhost:3001/remoteEntry.js\",\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Labeled list
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:25
#, no-wrap
msgid "remote webpack.config"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:26
#, no-wrap
msgid ""
"// webpack.config.js for remote app\n"
"const HtmlWebpackPlugin = require(\"html-webpack-plugin\");\n"
"const { ModuleFederationPlugin } = require(\"webpack\").container;\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:27
#, no-wrap
msgid ""
"module.exports = {\n"
"  mode: \"development\",\n"
"  devServer: {\n"
"    port: 3001,\n"
"  },\n"
"  plugins: [\n"
"    new HtmlWebpackPlugin({\n"
"      template: \"./src/index.html\",\n"
"    }),\n"
"    new ModuleFederationPlugin({\n"
"      name: \"remote\",\n"
"      filename: \"remoteEntry.js\",\n"
"      exposes: {\n"
"        \"./greeting\": \"./src/greeting.js\",\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:28
msgid ""
"The `ModuleFederationPlugin` is the main plugin that enables Module "
"Federation. It takes some options that define how the modules are exposed "
"and consumed."
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:29
msgid ""
"In the host app, we specify a `remotes` option that tells Webpack where to "
"find the remote app's entry point. The syntax is `<name>@<url>`, where "
"`<name>` is an alias that we can use to import modules from the remote app, "
"and `<url>` is the URL of the remote app's entry point."
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:30
msgid ""
"In the remote app, we specify a `filename` option that tells Webpack what "
"name to use for the entry point file. We also specify an `exposes` option "
"that tells Webpack what modules we want to expose to other apps. The syntax "
"is `<name>:<path>`, where `<name>` is an alias that other apps can use to "
"import our module, and `<path>` is the relative path to our module file."
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:31
msgid ""
"Create an `index.html` file in each subfolder with the following content:"
msgstr ""

#. type: Labeled list
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:32
#, no-wrap
msgid "host index.html"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:33
#, no-wrap
msgid ""
"<!-- index.html for host app -->\n"
"<html>\n"
"  <head>\n"
"    <title>Host App</title>\n"
"  </head>\n"
"  <body>\n"
"    <h1>Host App</h1>\n"
"    <div id=\"container\"></div>\n"
"    <script src=\"main.js\"></script>\n"
"  </body>\n"
"</html>\n"
msgstr ""

#. type: Labeled list
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:34
#, no-wrap
msgid "remote index.html"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:35
#, no-wrap
msgid ""
"<!-- index.html for remote app -->\n"
"<html>\n"
"  <head>\n"
"    <title>Remote App</title>\n"
"  </head>\n"
"  <body>\n"
"    <h1>Remote App</h1>\n"
"    <script src=\"remoteEntry.js\"></script>\n"
"  </body>\n"
"</html>\n"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:36
msgid ""
"The `index.html` files are the entry points for the web applications. They "
"load the respective JavaScript bundles generated by Webpack."
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:37
msgid "Create a `src` folder in each subfolder and add the following files:"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:38
msgid "Host:"
msgstr ""

#. type: Labeled list
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:39
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:51
#: src/en/modules/ROOT/pages/shared-api.adoc:34
#, no-wrap
msgid "index.js"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:40
#, no-wrap
msgid ""
"// src/index.js for host app\n"
"import(\"./bootstrap\");\n"
msgstr ""

#. type: Labeled list
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:41
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:53
#: src/en/modules/ROOT/pages/shared-api.adoc:36
#, no-wrap
msgid "bootstrap.js"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:42
#, no-wrap
msgid ""
"// src/bootstrap.js for host app\n"
"import React from \"react\";\n"
"import ReactDOM from \"react-dom\";\n"
"import App from \"./App\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:43
#, no-wrap
msgid "ReactDOM.render(<App />, document.getElementById(\"container\"));\n"
msgstr ""

#. type: Labeled list
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:44
#, no-wrap
msgid "App.js"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:45
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:80
#, no-wrap
msgid ""
"// src/App.js for host app\n"
"import React, { useEffect, useState } from \"react\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:46
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:93
#, no-wrap
msgid ""
"const App = () => {\n"
"  const [greeting, setGreeting] = useState(\"\");\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:47
#, no-wrap
msgid ""
"  useEffect(() => {\n"
"    // Load the greeting module from the remote app\n"
"    import(\"remote/greeting\")\n"
"      .then((module) => {\n"
"        // Call the module's default export function and set the greeting state\n"
"        setGreeting(module.default());\n"
"      })\n"
"      .catch((error) => {\n"
"        // Handle any errors while loading the module\n"
"        console.error(error);\n"
"        setGreeting(\"Oops, something went wrong!\");\n"
"      });\n"
"  }, []);\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:48
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:83
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:96
#, no-wrap
msgid ""
"  return (\n"
"    <div>\n"
"      <p>The greeting from the remote app is:</p>\n"
"      <p>{greeting}</p>\n"
"    </div>\n"
"  );\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:50
msgid "Remote"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:52
#, no-wrap
msgid ""
"// src/index.js for remote app\n"
"import(\"./bootstrap\");\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:54
#, no-wrap
msgid ""
"// src/bootstrap.js for remote app\n"
"import React from \"react\";\n"
"import ReactDOM from \"react-dom\";\n"
"import Greeting from \"./Greeting\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:55
#, no-wrap
msgid "ReactDOM.render(<Greeting />, document.getElementById(\"root\"));\n"
msgstr ""

#. type: Labeled list
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:56
#, no-wrap
msgid "greeting.js"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:57
#, no-wrap
msgid ""
"// src/Greeting.js for remote app\n"
"import React from \"react\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:58
#, no-wrap
msgid ""
"const Greeting = () => {\n"
"  return <h2>Hello from the remote app!</h2>;\n"
"};\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:59
#, no-wrap
msgid "export default Greeting;\n"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:60
msgid ""
"The `src/index.js` files are the entry points for the JavaScript bundles. "
"They import a `bootstrap.js` file that contains the actual logic of the "
"apps. This is a common pattern to enable asynchronous loading of modules "
"with Module Federation."
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:61
msgid ""
"The `src/bootstrap.js` files for the host app and the remote app use React "
"to render some components on the page. The host app imports a `App.js` file "
"that contains a component that loads the greeting module from the remote app "
"and displays it on the page. The remote app imports a `Greeting.js` file "
"that contains a component that renders a greeting message on the page."
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:62
msgid ""
"The `src/greeting.js` file for the remote app is the module that we expose "
"to other apps. It exports a function that returns a greeting message."
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:63
msgid ""
"Run `npm run dev` in both subfolders to start the development servers. You "
"should see something like this in your browser:"
msgstr ""

#.  TODO: (screenshot)
#. type: delimited block =
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:64
msgid ""
"You have successfully set up a basic Module Federation project. Next, we "
"will see how to improve its resiliency and failover capabilities."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:65
#, no-wrap
msgid "Loading modules with fallbacks"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:66
msgid ""
"One of the benefits of Module Federation is that it allows you to load "
"modules from remote sources without having to bundle them with your "
"application. This can reduce your bundle size and improve your performance."
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:67
msgid ""
"However, this also introduces some risks. What if the remote source is "
"unavailable or slow? What if the module fails to load or execute? How can "
"you ensure that your application still works in these scenarios?"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:68
msgid ""
"One way to handle these situations is to provide fallbacks for your modules. "
"A fallback is an alternative module that you can load in case the original "
"module fails. For example, you can provide a local copy of the module, or a "
"mock module that returns some dummy data."
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:69
msgid ""
"To use fallbacks with Module Federation, you can use the `fallback` option "
"of the `ModuleFederationPlugin`. This option allows you to specify an object "
"that maps remote names to fallback modules. For example, you can modify your "
"host app's Webpack configuration like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:71
#, no-wrap
msgid ""
"module.exports = {\n"
"  mode: \"development\",\n"
"  devServer: {\n"
"    port: 3000,\n"
"  },\n"
"  plugins: [\n"
"    new HtmlWebpackPlugin({\n"
"      template: \"./src/index.html\",\n"
"    }),\n"
"    new ModuleFederationPlugin({\n"
"      name: \"host\n"
"      remotes: {\n"
"        remote: \"remote@http://localhost:3001/remoteEntry.js\",\n"
"      },\n"
"      // Specify the fallback modules for the remote app\n"
"      fallback: {\n"
"        remote: \"./src/fallback.js\",\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:72
msgid ""
"The `fallback` option tells Webpack to load the `src/fallback.js` file as a "
"fallback for the remote app. This file should export the same modules as the "
"remote app, but with different implementations. For example, you can create "
"a `src/fallback.js` file like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:73
#, no-wrap
msgid ""
"// src/fallback.js for host app\n"
"// Export a mock greeting module that returns a static message\n"
"export const greeting = () => {\n"
"  return \"Hello from the fallback module!\";\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:74
msgid ""
"Now, if the remote app fails to load or expose the greeting module, the host "
"app will use the fallback module instead. You can test this by stopping the "
"remote app's server and refreshing the host app's page. You should see "
"something like this:"
msgstr ""

#.  TODO: (screenshot)
#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:75
msgid ""
"You have successfully implemented a fallback mechanism for your modules. "
"Next, we will see how to handle errors and retries when loading modules."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:76
msgid "## Handling errors and retries when loading modules"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:77
msgid ""
"Another way to improve the resiliency of your web application is to handle "
"errors and retries when loading modules from remote sources. This can help "
"you recover from temporary failures or network issues."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:78
msgid ""
"To handle errors and retries with Module Federation, you can use the "
"`import()` function that Webpack provides. This function returns a promise "
"that resolves to the module object if the module is loaded successfully, or "
"rejects with an error if the module fails to load. You can use the `catch()` "
"method of the promise to handle any errors and retry loading the module if "
"needed."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:79
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:91
msgid "For example, you can modify your host app's `App.js` file like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:81
#, no-wrap
msgid ""
"const App = () => {\n"
"  const [greeting, setGreeting] = useState(\"\");\n"
"  const [retryCount, setRetryCount] = useState(0);\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:82
#, no-wrap
msgid ""
"  useEffect(() => {\n"
"    // Load the greeting module from the remote app\n"
"    import(\"remote/greeting\")\n"
"      .then((module) => {\n"
"        // Call the module's default export function and set the greeting state\n"
"        setGreeting(module.default());\n"
"      })\n"
"      .catch((error) => {\n"
"        // Handle any errors while loading the module\n"
"        console.error(error);\n"
"        // Check if we have reached the maximum number of retries\n"
"        if (retryCount < 3) {\n"
"          // Increment the retry count\n"
"          setRetryCount(retryCount + 1);\n"
"          // Retry loading the module after 1 second\n"
"          setTimeout(() => {\n"
"            import(\"remote/greeting\").then((module) => {\n"
"              setGreeting(module.default());\n"
"            });\n"
"          }, 1000);\n"
"        } else {\n"
"          // Give up and show an error message\n"
"          setGreeting(\"Sorry, we could not load the greeting module.\");\n"
"        }\n"
"      });\n"
"  }, [retryCount]);\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:85
msgid ""
"The `App.js` file now uses a `retryCount` state to keep track of how many "
"times it has tried to load the greeting module. If the module fails to load, "
"it checks if the retry count is less than 3. If so, it increments the retry "
"count and tries to load the module again after 1 second. If not, it gives up "
"and shows an error message."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:86
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:99
msgid ""
"You can test this by simulating a network failure in your browser's "
"developer tools. You should see something like this:"
msgstr ""

#.  TODO: (screenshot)
#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:87
msgid ""
"You have successfully implemented an error handling and retry mechanism for "
"your modules. Next, we will see how to implement a circuit breaker pattern "
"to avoid cascading failures."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:88
msgid "## Implementing a circuit breaker pattern to avoid cascading failures"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:89
msgid ""
"Another way to improve the resiliency of your web application is to "
"implement a circuit breaker pattern to avoid cascading failures. A circuit "
"breaker is a design pattern that monitors the health of a remote service and "
"prevents excessive requests when the service is unhealthy. This can help you "
"avoid overloading the service or wasting resources when the service is "
"unlikely to respond."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:90
msgid ""
"To implement a circuit breaker pattern with Module Federation, you can use a "
"third-party library called `opossum`. This library provides a "
"`circuitBreaker` function that wraps a promise-based function and monitors "
"its success and failure rates. It also provides some options to configure "
"the circuit breaker's behavior, such as the failure threshold, the timeout "
"duration, and the reset timeout."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:92
#, no-wrap
msgid ""
"// src/App.js for host app\n"
"import React, { useEffect, useState } from \"react\";\n"
"import { circuitBreaker } from \"opossum\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:94
#, no-wrap
msgid ""
"  useEffect(() => {\n"
"    // Create a circuit breaker for loading the greeting module\n"
"    const breaker = circuitBreaker(() => import(\"remote/greeting\"), {\n"
"      // Set the failure threshold to 50%\n"
"      errorThresholdPercentage: 50,\n"
"      // Set the timeout duration to 3 seconds\n"
"      timeout: 3000,\n"
"      // Set the reset timeout to 10 seconds\n"
"      resetTimeout: 10000,\n"
"    });\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:95
#, no-wrap
msgid ""
"    // Load the greeting module using the circuit breaker\n"
"    breaker\n"
"      .fire()\n"
"      .then((module) => {\n"
"        // Call the module's default export function and set the greeting state\n"
"        setGreeting(module.default());\n"
"      })\n"
"      .catch((error) => {\n"
"        // Handle any errors while loading the module\n"
"        console.error(error);\n"
"        // Check if the circuit breaker is open\n"
"        if (breaker.opened) {\n"
"          // Show a message that the service is unavailable\n"
"          setGreeting(\"The remote service is unavailable. Please try again later.\");\n"
"        } else {\n"
"          // Show a message that something went wrong\n"
"          setGreeting(\"Oops, something went wrong!\");\n"
"        }\n"
"      });\n"
"  }, []);\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:98
msgid ""
"The `App.js` file now uses a circuit breaker to load the greeting module. "
"The circuit breaker will monitor the success and failure rates of loading "
"the module and open or close accordingly. If the circuit breaker is open, it "
"will reject any requests immediately and show a message that the service is "
"unavailable. If the circuit breaker is closed, it will try to load the "
"module normally and show a message that something went wrong if it fails."
msgstr ""

#.  TODO: (screenshot)
#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:100
msgid ""
"You have successfully implemented a circuit breaker pattern for your "
"modules. Next, we will see how to use service workers to cache modules and "
"serve them offline."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:101
msgid "## Using service workers to cache modules and serve them offline"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:102
msgid ""
"Another way to improve the resiliency of your web application is to use "
"service workers to cache modules and serve them offline. A service worker is "
"a script that runs in the background and intercepts network requests. It can "
"cache the responses and serve them from the cache when the network is "
"unavailable or slow. This can help you improve the performance and "
"reliability of your web application."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:103
msgid ""
"To use service workers with Module Federation, you can use a third-party "
"library called `workbox`. This library provides some tools and modules to "
"simplify the creation and management of service workers. It also provides "
"some strategies to control how the service worker handles network requests "
"and cache responses."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:104
msgid ""
"For example, you can modify your host app's Webpack configuration like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:105
#, no-wrap
msgid ""
"// webpack.config.js for host app\n"
"const HtmlWebpackPlugin = require(\"html-webpack-plugin\");\n"
"const { ModuleFederationPlugin } = require(\"webpack\").container;\n"
"const { InjectManifest } = require(\"workbox-webpack-plugin\");\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:106
#, no-wrap
msgid ""
"module.exports = {\n"
"  mode: \"development\",\n"
"  devServer: {\n"
"    port: 3000,\n"
"  },\n"
"  plugins: [\n"
"    new HtmlWebpackPlugin({\n"
"      template: \"./src/index.html\",\n"
"    }),\n"
"    new ModuleFederationPlugin({\n"
"      name: \"host\",\n"
"      remotes: {\n"
"        remote: \"remote@http://localhost:3001/remoteEntry.js\",\n"
"      },\n"
"      fallback: {\n"
"        remote: \"./src/fallback.js\",\n"
"      },\n"
"    }),\n"
"    // Use the InjectManifest plugin to generate a service worker\n"
"    new InjectManifest({\n"
"      swSrc: \"./src/sw.js\",\n"
"      swDest: \"sw.js\",\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:107
msgid ""
"The `InjectManifest` plugin is a plugin that generates a service worker "
"based on a source file. It takes some options that define the source and "
"destination of the service worker file."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:108
msgid ""
"In this case, we specify a `swSrc` option that tells Webpack to use the `src/"
"sw.js` file as the source of the service worker. We also specify a `swDest` "
"option that tells Webpack what name to use for the generated service worker "
"file."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:109
msgid ""
"Next, we need to create a `src/sw.js` file that contains the logic of the "
"service worker. We can use the `workbox` modules to implement some caching "
"strategies for our modules. For example, we can create a `src/sw.js` file "
"like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:110
#, no-wrap
msgid ""
"// src/sw.js for host app\n"
"import { precacheAndRoute } from \"workbox-precaching\";\n"
"import { registerRoute } from \"workbox-routing\";\n"
"import { StaleWhileRevalidate } from \"workbox-strategies\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:111
#, no-wrap
msgid ""
"// Precache and route the files generated by Webpack\n"
"precacheAndRoute(self.__WB_MANIFEST);\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:112
#, no-wrap
msgid ""
"// Register a route for remote modules using a stale-while-revalidate strategy\n"
"registerRoute(\n"
"  ({ url }) => url.origin === \"http://localhost:3001\",\n"
"  new StaleWhileRevalidate()\n"
");\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:113
msgid ""
"The `sw.js` file imports some modules from `workbox` and uses them to "
"implement some caching strategies for our modules."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:114
msgid ""
"The `precacheAndRoute` function takes an array of files to precache and "
"route. In this case, we pass it the `self.__WB_MANIFEST` variable, which is "
"an array of files generated by Webpack. This will ensure that our host app's "
"files are cached and served from the cache when offline."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:115
msgid ""
"The `registerRoute` function takes a matching function and a caching "
"strategy. In this case, we pass it a function that matches any requests to "
"the remote app's origin, and a `StaleWhileRevalidate` strategy. This will "
"ensure that any remote modules are cached and served from the cache if "
"available, while also updating the cache in the background if possible."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:116
msgid ""
"Finally, we need to register the service worker in our host app's `index."
"html` file. We can add a script tag like this:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:117
#, no-wrap
msgid ""
"<!-- index.html for host app -->\n"
"<html>\n"
"  <head>\n"
"    <title>Host App</title>\n"
"  </head>\n"
"  <body>\n"
"    <h1>Host App</h1>\n"
"    <div id=\"container\"></div>\n"
"    <script src=\"main.js\"></script>\n"
"    <!-- Register the service worker -->\n"
"    <script>\n"
"      if (\"serviceWorker\" in navigator) {\n"
"        window.addEventListener(\"load\", () => {\n"
"          navigator.serviceWorker.register(\"/sw.js\");\n"
"        });\n"
"      }\n"
"    </script>\n"
"  </body>\n"
"</html>\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:118
msgid ""
"The script tag checks if the browser supports service workers and registers "
"the `sw.js` file as a service worker."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:119
msgid ""
"Now, if you reload your host app's page, you should see something like this "
"in your browser's developer tools:"
msgstr ""

#.  TODO: (screenshot)
#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:120
msgid ""
"You have successfully registered a service worker that caches your modules "
"and serves them offline. You can test this by simulating an offline mode in "
"your browser's developer tools. You should see something like this:"
msgstr ""

#.  TODO: (screenshot)
#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:121
msgid ""
"You have successfully implemented a service worker to cache modules and "
"serve them offline."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:123
msgid ""
"In this guide, you learned how to use Module Federation to improve the "
"resiliency and failover capabilities of your web applications. You learned "
"how to:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:128
msgid "You can find the source code for this guide on GitHub."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/resiliency-failovers.adoc:129
msgid ""
"We hope you enjoyed this guide and learned something new. If you have any "
"feedback or questions, please let us know in the comments below. Thank you "
"for reading! 😊"
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/setup.adoc:1
#, no-wrap
msgid "Setting up Module Federation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:2
msgid ""
"Module Federation is a feature of Webpack that allows you to share code "
"between micro-frontends in a decentralized way. This documentation is "
"intended for beginner users and will guide you through the process of "
"setting up Module Federation."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:4
msgid ""
"Before we begin, make sure you have a fresh version of Node.js installed. "
"The current Long Term Support (LTS) release is an ideal starting point. You "
"may run into a variety of issues with the older versions as they may be "
"missing functionality webpack and/or its related packages require."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:5
msgid "You need to have `Node.js` and `npm` installed on your machine."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:6
msgid ""
"You need to have a basic understanding of front-end development concepts."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:7
msgid "You need to have multiple applications that can load JavaScript modules"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:8
msgid ""
"For more detailed information on installation of Webpack 5, please, refer to "
"the official https://webpack.js.org/guides/installation/[Installation "
"Instructions]"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/setup.adoc:9
#, no-wrap
msgid "Installation Instructions"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:10
msgid "To install Module Federation, follow these steps:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:11
msgid "Open a terminal and navigate to your project directory."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:12
msgid "Run the following command to install Webpack and its dependencies:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:13
msgid "`npm install webpack webpack-cli webpack-dev-server --save-dev`"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:14
msgid ""
"Create a Webpack configuration file in the root of each application that "
"will be using Module Federation."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:15
msgid ""
"In each configuration file, add the following code to enable Module "
"Federation:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:16
msgid "const { ModuleFederationPlugin } = require(\"webpack\").container;"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/setup.adoc:17
#, no-wrap
msgid ""
"module.exports = {\n"
"  // ...\n"
"  plugins: [\n"
"\tnew ModuleFederationPlugin({\n"
"  \t// ...\n"
"\t}),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/setup.adoc:18
#, no-wrap
msgid "Configuration Options"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:19
msgid ""
"Once you have enabled Module Federation in your Webpack configuration files, "
"you can start configuring it. The following options are available:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:20
msgid "name (required): The name of the application module."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:21
msgid "filename (optional): The filename of the remote entry file."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:22
msgid ""
"exposes (optional): An object that maps local module names to the modules "
"that should be exposed to other applications."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:23
msgid ""
"remotes (optional): An object that maps the names of remote applications to "
"the URLs where they are hosted."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:24
msgid ""
"shared (optional): An object that lists the modules that should be shared "
"between applications."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/setup.adoc:25
#, no-wrap
msgid "Using Module Federation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:26
msgid "To use Module Federation, you need to:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:27
msgid "Identify the modules you want to share between applications."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:28
msgid "Add those modules to a shared package or repository."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:29
msgid ""
"Make sure that each application has access to the shared package or "
"repository."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:30
msgid ""
"Configure each application's Webpack configuration file to use Module "
"Federation."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:31
msgid "Use the shared modules in your applications as needed."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/setup.adoc:32
msgid ""
"For more information and advanced configuration options, please refer to the "
"official Webpack documentation."
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/shared-api.adoc:1
#, no-wrap
msgid "Module Federation Shared API"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:2
msgid ""
"This documentation page provides an in-depth explanation of the Module "
"Federation Shared API, its configuration options, use cases, and benefits as "
"well as potential downsides. This guide is intended for users looking to "
"optimize the performance of their distributed applications."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/shared-api.adoc:3
#, no-wrap
msgid "Overview of the Shared API"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:4
msgid ""
"The Shared API is a part of the Module Federation plugin configuration "
"options. It allows you to pass an array or object called shared containing a "
"list of dependencies that can be shared and used by other federated apps "
"(aka \"remotes\")."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:5
msgid "Here's an example of how to use the Shared API in Module Federation:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-api.adoc:6
#, no-wrap
msgid ""
"new ModuleFederationPlugin({\n"
"  name: \"host\",\n"
"  filename: \"remoteEntry.js\",\n"
"  remotes: {},\n"
"  exposes: {},\n"
"  shared: [],\n"
"});\n"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/shared-api.adoc:7
#, no-wrap
msgid "API Definition"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:8
msgid ""
"`shared (object | [string])`: An object or Array of strings containing a "
"list of dependencies that can be shared and consumed by other federated apps."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:9
msgid ""
"`eager (boolean)`: If `true`, the dependency will be eagerly loaded and made "
"available to other federated apps as soon as the host application starts. If "
"`false`, the dependency will be lazily loaded when it is first requested by "
"a federated app."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:10
msgid ""
"`singleton (boolean)`: If `true`, the dependency will be treated as a "
"singleton, and only a single instance of it will be shared among all "
"federated apps."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:11
msgid ""
"`requiredVersion (string)`: Specifies the required version of the "
"dependency. If a federated app tries to load an incompatible version of the "
"dependency, two copies will be loaded. If the `singleton` option is set to "
"`true`, a warning will be printed in the console."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/shared-api.adoc:12
#, no-wrap
msgid "Benefits of Using the Shared API"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:13
msgid ""
"When using federated modules, they are bundled separately and include all "
"the dependencies they need to function. However, when they're used in a host "
"application, it's possible for multiple copies of the same dependency to be "
"downloaded. This can hurt performance and make users download more "
"JavaScript than necessary."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:14
msgid ""
"The Shared API helps prevent this issue by enabling you to avoid downloading "
"multiple copies of the same dependency, ultimately improving the performance "
"of your application."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/shared-api.adoc:15
#, no-wrap
msgid "Avoiding Duplication"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:16
msgid ""
"Consider the following example: you have two modules, Module A and Module B, "
"both of which require lodash to function independently."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:17
msgid ""
"When these modules are used in a host application that brings both modules "
"together, the Shared API comes into play. If a preloaded, shared copy of "
"lodash is available, Module A and Module B will use that copy instead of "
"loading their own independent copies. This copy could be loaded by the host "
"or another remote application inside it."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:18
msgid ""
"Both the remote and host have to add the same dependency in \"shared\" for "
"it to be available for consumption."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-api.adoc:19
#, no-wrap
msgid ""
"new ModuleFederationPlugin({\n"
"  ...\n"
"  shared: [\"lodash\"],\n"
"});\n"
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/shared-api.adoc:20
#, no-wrap
msgid "How the Shared API Works"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:21
msgid ""
"If you are familiar with Dynamic Imports, Module Federation operates "
"similarly; it requests a module and returns a promise that resolves with an "
"object containing all exports from the moduleName declared in the `exposes` "
"object."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:22
msgid ""
"The asynchronous nature of Module Federation makes the Shared API highly "
"flexible."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/shared-api.adoc:23
#, no-wrap
msgid "Async Dependency Loading"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:24
msgid ""
"When a module is required, it will load a file called `remoteEntry.js`, "
"listing all the dependencies the module needs. Since this operation is "
"asynchronous, the container can check all the `remoteEntry` files and list "
"all the dependencies that each module has declared in `shared`. Then, the "
"host can load a single copy and share it with all the modules that need it."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:25
msgid ""
"Because `shared` relies on an asynchronous operation to inspect and resolve "
"the dependencies, if your application or module loads synchronously and "
"declares a dependency in `shared`, you might encounter the following error:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-api.adoc:26
#, no-wrap
msgid "Uncaught Error: Shared module is not available for eager consumption\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:27
msgid "To solve the error above, there are two options:"
msgstr ""

#. type: Title ====
#: src/en/modules/ROOT/pages/shared-api.adoc:28
#, no-wrap
msgid "Eager Consumption"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-api.adoc:29
#, no-wrap
msgid ""
"new ModuleFederationPlugin({\n"
"  ...\n"
"  shared: { \n"
"      lodash: {\n"
"          eager: true,\n"
"        },\n"
"  },\n"
"});\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:30
msgid ""
"Individual dependencies can be marked as `eager: true`. This option doesn't "
"put the dependencies in an async chunk, so they can be provided "
"synchronously. However, this means that those dependencies will always be "
"downloaded, potentially impacting bundle size. The recommended solution is "
"to load your module asynchronously by wrapping it into an async boundary:"
msgstr ""

#. type: Title ====
#: src/en/modules/ROOT/pages/shared-api.adoc:31
#, no-wrap
msgid "Using an Async Boundary"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:32
msgid ""
"This only applies to the application's entry point; remote modules consumed "
"via module federation are automatically wrapped in an Async Boundary."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:33
msgid ""
"To create an async boundary, use a dynamic import to ensure your entry point "
"runs asynchronously:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-api.adoc:37
#, no-wrap
msgid ""
"import React from 'react';\n"
"import ReactDOM from 'react-dom';\n"
"import App from './App';\n"
"ReactDOM.render(<App />, document.getElementById('root'));\n"
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/shared-api.adoc:38
#, no-wrap
msgid "Versioning"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/shared-api.adoc:39
msgid ""
"What happens if two remote modules use different versions of the same "
"dependency?"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/shared-api.adoc:40
msgid ""
"Module Federation is capable of handling this situation by default. If the "
"semantic version ranges for those dependencies don't match, Module "
"Federation can identify them and provide separate copies. This ensures that "
"you don't accidentally load the wrong version containing breaking changes. "
"While this can cause performance issues due to downloading different "
"versions of a dependency, it prevents your app from breaking."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/shared-api.adoc:41
#, no-wrap
msgid "Singleton Loading"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/shared-api.adoc:42
msgid ""
"To guarantee that only one copy of a given dependency is loaded at all times "
"(e.g., React), pass `singleton: true` to the dependency object:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-api.adoc:43
#, no-wrap
msgid ""
"shared: {\n"
"  react: {\n"
"    singleton: true,\n"
"    requiredVersion: \"^18.0.0\",\n"
"  },\n"
"  \"react-dom\": {\n"
"    singleton: true,\n"
"    requiredVersion: \"^18.0.0\"\n"
"  },\n"
"},\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:44
msgid ""
"If one of your remote modules tries to load an incompatible dependency "
"version that has been marked as a singleton, Webpack will print a warning in "
"the console. The build will not break, and Webpack will continue to bundle "
"and load your applications. However, the warning serves as a reminder to "
"align your dependencies to avoid potential issues."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/shared-api.adoc:45
#, no-wrap
msgid "Drawbacks and Compromises"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:46
msgid ""
"While the Shared API is a powerful tool, it's important to be aware of some "
"potential issues and trade-offs associated with its use."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:47
msgid "Here are some issues that you might encounter using the Shared API:"
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/shared-api.adoc:48
#, no-wrap
msgid "Inconsistencies in Dependencies at Runtime"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:49
msgid ""
"As applications are compiled at different times by distinct Webpack "
"processes, they lack a common dependency graph. As a result, you must depend "
"on Semantic Versioning ranges for deduplication and providing identical "
"dependency versions."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:50
msgid ""
"There might be a situation where your remote has been built and tested with "
"version `1.0.0` of a library. However, when the host loads it, the Semantic "
"Versioning Range `^1.0.0` satisfies `1.1.0`, causing the `1.1.0` version to "
"load at runtime in production. This could lead to compatibility issues."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:51
msgid ""
"One way to mitigate this risk is by aligning versions to the greatest extent "
"possible (using a monorepo with a single package JSON could be beneficial)."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:52
msgid ""
"This challenge pertains to our reliance on Semantic Versioning ranges, "
"rather than the Module Federation and Shared API themselves. In distributed "
"systems (akin to microservices), a contract is necessary to ensure system "
"stability and dependability. In the context of the Shared API, the Semantic "
"Version Range serves as the contract (though it may not be the most reliable "
"one)."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:53
msgid ""
"From our experience, there is no superior alternative for shared "
"dependencies in a distributed frontend application. Despite the Shared API's "
"imperfections, it remains the most effective option currently available."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:55
msgid ""
"In summary, the Module Federation Shared API is a potent instrument for "
"enhancing the performance of distributed applications. It enables dependency "
"sharing across modules, preventing redundant duplication and leading to "
"quicker load times and superior overall performance. Nevertheless, it's "
"crucial to be cognizant of potential issues and compromises, such as "
"inconsistencies in dependencies at runtime. By recognizing these potential "
"challenges and actively working to address them, you can effectively employ "
"the Shared API to optimize your distributed applications."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:56
msgid ""
"To make the most of the Shared API, ensure that your team understands its "
"features, limitations, and best practices. Regularly review and update "
"dependencies, align versions, and monitor for potential compatibility "
"issues. By staying proactive in managing these aspects, you can continue to "
"improve the performance and reliability of your distributed applications "
"while minimizing risks associated with dependency management."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-api.adoc:57
msgid ""
"In conclusion, while the Module Federation Shared API isn't without its "
"drawbacks, it remains a powerful and valuable tool for developers working "
"with distributed applications. By being aware of its limitations and working "
"diligently to mitigate potential issues, you can harness the full potential "
"of the Shared API to create efficient, high-performance distributed systems."
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:1
#, no-wrap
msgid "Where to start: Shared Header or Footer using Module Federation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:2
msgid ""
"In this guide, you will learn how to create a shared header and footer "
"component using Module Federation, and how to use them in two different "
"applications. You will also learn how to handle routing, authentication, and "
"styling in the shared components."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:3
#, no-wrap
msgid "Step 1: Create the header and footer components"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:4
msgid ""
"The first step is to create a separate project that will contain the header "
"and footer components. This project will act as a host for the shared "
"components, and will expose them using Module Federation."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:5
msgid "Create a new folder called `shared-components` and navigate to it."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:6
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:63
msgid "Run `npm init -y` to initialize a new Node.js project."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:7
msgid ""
"Run `npm install webpack webpack-cli webpack-dev-server html-webpack-plugin "
"@webpack-cli/serve` to install the necessary dependencies."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:8
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:65
msgid ""
"Create a new file called `webpack.config.js` in the root folder and add the "
"following code:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:9
#, no-wrap
msgid "const HtmlWebpackPlugin = require(\"html-webpack-plugin\");\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:10
#, no-wrap
msgid ""
"module.exports = {\n"
"  mode: \"development\",\n"
"  devServer: {\n"
"    port: 3000,\n"
"  },\n"
"  plugins: [\n"
"    new HtmlWebpackPlugin({\n"
"      template: \"./public/index.html\",\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:11
msgid ""
"This is a basic Webpack configuration that will serve an HTML file using the "
"webpack-dev-server."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:12
msgid ""
"Create a new folder called public and add a new file called index.html with "
"the following content:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:13
#, no-wrap
msgid ""
"<!DOCTYPE html>\n"
"<html lang=\"en\">\n"
"<head>\n"
"  <meta charset=\"UTF-8\">\n"
"  <title>Shared Components</title>\n"
"</head>\n"
"<body>\n"
"  <div id=\"header\"></div>\n"
"  <div id=\"footer\"></div>\n"
"</body>\n"
"</html>\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:14
msgid ""
"This is the HTML file that will be served by the `webpack-dev-server`. It "
"has two empty divs with ids header and footer, where we will render our "
"shared components."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:15
msgid "Run `npm install react react-dom` to install React as a dependency."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:16
msgid ""
"Create a new folder called `src` and add two files: `Header.js` and `Footer."
"js`. These files will contain the React components for the header and footer."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:17
msgid "In `Header.js`, add the following code:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:18
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:23
#, no-wrap
msgid "import React from \"react\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:19
#, no-wrap
msgid ""
"function Header() {\n"
"  return (\n"
"    <div className=\"header\">\n"
"      <h1>Shared Header</h1>\n"
"      <nav>\n"
"        <ul>\n"
"          <li><a href=\"/\">Home</a></li>\n"
"          <li><a href=\"/about\">About</a></li>\n"
"          <li><a href=\"/contact\">Contact</a></li>\n"
"        </ul>\n"
"      </nav>\n"
"    </div>\n"
"  );\n"
"}\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:20
#, no-wrap
msgid "export default Header;\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:21
msgid ""
"This is a simple header component that has a title and a navigation menu."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:22
msgid "In Footer.js, add the following code:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:24
#, no-wrap
msgid ""
"function Footer() {\n"
"  return (\n"
"    <div className=\"footer\">\n"
"      <p>© 2023 Shared Components. All rights reserved.</p>\n"
"    </div>\n"
"  );\n"
"}\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:25
#, no-wrap
msgid "export default Footer;\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:26
msgid "This is a simple footer component that has a copyright notice."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:27
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:56
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:78
msgid ""
"Create a new file called `index.js` in the `src` folder and add the "
"following code:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:28
#, no-wrap
msgid ""
"import React from \"react\";\n"
"import ReactDOM from \"react-dom\";\n"
"import Header from \"./Header\";\n"
"import Footer from \"./Footer\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:29
#, no-wrap
msgid ""
"ReactDOM.render(<Header />, document.getElementById(\"header\"));\n"
"ReactDOM.render(<Footer />, document.getElementById(\"footer\"));\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:30
msgid ""
"This is the entry point of our project, where we import the header and "
"footer components and render them to the HTML elements with the "
"corresponding ids."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:31
msgid "Modify the webpack.config.js file to add the following code:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:32
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:44
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:66
#, no-wrap
msgid ""
"const HtmlWebpackPlugin = require(\"html-webpack-plugin\");\n"
"const ModuleFederationPlugin = require(\"webpack/lib/container/ModuleFederationPlugin\");\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:33
#, no-wrap
msgid ""
"module.exports = {\n"
"  mode: \"development\",\n"
"  devServer: {\n"
"    port: 3000,\n"
"  },\n"
"  plugins: [\n"
"    new HtmlWebpackPlugin({\n"
"      template: \"./public/index.html\",\n"
"    }),\n"
"    new ModuleFederationPlugin({\n"
"      name: \"shared-components\",\n"
"      filename: \"remoteEntry.js\",\n"
"      exposes: {\n"
"        \"./Header\": \"./src/Header\",\n"
"        \"./Footer\": \"./src/Footer\",\n"
"      },\n"
"      shared: [\"react\", \"react-dom\"],\n"
"    }),\n"
"  ],\n"
"  module: {\n"
"    rules: [\n"
"      {\n"
"        test: /\\.jsx?$/,\n"
"        exclude: /node_modules/,\n"
"        use: {\n"
"          loader: \"babel-loader\",\n"
"          options: {\n"
"            presets: [\"@babel/preset-react\"],\n"
"          },\n"
"        },\n"
"      },\n"
"    ],\n"
"  },\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:34
msgid ""
"This is the most important part of the configuration, where we use the "
"ModuleFederationPlugin to expose the header and footer components as remote "
"modules. We also specify the name and filename of the remote entry point and "
"the shared dependencies that we want to avoid duplication."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:35
msgid ""
"Run `npm install babel-loader @babel/core @babel/preset-react` to install "
"the necessary dependencies for transpiling JSX code."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:36
msgid ""
"Run `npx webpack serve` to start the webpack-dev-server and open `http://"
"localhost:3000` in your browser. You should see something like this:"
msgstr ""

#.  TODO: [add screenshot]
#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:37
msgid ""
"Congratulations! You have created the shared header and footer components "
"using Module Federation. Now let's see how to use them in other applications."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:38
#, no-wrap
msgid "Step 2: Create the consumer applications"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:39
msgid ""
"The next step is to create two different applications that will consume the "
"shared header and footer components. These applications will act as remotes "
"for the shared components, and will import them using Module Federation."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:40
msgid "Create a new folder called app1 and navigate to it."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:41
msgid "Run npm init -y to initialize a new Node.js project."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:42
msgid ""
"Run npm install webpack webpack-cli webpack-dev-server html-webpack-plugin "
"@webpack-cli/serve react react-dom to install the necessary dependencies."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:43
msgid ""
"Create a new file called webpack.config.js in the root folder and add the "
"following code:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:45
#, no-wrap
msgid ""
"module.exports = {\n"
"  mode: \"development\",\n"
"  devServer: {\n"
"    port: 3001,\n"
"  },\n"
"  plugins: [\n"
"    new HtmlWebpackPlugin({\n"
"      template: \"./public/index.html\",\n"
"    }),\n"
"    new ModuleFederationPlugin({\n"
"      name: \"app1\",\n"
"      filename: \"remoteEntry.js\",\n"
"      remotes: {\n"
"        \"shared-components\": \"shared-components@http://localhost:3000/remoteEntry.js\",\n"
"      },\n"
"      shared: [\"react\", \"react-dom\"],\n"
"    }),\n"
"  ],\n"
"  module: {\n"
"    rules: [\n"
"      {\n"
"        test: /\\.jsx?$/,\n"
"        exclude: /node_modules/,\n"
"        use: {\n"
"          loader: \"babel-loader\",\n"
"          options: {\n"
"            presets: [\"@babel/preset-react\"],\n"
"          },\n"
"        },\n"
"      },\n"
"    ],\n"
"  },\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:46
msgid ""
"This is a similar Webpack configuration as before, but this time we use the "
"ModuleFederationPlugin to specify the remote modules that we want to import "
"from the shared components project. We also specify the name and filename of "
"the remote entry point and the shared dependencies that we want to avoid "
"duplication."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:47
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:69
msgid ""
"Create a new folder called `public` and add a new file called `index.html` "
"with the following content:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:48
#, no-wrap
msgid ""
"<!DOCTYPE html>\n"
"<html lang=\"en\">\n"
"<head>\n"
"  <meta charset=\"UTF-8\">\n"
"  <title>App 1</title>\n"
"</head>\n"
"<body>\n"
"  <div id=\"root\"></div>\n"
"</body>\n"
"</html>\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:49
msgid ""
"This is the HTML file that will be served by the `webpack-dev-server`. It "
"has an empty div with id `root`, where we will render our application."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:50
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:72
msgid ""
"Create a new folder called `src` and add a new file called `App.js`. This "
"file will contain the React component for the application."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:51
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:73
msgid "In `App.js`, add the following code:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:52
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:74
#, no-wrap
msgid ""
"import React from \"react\";\n"
"import Header from \"shared-components/Header\";\n"
"import Footer from \"shared-components/Footer\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:53
#, no-wrap
msgid ""
"function App() {\n"
"  return (\n"
"    <div className=\"app\">\n"
"      <Header />\n"
"      <main>\n"
"        <h2>Welcome to App 1</h2>\n"
"        <p>This is an example of using shared header and footer components using Module Federation.</p>\n"
"      </main>\n"
"      <Footer />\n"
"    </div>\n"
"  );\n"
"}\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:55
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:77
msgid ""
"This is a simple application component that imports the header and footer "
"components from the shared components project using Module Federation. It "
"also has some content in the main section."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:57
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:79
#, no-wrap
msgid ""
"import React from \"react\";\n"
"import ReactDOM from \"react-dom\";\n"
"import App from \"./App\";\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:59
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:81
msgid ""
"This is the entry point of our project, where we import the app component "
"and render it to the HTML element with id `root`."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:60
msgid ""
"Run `npx webpack serve` to start the `webpack-dev-server` and open http://"
"localhost:3001 in your browser. You should see something like this:"
msgstr ""

#.  TODO: [add screenshot]
#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:61
msgid ""
"We have successfully created an application that uses the shared header and "
"footer components using Module Federation. Now let's create another "
"application that does the same thing."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:62
msgid "Create a new folder called `app2` and navigate to it."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:64
msgid ""
"Run `npm install webpack webpack-cli webpack-dev-server html-webpack-plugin "
"@webpack-cli/serve react react-dom` to install the necessary dependencies."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:67
#, no-wrap
msgid ""
"module.exports = {\n"
"  mode: \"development\",\n"
"  devServer: {\n"
"    port: 3002,\n"
"  },\n"
"  plugins: [\n"
"    new HtmlWebpackPlugin({\n"
"      template: \"./public/index.html\",\n"
"    }),\n"
"    new ModuleFederationPlugin({\n"
"      name: \"app2\",\n"
"      filename: \"remoteEntry.js\",\n"
"      remotes: {\n"
"        \"shared-components\": \"shared-components@http://localhost:3000/remoteEntry.js\",\n"
"      },\n"
"      shared: [\"react\", \"react-dom\"],\n"
"    }),\n"
"  ],\n"
"  module: {\n"
"    rules: [\n"
"      {\n"
"        test: /\\.jsx?$/,\n"
"        exclude: /node_modules/,\n"
"        use: {\n"
"          loader: \"babel-loader\",\n"
"          options: {\n"
"            presets: [\"@babel/preset-react\"],\n"
"          },\n"
"        },\n"
"      },\n"
"    ],\n"
"  },\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:68
msgid ""
"This is a similar Webpack configuration as before, but this time we use the "
"ModuleFederationPlugin to specify the remote modules that we want to import "
"from the shared components project. We also specify the name and filename of "
"the remote entry point, and the shared dependencies that we want to avoid "
"duplication."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:70
#, no-wrap
msgid ""
"<!DOCTYPE html>\n"
"<html lang=\"en\">\n"
"<head>\n"
"  <meta charset=\"UTF-8\">\n"
"  <title>App 2</title>\n"
"</head>\n"
"<body>\n"
"  <div id=\"root\"></div>\n"
"</body>\n"
"</html>\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:71
msgid ""
"This is the HTML file that will be served by the webpack-dev-server. It has "
"an empty div with id `root`, where we will render our application."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:75
#, no-wrap
msgid ""
"function App() {\n"
"  return (\n"
"    <div className=\"app\">\n"
"      <Header />\n"
"      <main>\n"
"        <h2>Welcome to App 2</h2>\n"
"        <p>This is another example of using shared header and footer components using Module Federation.</p>\n"
"      </main>\n"
"      <Footer />\n"
"    </div>\n"
"  );\n"
"}\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:82
msgid ""
"Run `npx webpack serve` to start the webpack-dev-server and open `http://"
"localhost:3002` in your browser. You should see something like this:"
msgstr ""

#.  TODO: [add screenshot]
#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:83
msgid ""
"We have successfully created another application that uses the shared header "
"and footer components using Module Federation."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:85
msgid ""
"In this guide, you have learned how to create a shared header and footer "
"component using Module Federation, and how to use them in two different "
"applications. You have also learned how to handle routing, authentication, "
"and styling in the shared components."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:86
#, no-wrap
msgid "Additional Resources"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:87
msgid ""
"If you want to learn more about Module Federation, you can check out the "
"official documentation here:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:88
msgid "https://webpack.js.org/concepts/module-federation/"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:89
msgid "You can also find more examples and tutorials here:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/shared-header-footer.adoc:90
msgid "https://github.com/module-federation/module-federation-examples"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:1
msgid ""
"# Team collaboration and code review when working with Federated Modules"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:2
msgid ""
"Federated Modules are a feature of Webpack 5 that allows you to create and "
"consume JavaScript modules that are dynamically loaded at runtime. They "
"enable you to share code across different applications without requiring a "
"build step or a centralized package registry. Federated Modules allow you to "
"create a more modular and decoupled architecture for your web applications."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:3
msgid ""
"However, working with Federated Modules also introduces some challenges for "
"team collaboration and code review. How do you ensure that your code is "
"consistent, readable, and secure across different modules and applications? "
"How do you manage dependencies and avoid breaking changes? How do you test "
"and debug your code in a federated environment?"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:4
msgid ""
"In this guide, we will explore some best practices and tools for team "
"collaboration and code review when working with Federated Modules. We will "
"cover the following topics:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:5
msgid "Code formatting and linting"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:6
msgid "Code documentation and comments"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:7
msgid "Code quality and security"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:8
msgid "Dependency management and versioning"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:9
msgid "Testing and debugging"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:10
msgid "## Code formatting and linting"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:11
msgid ""
"Code formatting and linting are essential for maintaining a consistent and "
"readable code style across your team. They help you avoid common errors, "
"enforce best practices, and improve the readability of your code. They also "
"make it easier to review your code changes and spot potential issues."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:12
msgid ""
"There are many tools available for code formatting and linting, such as "
"Prettier, ESLint, Stylelint, etc. You can use them to automatically format "
"and lint your code according to a set of rules that you define or adopt from "
"a popular style guide. You can also integrate them with your editor, IDE, or "
"build tool to format and lint your code on save, on commit, or on build."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:13
msgid ""
"When working with Federated Modules, you should use the same code formatting "
"and linting tools and rules across all your modules and applications. This "
"will ensure that your code is consistent and compatible across different "
"federated environments. You should also configure your tools to support the "
"syntax and features of Federated Modules, such as dynamic imports, module "
"federation plugins, etc."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:14
msgid ""
"For example, if you are using Prettier for code formatting, you can add the "
"following options to your `.prettierrc` file to support dynamic imports:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:15
#, no-wrap
msgid ""
"{\n"
"  \"parser\": \"babel\",\n"
"  \"plugins\": [\"@babel/plugin-syntax-dynamic-import\"]\n"
"}\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:16
msgid ""
"If you are using ESLint for code linting, you can add the following options "
"to your `.eslintrc` file to support module federation plugins:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:17
#, no-wrap
msgid ""
"{\n"
"  \"parserOptions\": {\n"
"    \"sourceType\": \"module\",\n"
"    \"ecmaVersion\": 2020\n"
"  },\n"
"  \"plugins\": [\"@module-federation/eslint-plugin\"]\n"
"}\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:18
msgid "## Code documentation and comments"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:19
msgid ""
"Code documentation and comments are important for explaining the purpose, "
"functionality, and usage of your code. They help you communicate your design "
"decisions, assumptions, and limitations to other developers who work with or "
"consume your code. They also make it easier to maintain, update, and reuse "
"your code in the future."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:20
msgid ""
"There are many tools available for code documentation and comments, such as "
"JSDoc, TypeScript Markdown, etc. You can use them to write structured and "
"descriptive comments in your code that document the parameters, return "
"values, types, examples, etc. of your functions, classes, variables, etc. "
"You can also use them to generate HTML pages or PDF files that contain the "
"documentation of your code."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:21
msgid ""
"When working with Federated Modules, you should use the same code "
"documentation and comments tools and conventions across all your modules and "
"applications. This will ensure that your code is well-documented and "
"understandable across different federated environments. You should also "
"document the specific aspects of Federated Modules in your code comments, "
"such as the exposed modules, the remote modules, the shared modules, etc."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:22
msgid ""
"For example, if you are using JSDoc for code documentation, you can add the "
"following tags to your comments to document the exposed modules:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:23
#, no-wrap
msgid ""
"/**\n"
" * A module that exposes a greeting function.\n"
" * @module greeting\n"
" * @expose greeting\n"
" */\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:24
#, no-wrap
msgid ""
"/**\n"
" * A function that returns a greeting message.\n"
" * @param {string} name - The name of the person to greet.\n"
" * @returns {string} A greeting message.\n"
" */\n"
"export function greeting(name) {\n"
"  return `Hello ${name}!`;\n"
"}\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:25
msgid ""
"If you are using TypeScript for code documentation, you can add the "
"following types to your comments to document the remote modules:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:26
#, no-wrap
msgid ""
"/**\n"
" * A type that represents a remote module that provides a math utility.\n"
" * @remote math\n"
" */\n"
"type MathModule = {\n"
"  /**\n"
"   * A function that adds two numbers\n"
"   * @param {number} x - The first number.\n"
"   * @param {number} y - The second number.\n"
"   * @returns {number} The sum of x and y.\n"
"   */\n"
"  add: (x: number, y: number) => number;\n"
"};\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:27
#, no-wrap
msgid ""
"/**\n"
" * A function that imports and uses a remote module.\n"
" * @async\n"
" * @returns {Promise<void>}\n"
" */\n"
"async function useRemoteModule() {\n"
"  // Import the remote module using dynamic import\n"
"  const math = await import(\"math@http://localhost:3001/remoteEntry.js\");\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:28
#, no-wrap
msgid ""
"  // Use the remote module as a normal module\n"
"  const result = math.add(1, 2);\n"
"  console.log(result); // 3\n"
"}\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:29
msgid "## Code quality and security"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:30
msgid ""
"Code quality and security are essential for ensuring that your code is "
"reliable, maintainable, and safe. They help you avoid bugs, errors, "
"vulnerabilities, and performance issues that can affect the functionality "
"and usability of your code. They also make it easier to review your code "
"changes and ensure that they meet the quality and security standards of your "
"team."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:31
msgid ""
"There are many tools available for code quality and security, such as Jest, "
"Mocha, Chai, Sinon, Cypress, Codecov, SonarQube, Snyk, etc. You can use them "
"to write unit tests, integration tests, end-to-end tests, code coverage "
"reports, code analysis reports, vulnerability scans, etc. for your code. You "
"can also integrate them with your editor, IDE, or build tool to run your "
"tests and generate your reports on save, on commit, or on build."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:32
msgid ""
"When working with Federated Modules, you should use the same code quality "
"and security tools and techniques across all your modules and applications. "
"This will ensure that your code is tested and verified across different "
"federated environments. You should also test and analyze the specific "
"aspects of Federated Modules in your code, such as the dynamic loading, the "
"module federation plugins, the shared scope, etc."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:33
msgid ""
"For example, if you are using Jest for unit testing, you can add the "
"following options to your `jest.config.js` file to support dynamic imports:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:34
#, no-wrap
msgid ""
"module.exports = {\n"
"  // Use babel-jest to transform dynamic imports\n"
"  transform: {\n"
"    \"^.+\\\\.js$\": \"babel-jest\",\n"
"  },\n"
"  // Use @module-federation/jest-federated-module-loader to mock remote modules\n"
"  moduleNameMapper: {\n"
"    \"@module-federation/jest-federated-module-loader\": \"@module-federation/jest-federated-module-loader\",\n"
"  },\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:35
msgid ""
"If you are using Codecov for code coverage reporting, you can add the "
"following options to your `.codecov.yml` file to ignore the module "
"federation plugins:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:36
#, no-wrap
msgid ""
"ignore:\n"
"  - \"**/webpack.config.js\" # Ignore webpack configuration files\n"
"  - \"**/remoteEntry.js\" # Ignore remote entry files generated by module federation plugins\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:37
msgid "## Dependency management and versioning"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:38
msgid ""
"Dependency management and versioning are important for managing the external "
"modules that your code depends on. They help you specify the exact versions "
"of the modules that your code requires, avoid conflicts and compatibility "
"issues with other modules or applications, and update your modules when new "
"versions are available. They also make it easier to review your code changes "
"and ensure that they do not introduce breaking changes or regressions."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:39
msgid ""
"There are many tools available for dependency management and versioning, "
"such as npm, yarn, pnpm, lerna, semver, etc. You can use them to install, "
"update, and publish your modules to a package registry, such as npm or "
"GitHub Packages. You can also use them to define the version ranges of your "
"modules using semantic versioning, which indicates the level of changes in "
"each version using major, minor, and patch numbers."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:40
msgid ""
"When working with Federated Modules, you should use the same dependency "
"management and versioning tools and practices across all your modules and "
"applications. This will ensure that your modules are installed and updated "
"consistently and correctly across different federated environments. You "
"should also use semantic versioning for your modules and follow the "
"principle of backward compatibility, which means that you should not "
"introduce breaking changes in minor or patch versions."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:41
msgid ""
"For example, if you are using npm for dependency management, you can add the "
"following options to your `package.json` file to specify the version ranges "
"of your dependencies using semantic versioning:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:42
#, no-wrap
msgid ""
"{\n"
"  \"dependencies\": {\n"
"    \"lodash\": \"^4.17.21\", // Accept any patch version greater than or equal to 4.17.21\n"
"    \"react\": \"~17.0.2\", // Accept any patch version greater than or equal to 17.0.2 but less than 17.1.0\n"
"    \"webpack\": \"5.65.0\" // Accept only the exact version 5.65.0\n"
"  }\n"
"}\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:43
msgid ""
"If you are using lerna for versioning, you can add the following options to "
"your `lerna.json` file to use semantic versioning for your packages:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:44
#, no-wrap
msgid ""
"{\n"
"  \"version\": \"independent\", // Use independent versioning for each package\n"
"  \"command\": {\n"
"    \"version\": {\n"
"      \"conventionalCommits\": true // Use conventional commits to determine the version bump\n"
"    }\n"
"  }\n"
"}\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:45
msgid "## Testing and debugging"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:46
msgid ""
"Testing and debugging are essential for verifying the functionality and "
"usability of your code. They help you find and fix errors, bugs, and issues "
"that can affect the behavior and performance of your code. They also make it "
"easier to review your code changes and ensure that they do not introduce new "
"errors or regressions."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:47
msgid ""
"There are many tools available for testing and debugging, such as Chrome "
"DevTools, Firefox DevTools, Visual Studio Code, Webpack Dev Server, etc. You "
"can use them to run your code in different browsers and devices, inspect and "
"modify your code and data at runtime, set breakpoints and watch expressions, "
"evaluate and execute your code in the console, etc. You can also integrate "
"them with your editor, IDE, or build tool to launch and debug your code on "
"save, on commit, or on build."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:48
msgid ""
"When working with Federated Modules, you should use the same testing and "
"debugging tools and techniques across all your modules and applications. "
"This will ensure that your code is tested and debugged across different "
"federated environments. You should also test and debug the specific aspects "
"of Federated Modules in your code, such as the dynamic loading, the module "
"federation plugins, the shared scope, etc."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:49
msgid ""
"For example, if you are using Chrome DevTools for debugging, you can use the "
"following steps to debug your federated modules:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:50
msgid ""
"Open the Sources panel and enable JavaScript source maps in the Settings."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:51
msgid ""
"Navigate to the webpack:// folder and find the federated modules that you "
"want to debug."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:52
msgid ""
"Set breakpoints or log points in the federated modules as you would normally "
"do."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:53
msgid "Reload the page or trigger the dynamic import of the federated modules."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:54
msgid "Observe the execution of the federated modules in the debugger."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:55
msgid "(screenshot)"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:56
msgid ""
"If you are using Webpack Dev Server for testing, you can use the following "
"options to enable hot module replacement (HMR) for your federated modules:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/team-collaboration-review.adoc:57
#, no-wrap
msgid ""
"module.exports = {\n"
"  // Enable HMR for development mode\n"
"  mode: \"development\",\n"
"  devServer: {\n"
"    hot: true,\n"
"  },\n"
"  plugins: [\n"
"    // Use ModuleFederationPlugin to expose or consume federated modules\n"
"    new ModuleFederationPlugin({\n"
"      // Enable HMR for federated modules\n"
"      hot: true,\n"
"      // Other options...\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/unit-testing.adoc:1
#, no-wrap
msgid "Module Federation: How to Create Unit Tests for Distributed Code"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:2
msgid ""
"In this guide, we'll cover the best practices for creating unit tests for "
"distributed code when using Module Federation. We'll discuss the challenges "
"and advantages of testing federated modules, along with techniques to ensure "
"your tests are thorough and maintainable."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/unit-testing.adoc:3
#, no-wrap
msgid "Introduction to Unit Testing in Module Federation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:4
msgid ""
"Unit testing is crucial for ensuring the reliability and maintainability of "
"your code, especially when working with distributed systems like Module "
"Federation. It helps you catch errors early, verify the correctness of your "
"code, and ensure that changes don't introduce unexpected behavior."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/unit-testing.adoc:5
#, no-wrap
msgid "Challenges in Testing Federated Modules"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:6
msgid ""
"Testing federated modules can be more challenging than testing traditional "
"code due to factors such as:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:7
msgid "At-runtime orchestration and code sharing"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:8
msgid "Asynchronous module loading"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:9
msgid "Remote dependencies and entry points"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:10
msgid "Diverse application environments"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:11
msgid ""
"Despite these challenges, it's essential to create robust unit tests for "
"your distributed code to ensure its reliability and maintainability."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/unit-testing.adoc:12
#, no-wrap
msgid "Best Practices for Testing Distributed Code"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:13
msgid ""
"Follow these best practices to ensure your unit tests for federated modules "
"are effective and maintainable:"
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/unit-testing.adoc:14
#, no-wrap
msgid "Isolate Test Cases"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:15
msgid ""
"Write independent test cases for each component or module to ensure that "
"they can be tested in isolation. This approach helps you identify issues "
"more easily and prevents cascading failures."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/unit-testing.adoc:16
#, no-wrap
msgid "Test Various Scenarios"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:17
msgid ""
"Test your federated modules in different scenarios to ensure that they work "
"correctly across various application environments and configurations."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/unit-testing.adoc:18
#, no-wrap
msgid "Ensure Test Coverage"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:19
msgid ""
"Ensure that your test suite provides comprehensive coverage of your "
"distributed code, including edge cases and potential error conditions."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/unit-testing.adoc:20
#, no-wrap
msgid "Federated Unit Tests"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:21
msgid ""
"The concept of federated unit testing builds upon the idea of federating "
"features in Module Federation. In this approach, you create a test build for "
"each repository involved in the federation, essentially creating a commonjs "
"\"server\" build that exposes the features as commonjs modules. This allows "
"you to test the federated components in isolation and perform liability "
"testing."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:22
msgid ""
"Let's take a look at an example that demonstrates federated unit testing "
"with Jest:"
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/unit-testing.adoc:23
#, no-wrap
msgid "1. Example Application"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:24
msgid "Consider an application with a form that imports a federated button."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/unit-testing.adoc:25
#, no-wrap
msgid ""
"import React, { Suspense } from \"react\";\n"
"import lazy from \"react-lazy-ssr\";\n"
"const Button = lazy(\n"
"  () => import(\"federated/Button\"), { chunkId: \"federated/Button\" }\n"
");\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/unit-testing.adoc:26
#, no-wrap
msgid ""
"const Form = () => (\n"
"  <form>\n"
"    <input type=\"text\" />\n"
"    <Suspense fallback={\"failed\"} loading={\"loading\"}>\n"
"      <Button />\n"
"    </Suspense>\n"
"  </form>\n"
");\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/unit-testing.adoc:27
#, no-wrap
msgid "export default Form;\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:28
msgid "In this scenario, there are two aspects to test:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:29
msgid "Button: supplied by its own Webpack build"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:30
msgid "Form: supplied by its own Webpack build"
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/unit-testing.adoc:31
#, no-wrap
msgid "2. Creating Test Builds"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:32
msgid ""
"To enable federated unit testing, create test builds for each repository "
"involved in the federation. In this example, we create test builds for both "
"the `form_app` and the `dsl` repositories:"
msgstr ""

#. type: Labeled list
#: src/en/modules/ROOT/pages/unit-testing.adoc:33
#, no-wrap
msgid "form_app repository"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/unit-testing.adoc:34
#, no-wrap
msgid ""
"new ModuleFederationPlugin({\n"
"  name: \"form_app\",\n"
"  filename: \"remoteEntry.js\",\n"
"  library: { type: \"commonjs-module\", name: \"form_app\" },\n"
"  remotes: {\n"
"    \"dsl\": reunited(\n"
"      path.resolve(__dirname, \"../dsl/dist-test/remoteEntry.js\"),\n"
"      \"dsl\"\n"
"    ),\n"
"  },\n"
"  exposes: {\n"
"    \"./Form\": \"./federated-cross-test/form.js\",\n"
"  },\n"
"  shared: {\n"
"    react: deps.devDependencies.react,\n"
"    \"react-dom\": deps.devDependencies[\"react-dom\"],\n"
"  },\n"
"});\n"
msgstr ""

#. type: Labeled list
#: src/en/modules/ROOT/pages/unit-testing.adoc:35
#, no-wrap
msgid "dsl repository"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/unit-testing.adoc:36
#, no-wrap
msgid ""
"new ModuleFederationPlugin({\n"
"  name: \"dsl\",\n"
"  filename: \"remoteEntry.js\",\n"
"  library: { type: \"commonjs-module\", name: \"dsl\" },\n"
"  exposes: {\n"
"    \"./Button\": \"./src/Button.js\",\n"
"  },\n"
"  shared: {\n"
"    react: deps.devDependencies.react,\n"
"    \"react-dom\": deps.devDependencies[\"react-dom\"],\n"
"  },\n"
"});\n"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/unit-testing.adoc:37
msgid "Both Button and Form are exposed for liability testing."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/unit-testing.adoc:38
#, no-wrap
msgid "3. Federated Unit Testing with Jest"
msgstr ""

#. type: delimited block =
#: src/en/modules/ROOT/pages/unit-testing.adoc:39
msgid ""
"With the test builds in place, you can use Jest to run tests against a "
"Webpack-built test of test files. This allows you to utilize Webpack's async "
"capabilities to import federated modules and test them."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/unit-testing.adoc:40
#, no-wrap
msgid ""
"// federated.test.js\n"
"import React from \"react\";\n"
"import { shallow, mount, render } from \"enzyme\";\n"
"// Form and Button are federated imports\n"
"const Form = import(\"form_app/Form\");\n"
"const Button = import(\"dsl/Button\");\n"
"import suspenseRender from \"./suspenseRender\";\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/unit-testing.adoc:41
#, no-wrap
msgid ""
"describe(\"Federation\", function () {\n"
"  it(\"is rendering Nested Suspense\", async () => {\n"
"    const from = await Form;\n"
"    console.log(await suspenseRender(from.default));\n"
"  });\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/unit-testing.adoc:42
#, no-wrap
msgid ""
"  it(\"Testing Button from Remote\", async function () {\n"
"    const Btn = (await Button).default;\n"
"    const wrapper = render(<Btn />);\n"
"    expect(wrapper).toMatchSnapshot();\n"
"  });\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/unit-testing.adoc:43
#, no-wrap
msgid ""
"  it(\"Testing Button from Form\", async function () {\n"
"    const Frm = (await Form).default;\n"
"    const wrapper = mount(<Frm />);\n"
"    expect(wrapper).toMatchSnapshot();\n"
"  });\n"
"});\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:44
msgid ""
"In this example, Jest processes an already-built test file, allowing you to "
"use federated imports in your tests. This is made possible by using Webpack "
"to compile the test files instead of Babel."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/unit-testing.adoc:45
#, no-wrap
msgid "4. Federated Test Build"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:46
msgid ""
"To enable federated testing with Jest, you need a special Webpack build that "
"compiles `.test.js` files only."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/unit-testing.adoc:47
#, no-wrap
msgid "// jest test/bundle.test.js\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/unit-testing.adoc:48
#, no-wrap
msgid ""
"// The webpack build that creates the test bundle.\n"
"const path = require(\"path\");\n"
"const glob = require(\"glob\");\n"
"const thisFile = path.basename(__filename);\n"
"const nodeExternals = require(\"webpack-node-externals\");\n"
"const { ModuleFederationPlugin } = require(\"webpack\").container;\n"
"const ReactLazySsrPlugin = require(\"react-lazy-ssr/webpack\");\n"
"const reunited = require(\"../index\");\n"
"const testFiles = glob\n"
"  .sync(\"!(node_modules)/**/*.test.js\")\n"
"  .filter(function (element) {\n"
"    return (\n"
"      element != \"test/bundle.test.js\" && !element.includes(thisFile)\n"
"    );\n"
"  })\n"
"  .map(function (element) {\n"
"    return \"./\" + element;\n"
"  });\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/unit-testing.adoc:49
#, no-wrap
msgid ""
"module.exports = {\n"
"  entry: { \"bundle.test\": testFiles },\n"
"  output: {\n"
"    path: path.resolve(__dirname, \".\"),\n"
"    filename: \"[name].js\",\n"
"  },\n"
"  target: \"node\",\n"
"  resolve: {\n"
"    fallback: {\n"
"      path: false,\n"
"    },\n"
"  },\n"
"  externals: [\n"
"    nodeExternals({\n"
"      allowlist: [/^webpack\\/container\\/reference\\//, /react/],\n"
"    }),\n"
"  ],\n"
"  mode: \"none\",\n"
"  module: {\n"
"    rules: [\n"
"      {\n"
"        test: /\\.js$/,\n"
"        exclude: /node_modules/,\n"
"        loader: \"babel-loader\",\n"
"      },\n"
"    ],\n"
"  },\n"
"  plugins: [\n"
"    new ModuleFederationPlugin({\n"
"      name: \"test_bundle\",\n"
"      library: { type: \"commonjs-module\", name: \"test_bundle\" },\n"
"      filename: \"remoteEntry.js\",\n"
"      exposes: {\n"
"        \"./render\": \"./test/suspenseRender.js\",\n"
"      },\n"
"      remotes: {\n"
"        form_app: reunited(\n"
"          path.resolve(__dirname, \"../form_app/dist/test/remoteEntry.js\"),\n"
"          \"form_app\"\n"
"        ),\n"
"        dsl: reunited(\n"
"          path.resolve(__dirname, \"../dsl/dist/remoteEntry.js\"),\n"
"          \"dsl\"\n"
"        ),\n"
"      },\n"
"    }),\n"
"    new ReactLazySsrPlugin(),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:50
msgid ""
"This build configuration includes the `ModuleFederationPlugin` and imports "
"both the `form_app` and `dsl` repositories' test builds."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/unit-testing.adoc:51
#, no-wrap
msgid "5. CI Integration and Code Streaming"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:52
msgid ""
"Integrating federated unit testing into your CI pipeline can be accomplished "
"in a few ways:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:53
msgid ""
"Pull down other repositories or storage buckets and execute them locally "
"within the test container. This is a rudimentary but effective approach."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:54
msgid ""
"Use code streaming (not publicly available yet and planned to be "
"commercial). This approach makes Node work like a browser by requiring "
"modules over sockets, HTTP, or S3. It simplifies CI integration and offers a "
"\"just works\" architecture."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:55
msgid ""
"The goal of code streaming is to provide a more straightforward deployment "
"mechanism, considering the vast resources spent on CI."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:56
msgid ""
"For a complete example of federated unit testing, refer to the following "
"repository:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:57
msgid ""
"https://github.com/module-federation/reunited[reunited: An example of "
"federated unit testing]"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:58
msgid ""
"This example demonstrates the core concept of having Jest process an already-"
"built test file, enabling the use of federated imports in your tests."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:60
msgid ""
"By following the steps and examples outlined in this guide, you can create a "
"robust and maintainable testing strategy for your federated applications. By "
"setting up the correct build configurations and leveraging the power of "
"Module Federation, you can ensure that your distributed code remains "
"functional and reliable."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:61
msgid ""
"In summary, the essential steps to create unit tests for distributed code "
"using Module Federation are:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:62
msgid "Expose components from each repository for testing."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:63
msgid ""
"Create a test build for each repository that exposes components as CommonJS "
"modules."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:64
msgid "Write federated test cases using Jest and the exposed components."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:65
msgid ""
"Set up a special Webpack build configuration to compile `.test.js` files."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:66
msgid ""
"Integrate federated unit testing into your CI pipeline using local execution "
"or code streaming."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:67
msgid ""
"With this approach, you can achieve a high degree of confidence that your "
"federated modules will work correctly across different codebases and "
"repositories. Moreover, by having individual teams take part in liability "
"tests, you can ensure that updates and changes to federated modules do not "
"cause unexpected issues in the consuming applications."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/unit-testing.adoc:68
msgid ""
"The future of federated unit testing includes further simplifications and "
"optimizations, such as code streaming, which will make the process even more "
"seamless and accessible. By adopting these best practices and staying up-to-"
"date with the latest advancements in Module Federation, you can continue to "
"build and maintain high-quality distributed applications with ease."
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/use-cases.adoc:1
#, no-wrap
msgid "Use Cases for Module Federation"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/use-cases.adoc:2
msgid ""
"While Module Federation has the potential to significantly improve code "
"sharing and reduce duplication, it is important to consider the specific use "
"cases where it may be most beneficial. In this guide, we'll explore some of "
"the most common use cases for Module Federation, including examples of how "
"it can be used in different scenarios."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/use-cases.adoc:3
#, no-wrap
msgid "Use Case 1: Microfrontend Architecture"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/use-cases.adoc:4
msgid ""
"One of the most common use cases for Module Federation is in microfrontend "
"architecture. This approach involves breaking down large monolithic "
"applications into smaller, more manageable frontend modules that can be "
"developed and deployed independently. With Module Federation, these modules "
"can be shared between different applications, allowing for greater "
"flexibility and modularity in application design."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/use-cases.adoc:5
msgid ""
"For example, imagine a large e-commerce platform with multiple frontend "
"applications for product search, shopping cart, and checkout. By using "
"Module Federation, the platform could share common modules such as user "
"authentication and payment processing between the different frontend "
"applications, reducing duplication and improving collaboration between "
"development teams."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/use-cases.adoc:6
#, no-wrap
msgid "Use Case 2: Multi-Application Integration"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/use-cases.adoc:7
msgid ""
"Another common use case for Module Federation is in integrating multiple "
"applications that share common functionality. With Module Federation, "
"developers can share modules between different applications, allowing them "
"to work together seamlessly and share data more efficiently."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/use-cases.adoc:8
msgid ""
"For example, imagine a suite of productivity applications such as a project "
"management tool, a team communication app, and a time-tracking tool. By "
"using Module Federation, these applications could share common modules such "
"as user authentication and data storage, allowing them to work together "
"seamlessly and share data more efficiently."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/use-cases.adoc:9
#, no-wrap
msgid "Use Case 3: Third-Party Integrations"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/use-cases.adoc:10
msgid ""
"Module Federation can also be used for integrating third-party modules and "
"applications into an existing application. With Module Federation, "
"developers can easily integrate modules from different sources, allowing "
"them to incorporate external functionality into their applications without "
"having to develop it from scratch."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/use-cases.adoc:11
msgid ""
"For example, imagine an e-commerce platform that wants to incorporate a "
"third-party shipping module into their application. With Module Federation, "
"the platform could easily integrate the shipping module into their "
"application, allowing customers to see shipping options and prices in real-"
"time."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/use-cases.adoc:12
#, no-wrap
msgid "Use Case 4: Shared Libraries"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/use-cases.adoc:13
msgid ""
"Finally, Module Federation can also be used for sharing libraries and other "
"common code between different applications. With Module Federation, "
"developers can easily share code libraries and other common functionality, "
"reducing duplication and improving collaboration between development teams."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/use-cases.adoc:14
msgid ""
"For example, imagine a suite of applications that all require access to a "
"common library of UI components. With Module Federation, these applications "
"could share the UI component library, allowing developers to make changes "
"and improvements to the library in one place, rather than having to make the "
"same changes across multiple applications."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/use-cases.adoc:16
msgid ""
"By carefully considering the specific needs and requirements of their "
"applications, developers can determine whether Module Federation is the "
"right solution for their particular use case. Whether it's microfrontend "
"architecture, multi-application integration, third-party integrations, or "
"shared libraries, Module Federation can help developers to reduce "
"duplication, improve collaboration, and increase flexibility in application "
"design."
msgstr ""

#. type: Title =
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:1
#, no-wrap
msgid "Module Federation: Versioned Shared Modules"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:2
msgid ""
"This article covers the enhanced features of Module Federation, focusing on "
"the concept of versioned shared modules. This concept introduces a new "
"system based on the versions of shared modules, thus improving the federated "
"builds' management, especially in complex host-remote relationship scenarios."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:3
#, no-wrap
msgid "Understanding the New System"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:4
msgid ""
"The new system changes the traditional host-remote relationship by basing "
"shared modules on their versions. In a federated build group, all parts "
"agree on the highest version of a shared module."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:5
msgid ""
"Each version of the shared module undergoes a semver-based requirement "
"check. It allows the existence of multiple versions of a shared module, "
"consumed as per the required version. This strategy enables remotes to "
"provide an upgraded version of a shared module to the federated app, paving "
"the way for better decoupling between the host and the remotes."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:6
#, no-wrap
msgid "Consumption Mode"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:7
msgid ""
"You might choose to consume a shared module but not provide one. This "
"strategy can reduce build time and deployment size when the container is "
"always used within a shell that provides these shared modules."
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:8
#, no-wrap
msgid "Version Checking Modes"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:9
msgid "Version checking for shared modules can be either strict or loose."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:10
#, no-wrap
msgid "**Strict mode**: The shared module won't be used if the version is not in the valid range. Instead, a fallback is used.\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:11
#, no-wrap
msgid "**Loose mode**: Shared modules are always used, but a warning is printed for invalid versions. The fallback is only used when no shared module is available.\n"
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:12
#, no-wrap
msgid "Initialization Phase"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:13
msgid ""
"There is an initialization phase in which all remotes (including remotes of "
"remotes) get an opportunity to provide shared modules. This is vital as a "
"deep nested remote might require a higher version of a shared module and "
"needs to have a chance to provide it."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:14
#, no-wrap
msgid "Specify package versions"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:15
msgid "You can specify versions for your shared modules in three ways:"
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:16
#, no-wrap
msgid "Array syntax"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:17
msgid ""
"This syntax allows you to share libraries with package name only. This "
"approach is good for prototyping, but it will not allow you to scale to "
"large production environment given that libraries like `react` and `react-"
"dom` will require additional requirements."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:18
#, no-wrap
msgid ""
"const { ModuleFederationPlugin } = require('webpack').container;\n"
"module.exports = {\n"
"  plugins: [\n"
"    new ModuleFederationPlugin({\n"
"      // adds lodash as shared module\n"
"      // version is inferred from package.json\n"
"      // there is no version check for the required version\n"
"      // so it will always use the higher version found\n"
"      shared: ['lodash'],\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:19
#, no-wrap
msgid "Object syntax"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:20
msgid ""
"While specifying shared packages, it is also essential to manage their "
"versions correctly. By default, the system infers the versions from your "
"`package.json` file. However, you can explicitly specify the version or a "
"range of versions using [Semantic Versioning https://semver.org/[SemVer]"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:21
msgid ""
"Here are some examples that further illustrate how to specify package "
"versions for shared modules:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:22
#, no-wrap
msgid ""
"// Example 6: Do not provide a local version, emit a warning if the shared vue is < 2.6.5 or >= 3\n"
"shared: {\n"
"  \"vue\": {\n"
"    import: false,\n"
"    requiredVersion: \"^2.6.5\",\n"
"    strictVersion: true\n"
"  }\n"
"}\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:23
#, no-wrap
msgid ""
"// Example 7: Add all dependencies as shared modules, using versions from package.json\n"
"shared: require(\"./package.json\").dependencies\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:24
#, no-wrap
msgid ""
"// Example 8: Change specific entries using object spread\n"
"const deps = require(\"./package.json\").dependencies;\n"
"shared: {\n"
"  ...deps,\n"
"  react: {\n"
"    requiredVersion: deps.react,\n"
"    singleton: true\n"
"  }\n"
"}\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:25
#, no-wrap
msgid ""
"// Example 9: Configure shared module with specific requirements\n"
"shared: {\n"
"  \"my-vue\": { \n"
"    import: \"vue\", \n"
"    shareKey: \"shared-vue\", \n"
"    shareScope: \"default\",\n"
"    singleton: true, \n"
"    strictVersion: true,\n"
"    version: \"1.2.3\", \n"
"    requiredVersion: \"^1.0.0\" \n"
"  }\n"
"}\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:26
msgid ""
"In the `requiredVersion` field, simple semantic versioning is allowed. You "
"can use the `^`, `~`, `>=`, and exact matching symbols. More complex ranges "
"are not supported to avoid the need for significant runtime code."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:27
#, no-wrap
msgid "Object syntax with sharing hints"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:28
msgid ""
"This syntax allows you to provide additional hints to each shared package "
"where you define the package name as the key, and the value as an object "
"containing hints to modify sharing behavior."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:29
#, no-wrap
msgid "const deps = require('./package.json').dependencies;\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:30
#, no-wrap
msgid ""
"module.exports = {\n"
"  plugins: [\n"
"    new ModuleFederationPlugin({\n"
"      shared: {\n"
"        // adds react as shared module\n"
"        react: {\n"
"          requiredVersion: deps.react,\n"
"          singleton: true,\n"
"        },\n"
"      },\n"
"    }),\n"
"  ],\n"
"};\n"
msgstr ""

#. type: Title ===
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:31
#, no-wrap
msgid "Sharing hints"
msgstr ""

#. type: Title ====
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:32
#, no-wrap
msgid "`eager`"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:33
msgid "`boolean``"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:34
msgid ""
"This hint will allow webpack to include the provided and fallback module "
"directly instead of fetching the library via an asynchronous request. In "
"other words, this allows to use this shared module in the initial chunk. "
"Also, be careful that all provided and fallback modules will always be "
"downloaded when this hint is enabled."
msgstr ""

#. type: Title ====
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:35
#, no-wrap
msgid "`import`"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:36
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:42
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:59
msgid "`false` | `string`"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:37
msgid ""
"The provided module that should be placed in the shared scope. This provided "
"module also acts as fallback module if no shared module is found in the "
"shared scope or version isn't valid. (The value for this hint defaults to "
"the property name.)"
msgstr ""

#. type: Title ====
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:38
#, no-wrap
msgid "`packageName`"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:39
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:45
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:48
msgid "`string`"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:40
msgid ""
"The package name that is used to determine required version from description "
"file. This is only needed when the package name can't be automatically "
"determined from request."
msgstr ""

#. type: Title ====
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:41
#, no-wrap
msgid "`requiredVersion`"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:43
msgid ""
"The required version of the package. It accepts semantic versioning. For "
"example, \"^1.2.3\"."
msgstr ""

#. type: Title ====
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:44
#, no-wrap
msgid "`shareKey`"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:46
msgid ""
"The requested shared module is looked up under this key from the shared "
"scope."
msgstr ""

#. type: Title ====
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:47
#, no-wrap
msgid "`shareScope`"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:49
msgid "The name of the shared scope."
msgstr ""

#. type: Title ====
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:50
#, no-wrap
msgid "singleton"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:51
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:55
msgid "`boolean`"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:52
msgid ""
"This hint only allows a single version of the shared module in the shared "
"scope (disabled by default). Some libraries use a global internal state (e."
"g. react, react-dom). Thus, it is critical to have only one instance of the "
"library running at a time."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:53
msgid ""
"In cases where there are multiple versions of the same dependency in the "
"shared scope, the highest semantic version is used."
msgstr ""

#. type: Title ====
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:54
#, no-wrap
msgid "`strictVersion`"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:56
msgid ""
"The `strictVersion` property plays a crucial role in managing shared "
"modules. If `strictVersion` is set to `true`, the shared module won't be "
"used unless the version is valid. In such cases, singleton or modules "
"without fallback will throw an error, otherwise the fallback module is used."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:57
msgid ""
"When a fallback module is provided, it is recommended to set `strictVersion` "
"to `true` as it will ensure that the shared module is only used if its "
"version is valid. If the shared module's version is not valid, then the "
"fallback module will be used instead, providing a safe fallback mechanism."
msgstr ""

#. type: Title ====
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:58
#, no-wrap
msgid "`version`"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:60
msgid ""
"The version of the provided module. It allows webpack to replace lower "
"matching versions, but not higher."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:61
msgid ""
"By default, Webpack uses the version from the package.json file of the "
"dependency."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:62
#, no-wrap
msgid "Example Scenarios"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:63
#, no-wrap
msgid " Here are a few examples that illustrate the various possibilities:\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:64
#, no-wrap
msgid ""
"// Example 1: Always use the higher version found\n"
"shared: [\"react\"]\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:65
#, no-wrap
msgid ""
"// Example 2: Use the highest moment version that is >= 2.20 and < 3\n"
"shared: {\n"
"  \"moment\": \"^2.20.0\"\n"
"}\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:66
#, no-wrap
msgid ""
"// Example 3: Use the shared version, but print a warning when the shared react is < 16.7 or >= 17\n"
"shared: {\n"
"  \"react\": {\n"
"    requiredVersion: \"^16.7.0\",\n"
"    singleton: true\n"
"  }\n"
"}\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:67
#, no-wrap
msgid ""
"// Example 4: Emit a warning if the shared vue is < 2.6.5 or >= 3\n"
"shared: {\n"
"  \"vue\": {\n"
"    import: false,\n"
"    requiredVersion: \"^2.6.5\"\n"
"  }\n"
"}\n"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:68
#, no-wrap
msgid ""
"// Example 5: Throw an error when the shared vue is < 2.6.5 or >= 3\n"
"shared: {\n"
"  \"vue\": {\n"
"    import: false,\n"
"    requiredVersion: \"^2.6.5\",\n"
"    strictVersion: true\n"
"  }\n"
"}\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:69
msgid ""
"In these examples, the shared property defines the shared modules, either as "
"an array of module names or as an object with additional configuration "
"options."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:70
msgid ""
"It's important to note that while hosts previously had clear control from "
"host to remote, the new system based on shared module versions allows "
"remotes to provide a higher version of a shared module to the federated app. "
"This change also permits two remotes to share a module without the host "
"being involved, or to share two different (major) versions of a module, "
"while still reusing compatible versions."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:71
#, no-wrap
msgid "Shared Module Initialization"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:72
msgid ""
"Remember that an initialization phase allows all remotes (including remotes "
"of remotes) to provide shared modules. This phase is crucial, as some deeply "
"nested remote might need a higher version of a shared module and should have "
"the opportunity to provide it. Asynchronous loading is available for all "
"remotes during this initialization phase."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:73
msgid ""
"By implementing and understanding these concepts, you can effectively manage "
"the versions of shared modules in a Module Federation context, ensuring "
"smoother collaboration and more reliable app performance."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:74
#, no-wrap
msgid "Consuming Modules Dynamically "
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:75
msgid ""
"A core advantage of the Module Federation approach lies in the ability to "
"dynamically consume modules from different containers. It allows modules to "
"be retrieved and initialized at runtime, fostering a flexible and efficient "
"application architecture.  This strategy also allows you to load an A/B test "
"dynamically, providing some newer versions of a shared module."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:76
msgid "Here is a sample code snippet on how to use a container dynamically:"
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:77
#, no-wrap
msgid ""
"// Initializes the share scope. This fills it with known provided modules from this build and all remotes\n"
"await __webpack_initialize_sharing__(\"default\");\n"
"const container = window.someContainer; // or get the container somewhere else\n"
"// Initialize the container, it may provide shared modules\n"
"await container.init(__webpack_share_scopes__.default);\n"
"const module = await container.get(\"./module\");\n"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:78
msgid "In the above code:"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:79
msgid ""
"First, we initialize the share scope using `__webpack_initialize_sharing__`. "
"This action fills the share scope with known provided modules from this "
"build and all remotes."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:80
msgid ""
"Next, we assign a specific container (in this case, `someContainer`) to the "
"`container` variable. You might retrieve the container from the window "
"object or any other source depending on your application architecture."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:81
msgid ""
"Then, we call `container.init` and pass `__webpack_share_scopes__.default` "
"as the argument. This action initializes the container, and it may provide "
"shared modules."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:82
msgid ""
"Finally, we call `container.get` with the module path we want to load from "
"the container. The `get` method returns a promise, so we use the `await` "
"keyword to pause execution until the promise is resolved."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:83
msgid ""
"If the container attempts to provide a shared module that has already been "
"used, a warning will be issued, and the provided shared module will be "
"ignored. However, the container might still use it as a fallback."
msgstr ""

#. type: Title ==
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:84
#, no-wrap
msgid "Singleton Mode and Eager Loading"
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:85
msgid ""
"Shared modules can operate in a singleton mode where only a single version "
"of the shared module is allowed. Any remote in the application can provide "
"this version, even if it's a deeply nested remote requiring a higher version "
"of the shared module. This version would then be used for the entire "
"application."
msgstr ""

#. type: Plain text
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:86
msgid ""
"Also, you may want your shared modules to be provided synchronously by "
"making them \"eager\". Eager shared modules are not placed in an "
"asynchronous chunk, enabling their use in the initial chunk. However, be "
"careful with this feature as all provided and fallback modules will always "
"be downloaded, which can lead to performance issues. It's recommended to use "
"this feature judiciously, providing eager modules only at a single point of "
"your app, such as the shell."
msgstr ""

#. type: delimited block -
#: src/en/modules/ROOT/pages/versioned-shared-modules.adoc:87
#, no-wrap
msgid ""
"// Example 10: Providing an eager module\n"
"     shared: {\n"
"        ...deps,\n"
"        react: {\n"
"          eager: true,\n"
"          singleton: true,\n"
"          requiredVersion: deps.react,\n"
"        },\n"
"        \"react-dom\": {\n"
"          eager: true,\n"
"          singleton: true,\n"
"          requiredVersion: deps[\"react-dom\"],\n"
"        },\n"
"      },\n"
msgstr ""
