# WebPack Hanami: 1.x
# Prerequisites
- WebPack is installed and handled by you
- You run it manually or inside Docker
- WebPack has config for 2 modes: WebpackDevServer and Production assest compilation (to files)
- WebPack Manifest.json is generated
- ENV vars are set up (true/false)
- USE_WEBPACK_DEV_SERVER
- USE_WEBPACK_GZIP
- Dry-Container is being used
# WebPack Manifest
Fragments of possible webpack.conf
output: {
path: path.resolve(__dirname, './public/assets'),
publicPath: publicPath,
filename: '[name].[hash].js'
},
// ...
plugins: [
new ManifestPlugin({
fileName: '../assets.json'
})
]
// ...
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# WebpackManifest parser
class WebpackManifest
attr_accessor :manifest
def initialize(manifest_path)
@manifest_path = manifest_path
@manifest = read_manifest
end
def read_manifest
begin
file = File.expand_path(@manifest_path)
file_contents = File.read(file)
rescue Exception => e
raise "Error while reading manifest file #{@manifest_path}. Does it exist? Exception details: #{e.message}"
end
JSON.parse(file_contents)
end
def resolve_entry(name)
entry = manifest[name]
if entry.nil?
raise "File #{name} is not found in Webpack Manifest"
end
entry
end
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Register single WebpackManifest instance
class Container
extend Dry::Container::Mixin
register('webpack_manifest', memoize: true) do
::WebpackManifest.new('public/assets.json')
end
#...
1
2
3
4
5
6
2
3
4
5
6
# WebPack View Helper
apps/web/views/webpack_helpers.rb
module WebpackHelpers
def javascript_pack_tag(script, use_dev_server=ENV['USE_WEBPACK_DEV_SERVER'], use_gzip=ENV['USE_WEBPACK_GZIP'])
if use_dev_server == "true"
url = [ENV['WEBPACK_DEV_SERVER_URL'], 'assets', script].join('/')
else
full_path = Container[:webpack_manifest].resolve_entry(script)
full_path = resolve_gzip_filename(full_path) if use_gzip == "true"
url = "#{full_path}"
end
raw %(<script src="#{url}"></script>)
end
def stylesheet_pack_tag(file, use_dev_server=ENV['USE_WEBPACK_DEV_SERVER'], use_gzip=ENV['USE_WEBPACK_GZIP'])
if use_dev_server == "true"
url = "" # do nothing as we consider style to be provided by Webpack Dev Server
else
full_path = Container[:webpack_manifest].resolve_entry(file)
full_path = resolve_gzip_filename(full_path) if use_gzip == "true"
url = "#{full_path}"
end
raw %(<link rel="stylesheet" type="text/css" href="#{url}" media="screen,projection" />)
end
def assets_path(file, use_dev_server=ENV['USE_WEBPACK_DEV_SERVER'])
if use_dev_server == "true"
[ENV['WEBPACK_DEV_SERVER_URL'], 'assets', file].join('/')
else
Container[:webpack_manifest].resolve_entry(file)
end
end
private
def resolve_gzip_filename(full_path)
filename_with_hash = [full_path.split('/').last, '.gz'].join
Container[:webpack_manifest].resolve_entry(filename_with_hash)
end
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
in application.rb
add
view.prepare do
#...
require_relative '../web/views/webpack_helpers'
include WebpackHelpers
end
1
2
3
4
5
2
3
4
5
# Use *_pack_tag in Template
apps/web/templates/application.html.erb
<!DOCTYPE html>
<html lang="en">
<head>
<%= stylesheet_pack_tag 'main.css' %>
</head>
<body>
<div id="app"></div>
<%= javascript_pack_tag 'main.js' %>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
TIP
main.css/main.js
exact names depends on how you have configured your webpack output
← RabbitMQ WebSockets →