/vueport

Single file components for Rails with Vue JS and Webpack

Primary LanguageRubyMIT LicenseMIT

Vueport

Single file components and SSR for Rails with Vue JS and Webpack

CircleCI Gem Version Gem Downloads

Vueport provides your Rails app with a modern, componentized approach to UI development by using Webpack and Vue.js to enable single file, reactive components rendered on the server and the client and seamless integration with your Rails views.

Take a look at the Vue.js documentation on single file components for more information on that side of things.

Vueport piggybacks onto the WebpackRails gem to get Webpack setup with Rails, so check that out for more information.

Example Rails App

Here.

Installation

Add this line to your application's Gemfile:

gem 'vueport'

And then execute:

$ bundle

Or install it yourself as:

$ gem install vueport

Then just run

rails generate vueport:install

to bootstrap everything you need to get started (this will install WebpackRails and also everything Vueport needs on top).

To run your app, execute

bundle exec foreman start -f Procfile.dev

to boot the Webpack Dev server and your Rails app!

Production Deployment

Ensure to run npm run compile (or yarn run compile) as part of your deployment process to production. This compiles the production version of your client side bundle, as well as compiling the server side bundle for our Node JS app to use.

In production we send HTTP requests to a basic NodeJS server to render our content. To run the Rails app and the Node server concurrently, use Procfile.

Usage

View Helper

Wrap your application in the vueport helper, to render out your components. E.g. in your application.html.erb:

<body>
    <%= vueport do %>
        <%= render partial: 'shared/nav' %>
        <%= yield %>
    <% end %>
</body>

It can also accept a single argument. E.g.:

<body>
    <%= vueport yield %>
</body>

Asset Setup

Add the Webpack Rails helpers to your layout to include your Javascript and CSS (see the WebpackRails readme for more information).

Ensure you place the JS entrypoint after the Vueport helper!

E.g.:

<head>
    <%= stylesheet_link_tag *webpack_asset_paths('application', extension:  'css') %>
</head>
<body>
    <%= vueport do %>
        <%= render partial: 'shared/nav' %>
        <%= yield %>
    <% end %>

    <%= javascript_include_tag *webpack_asset_paths("application", extension: 'js') %>
</body>

Default config

Out of the box, Vueport expects your components to live in app/components, and compiles assets to public/webpack. To change these, you'll need to change both the Webpack config (in config/webpack.config.js and config/webpack.server.js) and the Vue gem application config. To do this, in an initializer do:

Vueport.configure do |config|
    config[:server_port] = 3001
end

Check out the WebpackRails gem for information on its configuration.

How does it work?

What Vueport gives you is effectively 3 applications:

  • Your base rails app
  • A Node app for server side rendering in production (in /renderer)
  • A Node app for running webpack in development

These have been set up so that they can be built for production completely separately to avoid complicated pipelines—for example, you can run these 3 application using Docker completely separately meaning you don't need Ruby and Node in a single Dockerfile.

For more information on how Webpack has been integrated with Rails, check out this section of the Webpack Rails readme.

Server Side Rendering (SSR)

To enable Server Side rendering, I created a simple NodeJS app which uses the Vue Server Renderer to render out the contents of the page on each request. To enable Client Side rehydration, we also attach the original view contents in a template for the Client Side Vue instance to pick up.

SSR is only enabled in production.

Why Vue.js?

My experience of working with many modern UI libraries, and particulary with integrating them with Rails apps (especially React and Vue JS), has lead me to the conclusion that Vue JS seems to be a more explcit and 'batteries included' library when building compnents for Rails.

I use React on a regular basis for SPAs and love its functional philosophy, but for writing components to fit into a Rails frontend, Vue seems to provide me with the least complexity, and seems to be easiest for Ruby developers to reason about.

For a Vue.js and React collaborative comparison, check this out.

FAQs

  • I get the error Could not load compiled manifest from /app/public/webpack/manifest.json in production

    You'll need to run npm run compile as part of your build process to generate the production JS bundle (this error is generated by WebpackRails)

To Do

  • Handle SSR
  • Make webpack config more like the config from the Vue CLI template
  • Optimize SSR interaction with NodeJS
  • JS Component test setup

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/samtgarson/vueport. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

Thanks

  • Many thanks to Evan You and the VueJS team for sustaining such a vibrant and supportive community around Vue JS
  • Many thanks also to mipearson for his WebpackRails gem on which this gem relies.

License

The gem is available as open source under the terms of the MIT License.