Giter VIP home page Giter VIP logo

Comments (8)

bajtos avatar bajtos commented on August 18, 2024

An isomorphic client app, be it SPA or hybrid app, can be split into the following parts:

  1. LoopBack client implementing communication with backend, replication/offline sync. This client is a browserified loopback app (var app = loopback();) that provides Model classes for the actual client application (SPA/hybrid).
  2. The client application implemented using whatever framework - AngularJS, Backbone, even jQuery. The app may use a different build tooling, quite often based on Grunt.
  3. Glue to expose the client models in the means of the framework used by the client application. For AngularJS applications, this requires registering Model classes with the dependency injector. This AngularJS glue should be provided by loopback-angular in the future.

How to translate this idea into the project layout?

  1. There should be a new component (e.g. client/) that provides the browserified loopback app with all models. It should provide a single .js file (bundle) that can be added to any external SPAs without the need to use browserify again.

    Sample usage of the bundle:

    <script src="../client/loopback-client.js"></script>
    <script>
      var lbapp = require('loopback-client');
      // the LocalTodo model can be accessed as lbapp.models.LocalTodo
  2. The client application can be anything. For the sake of full-stack example, we should use generator-angular to scaffold the AngularJS SPA.

  3. The glue can be manually added to the scaffolded app.js file for now. It is basically the example described in 1. with automatic registration of all models:

    for (var modelName in lbapp.models)
     app.value(modelName, lbapp.models[modelName]);

from loopback-example-offline-sync.

bajtos avatar bajtos commented on August 18, 2024

/to @ritch the change proposed above will significantly affect the build module you are working on.

from loopback-example-offline-sync.

bajtos avatar bajtos commented on August 18, 2024

@ritch @seanbrookes thoughts?

from loopback-example-offline-sync.

bajtos avatar bajtos commented on August 18, 2024

The following tasks should be implemented as part of this issue too:

Split loopback-boot into two steps:

  1. gather all config files and produce one big JSON-like configuration of everything
  2. boot the application using the big JSON-like config object

In node.js server, we can call both methods at runtime.

In browserified clients, the build step will call 1. and the runtime will call 2.


Two possible solutions for boot/ scripts:

  1. require boot to have a static index.js require()ing all boot scripts
  2. let step1 to produce a list of files that will be required by the boot process and ensure in the build that these files are require()able in the browser by using b.export(path).

https://gist.github.com/bajtos/62413e23574d5511223b

from loopback-example-offline-sync.

ritch avatar ritch commented on August 18, 2024

This sounds like the loopback-angular approach. We generate (in this case build) an "SDK" like client that can be used by a client application, but the "SDK" is not the application itself. It enables us to decouple the "SDK" / client from the application implementation.

This means users don't have to wrap their head around browserify much, as the code can be delivered as a simple <script> tag. With this approach I think a simpler structure could be achieved that merges api and web into a single component as discussed in #22.

Something that looks like this:

/loopback-app
  /datasources.js
  /datasources.browser.js
  /models.json
  /models
    /todo.js
/express-app
  /app.js # mounts the loopback app `app.use('/api', require('../loobpack-app'));
  /public
    /index.html # includes <script src="loopback-app.js">....
    /spa.js # single page app
    /<anything>
/cordova-app
  /cordova-app.js 
/some-other-node-app
  /app.js # can require the loopback app and connect to the database directly or using the remote connector

I'm not sure how we would handle allowing code in the browser. When I originally wrote the full-stack example, I explicitly require()d the models I wanted to use in the browser. They weren't bundled for me.

from loopback-example-offline-sync.

bajtos avatar bajtos commented on August 18, 2024

Here is the structure I was thinking about

loopback-server-app/
  app.server.js
  datasources.json
  app-models.json

# shared models
# see Move models.json into /models #13
models/
  index.js
  todo.js
  todo.json

# SDK-like client
loopback-client-app/
  models/ # client-specific models
    index.js
    local-todo.js # locally stored Todo
  datasources.json # configure browser datasources
  app-models.json   # configure which models to expose in the app
  index.js
  gulpfile.js # browserify all into a bundle

cordova-app/
  cordova-app.js 

angular-app/
  index.html # includes the bundle from loopback-client-app
  routes/
  controllers/

express-app/
  app.js
  # mounts components:
  #    the loopback app `app.use('/api', require('../loobpack-app'));
  #    the angular SPA `app.use('/spa', loopback.static(..path-to-angular-app..))
  #    the index route redirects to SPA
  public/
    <anything>

/some-other-node-app
  /app.js # can require ../models and set them up to connect to the DB directly, or via remoting connector.

I'm not sure how we would handle allowing code in the browser. When I originally wrote the full-stack example, I explicitly require()d the models I wanted to use in the browser. They weren't bundled for me.

The design I have in my mind for #13 should allow you to pick the models you want to get bundled in loopback-client-app.

// loopback-client-app/index.js
// easy to add new files at the cost of larger bundle size
require('../models')(loopback);
require('./models')(loopback);
var app = loopback();
// uses app-models.json to decide which models to expose in the app 
bootLoopBackApp(app, ...);

// alternative: manually add a subset of models
require('../models/todo')(loopback);
// it's possible to hide the line above in ./models/local-todo.js
require('./models')(loopback);
var app = loopback();
// uses app-models.json to decide which models to expose in the app 
bootLoopBackApp(app, ...);

@ritch My plan was to make a series of "baby steps" changes steering towards the vision presented here, correcting the direction along the way. Each step should hopefully make sense on it's own, leaving the full-stack example in a state where it can be potentially "released". Despite that, I guess it may be difficult to review these baby steps without knowing the place these steps are heading to. Would it help if I wrote down a proposal outlining the new project structure I am hoping to arrive at?

from loopback-example-offline-sync.

bajtos avatar bajtos commented on August 18, 2024

Split loopback-boot into two steps:

gather all config files and produce one big JSON-like configuration of everything
boot the application using the big JSON-like config object
In node.js server, we can call both methods at runtime.

In browserified clients, the build step will call 1. and the runtime will call 2.

Done in strongloop/loopback-boot#5.

Let step1 to produce a list of files that will be required by the boot process and ensure in the build that these files are require()able in the browser by using b.export(path).

See strongloop/loopback-boot#6.

from loopback-example-offline-sync.

bajtos avatar bajtos commented on August 18, 2024

Done in #34.

from loopback-example-offline-sync.

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.