Here, at Elixirator, we had a major rework for one of our projects. We were moving project's backend from Rails to Hanami as part of this task. The Rails application had a mix of the javascript code, including vanilla JS, Coffeescript, JQuery and React. The final goal was to get rid of all extra dependencies, and use only one approach for writing frontend code - React.js. READMORE
We have decided to use Webpack as the main source of all frontend code, including Javascript and CSS. One of the first steps of the migration was making Hanami and Webpack work together.
After some initial testing, the best approach was found for our needs. Here is a short overview how it can be done.
Webpack configuration
First what is needed to be done, is Webpack. Hopefully, there is nothing difficult here. Just some basic Webpack stuff. Dev server needs to be started at some address, serving assets from the specific location.
An example of simple configuration could look like this:
// webpack.config.js
{
output: {
path: path.join(__dirname, '..', 'public', 'assets'),
filename: '[name]-bundle.js',
publicPath: 'http://localhost:8080/assets/'
}
}
Hanami configuration
Hanami configuration is easy thanks to built-in helpers, which allow consuming assets from CDN. It is needed to specify content security policy to accept Javascript, CSS, images, etc. from location different than a website address. Providing config with the same host and port (as in the Webpack config) allows achieving this.
# application.rb
configure :development do
security.content_security_policy %(
script-src 'unsafe-eval' *;
connect-src 'self' *;
img-src 'self' data: *;
style-src 'unsafe-inline' *;
font-src 'self' *;
)
assets do
compile false
cdn true
host '0.0.0.0'
port 8080
end
end
Going live
Despite using React.js as our main frontend library, most of the views are still written in plain HTML. These views are using Hanami asset helpers, such as image
and javascript
. We wanted to keep them. And we wanted to keep digested assets provided to us by Hanami.
When I was looking for the solution, I have tried to solve manifest file generation from the Webpack side initially. But existing plugins were producing it with the format that was not understood by Hanami. After spending some time, trying to export manifest with JS, I realized that I can achieve same easily using plain Ruby.
Webpack already outputs filenames with digest hash inside to the specified folder. So all I need is just get all files in assets folder, and save them to the JSON in the format that could be understood by Hanami.
The final solution is really straightforward:
# assets_tasks.rake
namespace :assets do
desc 'Generate assets from webpack'
task :generate do
pty 'npm run build:development'
assets_hash = {}
Dir.glob('./public/assets/**/*.*').each do |f|
file = Pathname(f.sub('./public', ''))
folder = file.dirname
asset_name = file.basename.to_s.split('_').first
extension = file.extname
assets_hash["#{folder}/#{asset_name}#{extension}"] = { target: file, sri: '' }
end
File.open('./public/assets.json', 'w') { |f| f.write(assets_hash.to_json) }
end
end
Summary
As the result, we started to use the combination of Hanami and React.js as our main tools. Adding minor features like auto mounting of React components, using mini SPAs inside the application, made our experience really smooth and pleasant. Webpack integration was just one of the first steps of our journey from Rails to Hanami. But this is a really long story. Stay tuned.
Also recommend
We’re always attentive to the opinion of our customers and take into account all the shortcomings