How to share libraries across web components - reactjs

I've started a micro frontends project by utilizing custom elements.
I'm looking for a way to share dependencies between all of the parts of the application.
I'm wondering how I could do this with Material-ui library.
For example one could attach library to the window object and access it from inside of the custom element (web component).
The problem that I'm seeing here is that the material-ui exists as a npm module, and I haven't managed to find an option to load it via script tag.
The custom elements are loaded via
http import
which means that they will be loaded before the window object has been populated with the material-ui library.

I found one way of sharing libraries, for example UI libraries, such as Material-UI, and that is by putting them on a global scope (window object).
Then the web component (custom element) which is being included in the composition layer can read it from the window object inherited from the context in which it's included.
This approach can be easily used in case when there is only functionality needed. In case of UI library, where there is style as well, one has to pay attention if the shadow dom is turned on or not on the web component, and turn it off if it is.
Reason for this is the web component's shadow dom styles scoping capability, meaning one can simply inherit styles from a parent.
Here's a quick sample that I've made last year and now I've just made it work again :) github.com/mnemanja/web-components-composition

Related

Bullet-Proof Encapsulation of AngularJS Application/Controller

I am a ServiceNOW Developer. Recently, ServiceNOW replaced their Jelly based Content Management System with an AngularJS based Service Portal. This interface uses AngularJS widgets for display and data manipulation including the ability to create custom widgets. However, the fulfiller interface is still Jelly based.
ServiceNOW has constructs called UI Macros and UI Scripts that can be used within the Jelly interface to develop UI modules for which OOTB constructs are unavialable, like the widgets in the Service Portal. I tried to create an AngularJS based UI Macro that referencess the AngularJS App/Controller through an include of the UI Script that contains them. I created a mirror widget for the Service Portal that uses, essentially, the same AngularJS App/Controller.
The widget works beautifully in the Service Portal. The UI Macro works beautifully in the Service Catalog view. However, when the same UI Macro is included in a fulfillment record, it no longer functions correctly. The console logs indicate that there is a Controller conflict.
I am guessing that where ServiceNOW is inserting my UI Macro is in the middle of another AngularJS Application for which there is no expectation of another AngularJS application, only Jelly.
Therefore, my question is, is there a way to encapsulate my AngularJS Application/Controller in such a way that it will function completely on its own or if it is inserted into some other AngularJS Application/Controller i.e. that it is truly bulletproof and independent of what may be around it?
FYI: The results of a ServiceNOW HI Incident regarding this issue was that UI Macros should only be Jelly. However, the idea of having to maintain two completely different technologies for the same thing is not appealing. Therefore I am exploring all possibilities.
Thank you in advance.
Respectfully,
Robert
One option which is common in servicenow is making use of <iframe> HTML elements, it gives you the ability to have a separate page with a separate scope and a separate JS window object (will not conflict with the internal angular app)
You can encapsulate every thing in a UI page, consider it your Angular JS app main file and you can refer to this UI page like below:
<iframe src='https://<YOUR_INSTANCE>.service-now.com/<YOUR_UI_PAGE_NAME>.do'></iframe>

Create an extensible architecture with React

My team is creating the administration panel of a CMS using React, Typescript, TSX and Webpack. Each page of the administration panel has been created as a React component, and each page contains many other child components (one for each section).
The CMS distribution currently includes a bundled version of the javascript needed to run the web app, but not the original TSX files.
Now, we would like to make it possible to the developers using our CMS to extend the web app by
1) Injecting additional sections into the UI using a "slot-fill" approach
2) Possibly even overriding the existing sections rendering a different component in the same place.
<div>
<SidebarComponent />
<Section1Component />
<Section2Component />
// How to inject a possible PluginComponent here?
</div>
From the research we've conducted so far, there seem to be no "official" way to do this, so I'm wondering what would be the best approach in this case.
I am facing the same issue where I need a component from a plugin to interact with a component from another plugin with a hook system. I have a created a small codesanbox with the same approach adapted to your need.
Basically the approach is to create a injectedComponents.js at the root of your plugin that specifies in which plugin and area your component needs to be injected.
Here is ademo
single-spa has some good options in order to achieve this.
Please see if it can be help for you.
Microfrontends
Parcels
I am late to this but
Just create a utility class with registry function, and register each component to the registry (just dictionary of key value pair, where key is a constant and Value is the component). T
Then when you display a component in your base app, get it from the registry using a key. Then once you publish this whole base app as package ( make sure to export the utility registry). A user can register a component with the same name and override the default component.
For communication between totally independant components, you can use and EventEmitter

Is it possible to dynamically load an html template with angular components to a angular app which is AOT compiled?

In my angular application, back-end users can create custom templates. Those custom templates need to be loaded in the angular application at specific positions. I have a custom directive which gets templates
( based on the routes) from the CMS and inject it to my angular application. If I put it into the innerHTML the components will not get rendered correctly. I need componentFactoryResolver and compiler to properly show the components.
The above solution does not work with AOT compilation. Is there any other way I can achieve the same and make use of AOT? Is server side rendering is only solution to this?
Angular doesn't encourage using Compiler to create dynamic template.
Could/would/will code using COMPILER_PROVIDERS be supported by AOT?
But maybe in future it will be possible with without shipping the compiler because new View Engine open new capabilities.
Properties
the generated code relies on very few internals.
we can make the API public and stable
users could ship the generated factory files on npm
this makes calls to ngc in applications faster as it does not need
to compile the code of libraries like Ionic any more.
users could implement their own ViewEngine
this way we can drop the Renderer abstraction, as we already have an indirection via the ViewEngine
users could create templates programmatically during runtime
without shipping the compiler
eg for a dynamic form / ....
we might want to provide a builder for this that calculates indices correctly and can already be used in tests
we could create a new kind of directive that transforms a ViewDefinition, e.g. wraps elements into new ones, ... (similar to the compile in Angular 1).
needs some helpers that maps indices from new to original indices
Read more in Design Doc for View Engine

angular2: service with a template?

I am trying to create a service for showing alerts (in case sending a form goes wrong). This will be used on various forms of my project so I thought I could use an independant service for this. The problem is: for this alert I need HTML code at a certain place of my form, so what I need to know is : what's best practice for that?
Can I define a template for my service? And how do I use this template in my form wihch uses the service?
I had a difficult time using angular2 packages for notifications then I decided to create my own notification for a system I'm working on. I scrapped online till I found Mathew Ross' Post Check it out and see if it guides you, somehow.
If showing alerts means showing a popup then it should be a component. Components have a view that is added to the DOM.
You can share a global service that allows other components, directives and services to communicate with your AlertsComponent and pass strings or component types to be shown in the alert. For more details see https://angular.io/docs/ts/latest/cookbook/component-communication.html
I would use ViewContainerRef.createComponent() like demonstrated in Angular 2 dynamic tabs with user-click chosen components to display arbitrary components as content of the alert if you need custom HTML support with Angular bindings in the alert content.

Use React with a non-browser JS environment

Very open ended, apologies in advance.
I've been going through the docs and searching google incessantly, but I'm wondering what steps I would need to take to use react with a non-browser JavaScript environment.
Some context on the environment:
The environment uses JavaScript to run a UI, it has http capabilities.
There is no html, css, document, window, HTMLElement, etc.
The environment does have the notion of a hierarchy, changes to the object hierarchy in JS cross the bridge and trigger a render through a graphics platform like OpenGL for instance. The environment does get input via keys and or a mouse.
If there's a roadmap to do this or something like an architecture diagram to refer to, that'd be fantastic.
Any help/advice is appreciated.
thanks in advance,
-dylan
ReactJS work with DOM, so environment need to have DOM structure, that means no HTML no DOM. Or you can use server render of React component, but you will get a string as result.
Read more here:
React.renderComponentToString

Resources