Giter VIP home page Giter VIP logo

Comments (6)

nikospara avatar nikospara commented on June 9, 2024

Hello Maciej!

The short answer is, unfortunately, no. I haven't even ever thought about this question. In contrast, I have considered many times how can a JS module be unloaded, but always in the context of an application that "is here to stay".

Why would you want to do that?

I could think of two perilous workarounds: (1) dig into the code and create a function that effectively reverses Angular's bootstrap procedure or (2) launch the disposable app in an iframe.

from angular-require-lazy.

maciej-gurban avatar maciej-gurban commented on June 9, 2024

I'm working on an app that would allow me to load multiple angular application one after another into the same document; premise being: one angular app in document at a time. Angular 1.x relies quite heavily on the framework being available on window.angular, so to do that I need to clear it on every app load, detach listeners and remove its root element.

I'm bootstrapping the applications manually to be able to load them in any order, and load them even multiple times (just not loading the same app multiple times in a row of course), and to do that I'm supplying a DOM element for the bootstrap process.

Here's where my question came from:
To make sure all bindings are broken, I was creating new element, appending it to DOM, and bootstrapping the app on that new element. This was not working for certain cases (from what I could gather, UI router might have been responsible). What I ended up doing is creating a new element, and bootstrapping angular on that element, but before appending in to DOM, and only after the bootstrapping happened, do I append it to DOM. This automagically works.

I'm not entirely sure how does angular "know" that I'm re-bootstrapping an app on element that it had bootstrapped on before (it's a totally new DOM node after all, even with different unique id, just appended to the same container element). I might be because I haven't tackled yet removing all app listeners, but that's probably not it, since I've been using the cloneNode() method that apparently takes care of destroying those.

from angular-require-lazy.

nikospara avatar nikospara commented on June 9, 2024

This automagically works.

That would be really fun! But I would always be scared that I have missed something (a corner case, an upgraded app that suddenly becomes incompatible...)

The iframe option seems inviting after all...

from angular-require-lazy.

maciej-gurban avatar maciej-gurban commented on June 9, 2024

Sorry in advance for a wall of text!

You're absolutely right! There's lots of things that can potentially break the whole thing. I'm working on a prototype that aims to figure out what exactly and to what extend can break, but also in what circumstances will things break, and how to detect these problems before shipping them to production.

Problems with iframes are unfortunately plenty - there's no way to have routing work between the apps (you could never share a link to a place in the sub app), data exchange/sharing on the frontend side becomes impossible, and security implications... I'd not even go there.

All of these make it a really bad idea. Of course the other approach - on-demand module/app loading - has plenty of issues as well, but if we discard iframes as an approach, we'll be presented with very few possible solutions to what I'm after.

What I'm after is a centralised and consistent user experience for users visiting a portal that to their eyes is one application, but under the hood is maintained by various different teams, and consists of different code repositories.

Here's what we can do:
We can either have one monolithic codebase, which is forever stuck at certain framework or dependency versions. Cooperation in such a project, while in theory possible, becomes a nightmare if you have to account for teams that often do not work from the same office, or even relatively close time zones. Changes becomes extremely slow and painful, development and agility falls on its head, and people are unhappy.

The other approach is to have multiple still small codebases, which then implement a common navigational component, but unless we can guarantee that everybody has the same framework and dependencies, we can't reuse that component, so we will end up rewriting and maintaining it separately for multiple teams. Additionally we now have full page reloads between what from a user's perspective is just a link in a navigation / a section of currently loaded app.

As a offshoot of this idea, something what StackOverflow (and probably Google) is doing could be implemented. This means generating the navigation on the server-side and shipping it fully rendered to the client, which is also a solution, but quite limited.

So finally, as a solution to what really is a non-technical issue, came the idea of loading multiple apps into the same document. It sounds totally crazy at first, feels very fragile in execution, and it's entirely possible that it's not feasible (yet), but that's what I'm trying to figure out.

What the web is moving towards is web components, and technical implications of that don't differ that much from what I'm doing, so the me the questions is not exactly: "can this work", but "can this work already?"

from angular-require-lazy.

nikospara avatar nikospara commented on June 9, 2024

Your case is interesting and challenging. Some more thoughts - for what they're worth:

If I understand correctly the key requirement is that users perceive this system as one application. This already imposes some constraints I guess: The look and feel of each component application must be the same. They would eventually need to share some kind of data. (Sharing at least user information would be nice.) And what about shared code? (I.e. if two apps are using Angular 1, why having to load Angular twice? It is big! But if you do not load it twice, then you must enforce that the teams developing the 2 apps use the same version of Angular.) They have to have some underlying navigation logic, if you do not want full-page refreshes when apps switch.

Do you want to support different technologies per app, e.g. app1: Angular1, app2: React, app3: Ember and so on? If so, things get tough I believe.

If not, do you have a minimal technology guarantee, i.e. everybody using Angular 1? (Off topic opinion: Angular 1 is really getting old, I would try something more up-to-date for a new system.)

If you can enforce a minimal technology, e.g. "everybody uses Angular 1" then it would probably be worth developing a module framework on top of that technology.

from angular-require-lazy.

maciej-gurban avatar maciej-gurban commented on June 9, 2024

You're right on the unified look & feel - that definitely needs to happen and is one of the goals of this project, and about sharing data - the main app would do that indeed - why fetch user data three times when you can do it once.

About loading Angular 1.x only once if two teams use the same version. All things considered, Angular 1.x is known to introduce huge (and breaking) changes between its minor versions. If two teams were to use a single version, they'd need to sync on how and when to update, which would slow down both of them, and many any updates more complex and scary.

Currently, all apps are Angular 1.x, but the more modern the framework, the more modular it is. Looking at React or Vue, they do a pretty good job and not polluting global scope and cleaning up after themselves. The biggest concern for me is dependencies, which aren't always held to the same quality standard as frameworks.

For example, Babel polyfills should probably be only loaded by the main app to avoid a situation where two projects use a different version of a specific polyfill. We should be able to depend on a browser feature to behave the same way, regardless of app/version.

Look like we're going to write something simple to detect what loading an app introduces to window object, and what global events listeners it creates, cache these and restore upon loading the app again.

Routing was an interesting problem. Surprisingly, you can have two routers (one from React, one from Angular) and they can co-exist and react to the same routes without issues.

from angular-require-lazy.

Related Issues (7)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.