Giter Club home page Giter Club logo

Comments (10)

jonathanong avatar jonathanong commented on May 24, 2024

koa and the official middleware do not consider apps self-contained. always consider this and .app to always be that of the "root" app.

i don't think this is going to change.

from mount.

timkurvers avatar timkurvers commented on May 24, 2024

I see. What is then the idea behind modular, distributable apps? This would essentially mean that an app augmented with functionality which is relied upon in its routes would cease to function once mounted.

from mount.

jonathanong avatar jonathanong commented on May 24, 2024

this isn't a philosophical issue, purely implementational. we're just not sure how to implement this correctly, concisely, and make everyone happy, so we didn't bother at all.

from mount.

timkurvers avatar timkurvers commented on May 24, 2024

Ah, I'm sorry I misunderstood. I did give the following a shot locally, which seems to work for the setup I had:

diff --git a/index.js b/index.js
index 553260e..60acccc 100644
--- a/index.js
+++ b/index.js
@@ -47,21 +47,26 @@ function mount(prefix, app) {

   return function *(upstream){
     var prev = this.path;
+    var prevApp = this.app;
     var newPath = match(prev);
     debug('mount %s %s -> %s', prefix, name, newPath);
     if (!newPath) return yield* upstream;

     this.mountPath = prefix;
     this.path = newPath;
+    this.app = app;
     debug('enter %s -> %s', prev, this.path);

     yield* downstream.call(this, function *(){
       this.path = prev;
+      this.app = prevApp;
       yield* upstream;
+      this.app = app;
       this.path = newPath;
     }.call(this));

     debug('leave %s -> %s', prev, this.path);
+    this.app = prevApp;
     this.path = prev;
   }

I'd gladly open a pull request if this is something to have in the main repo.

from mount.

jonathanong avatar jonathanong commented on May 24, 2024

the problem is that you'll run into other issues like passing settings through each app. you don't want 100% encapsulation, but you also don't want 0%. if you have an idea of exactly how encapsulation would work, that would be great!

from mount.

timkurvers avatar timkurvers commented on May 24, 2024

Hm, good point. Currently, a mounted app that relies on settings through the context would need its settings to be applied to the root application, right?

What kind of settings would one like to share?

from mount.

jonathanong avatar jonathanong commented on May 24, 2024

this is the problem. people want different settings to be passed based on their app.

from mount.

timkurvers avatar timkurvers commented on May 24, 2024

Wouldn't it then be more correct and flexible to have settings separated and allow developers themselves to configure how they see fit?

That would mean in certain circumstances having to configure certain settings multiple times (e.g. custom envs or proxy), but that would make the whole thing more portable.

from mount.

luin avatar luin commented on May 24, 2024

This issue could be solved by creating an new context instead of using the parent's context:

before:

yield* downstream.call(this, function *(){

after:

var context = app.creatContext(this.req, this.res);
yield* downstream.call(context, function *(){

So that this.app will always refer to the current app instead of the "root" app. However this change of course breaks the backwards compatibility because koa-mount currently mounts the middlewares of an app rather than the app itself.

related issue: #5.


@jonathanong The current API(app.use(mount(otherApp))) is a little misleading as it indicates otherApp will be the sub-app of app(related issue koajs/session#33), and leaving out the backwards compatibility, I think app.use(mount(otherApp.middleware)) may be better.

from mount.

naxmefy avatar naxmefy commented on May 24, 2024

really hard trap....

koa = require 'koa'
mount = require 'koa-mount'
error = require 'koa-error'

rootApp = koa()
subApp = koa()

rootApp.use error()

rootApp.context.rofl = "Root not Groot"
subApp.context.rofl = "Sub?"
subApp.use (next) ->
    this.body = this.app.context.rofl
    yield next
rootApp.use mount subApp

rootApp.listen process.env.PORT, process.env.IP, (err) =>
    throw err if err
    console.log "Server running on #{process.env.IP}:#{process.env.PORT}"

this prints Root not Groot

But what if i put (like koajs documentation) the db to my context?

Example from koajs.com

app.context

The recommended namespace to extend with information that's useful throughout the lifetime of your application, as opposed to a per request basis.

app.context.db = db();

the mounting of koa apps means - mounting an encapsulated application - every other meaning make no sense - like this example...

koa = require 'koa'
mount = require 'koa-mount'
error = require 'koa-error'

rootApp = koa()
rootApp.context.db = rootDB()
rootApp.use error()

blogApp = koa()
blogApp.context.db = blogDB()
blogApp.use (next) ->
    results = yield @app.context.db().posts.sort('-createdBy').limit(10).exec()
    @state.latestPosts = results
    yield next

rootApp.use mount '/blog', blogApp

rootApp.listen process.env.PORT, process.env.IP, (err) =>
    throw err if err
    console.log "Server running on #{process.env.IP}:#{process.env.PORT}"

what could be a solution?

  1. every mounting app is using his own context
  2. the parent app will be injected e.g. as this.app.parent or more better and like express would be an event hook app.on('mount', function(parent){
koa = require 'koa'
mount = require 'koa-mount'
error = require 'koa-error'
_ = require 'lodash'

rootApp = koa()
rootApp.context.db = rootDB()
rootApp.use error()

blogApp = koa()
blogApp.on 'mount', (parent) ->
  _.merge blogApp.context.config, parent.context.config
  blogApp.context.db = blogDB blogApp.context.config.blog
# ...

rootApp.use mount '/blog', blogApp

rootApp.listen process.env.PORT, process.env.IP, (err) =>
    throw err if err
    console.log "Server running on #{process.env.IP}:#{process.env.PORT}"

this.state should be also shared because it is ruhsing throw the middlewares...

This is no solution...

module.exports = (subApp) ->
  return (next) ->
    this.app.context.db = subApp.context.db
    yield next

from mount.

Related Issues (20)

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.