Restrict Hyperstack components/models to only those necessary for some specific page to work?

67 Views Asked by At

When you access some page in Hyperstack, every model from app/hyperstack/models directory is included and sent to the browser. For the sake of security and performance, is it possible to load (automatically or by some directive) only the required code for the models and not that are used from the components?

Maybe this can be done in a way similar that policies work for data? So I am asking if there is some kind of policy in Hyperstack that restricts the code that is sent to the browser?

1

There are 1 best solutions below

2
On BEST ANSWER

There is no nice automatic way of doing this, but it's not too much work to achieve this. You would have to create a shared JS file of anything that's used on every page (opal, hyperstack, react, etc), and then create a separate JS file for every Page/Single Page App.


Here's a very basic example:

Application.js

# app/assets/javascripts/application.rb

require 'webpack/client_only'
require 'components/shared'

Shared JS file

# app/hyperstack/components/shared.rb

require 'opal'

require 'webpack/client_and_server'
require 'hyperstack-config'

# etc...

User Dashboard SPA:

# app/hyperstack/components/user_dashboard.rb

# Require shared models
require './models/user'

# Require shared components
require_tree './components/user_dashboard'

Todo List SPA:

# app/hyperstack/components/todo_list.rb

# Require shared models
require './models/todo'
require './models/user'

# Require shared components
require_tree './components/todo_list'

User Dashboard HTML Layout

# app/views/layouts/user_dashboard.html.erb

<%= javascript_include_tag('application.js') %>
<%= javascript_include_tag('components/todo_list.js') %>

Todo List HTML Layout

# app/views/layouts/todo_list.html.erb

<%= javascript_include_tag('application.js') %>
<%= javascript_include_tag('components/todo_list.js') %>


What I've also done to make it more dynamic is create a helper method in the controller to define the name of the separate JS file to use based on the controller. This also allows you to use only one layout file if desired:

# app/controllers/application_controller.rb

class ApplicationController
  helper_method :spa_asset

  def spa_asset
    params[:controller]
  end
end
# app/views/layouts/application.html.erb

<%= javascript_include_tag('application.js') %>
<%= javascript_include_tag(spa_asset) %>

And then inheriting controller can redefine it if the file name doesn't match the controller name:

# app/controllers/foo_controller.rb

class FooController
  def spa_asset
    'todo_list'
  end
end

Hope this helps!