Skip to content

Commit

Permalink
webpack 5
Browse files Browse the repository at this point in the history
  • Loading branch information
MariaAga committed Nov 9, 2023
1 parent 76ec08d commit 452403b
Show file tree
Hide file tree
Showing 30 changed files with 744 additions and 360 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Base container that is used for both building and running the app
FROM quay.io/centos/centos:stream8 as base
ARG RUBY_VERSION="2.7"
ARG NODEJS_VERSION="12"
ARG NODEJS_VERSION="14"
ENV FOREMAN_FQDN=foreman.example.com
ENV FOREMAN_DOMAIN=example.com

Expand Down
5 changes: 4 additions & 1 deletion Procfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@
# If you wish to use a different server then the default, use e.g. `export RAILS_STARTUP='puma -w 3 -p 3000 --preload'`
rails: [ -n "$RAILS_STARTUP" ] && env PRY_WARNING=1 $RAILS_STARTUP || [ -n "$BIND" ] && bin/rails server -b $BIND || env PRY_WARNING=1 bin/rails server
# you can use WEBPACK_OPTS to customize webpack server, e.g. 'WEBPACK_OPTS='--https --key /path/to/key --cert /path/to/cert.pem --cacert /path/to/cacert.pem' foreman start '
webpack: [ -n "$NODE_ENV" ] && ./node_modules/.bin/webpack-dev-server-without-h2 --config config/webpack.config.js $WEBPACK_OPTS || env NODE_ENV=development ./node_modules/.bin/webpack-dev-server-without-h2 --config config/webpack.config.js $WEBPACK_OPTS
webpack: [ -n "$NODE_ENV" ] && npx webpack --config config/webpack.config.js --watch $WEBPACK_OPTS || env NODE_ENV=development npx webpack --config config/webpack.config.js --watch --analyze
#TODO readme/forklift to change/remove --key to --server-options-key
# --public -> --client-web-socket-url and see why it doesnt work
# --https --> --server-type
1 change: 1 addition & 0 deletions app/assets/config/manifest.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//= link late_load.js
//= link_tree ../../../vendor/assets/fonts
//= link_tree ../images
//= link application.css
Expand Down
11 changes: 10 additions & 1 deletion app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,18 @@
//= require lookup_keys

$(function() {
$(document).trigger('ContentLoad');
$(document).on('loadJS', function() {
$(document).trigger('ContentLoad');
});
});


// Override jQuery's ready function to run only after all scripts are loaded instead of when the DOM is ready
$.fn.ready = function(fn) {
this.on('loadJS', fn);
return this;
};

// Prevents all links with the disabled attribute set to "disabled"
// from being clicked.
var handleDisabledClick = function(event, element){
Expand Down
6 changes: 3 additions & 3 deletions app/assets/javascripts/host_edit_interfaces.js
Original file line number Diff line number Diff line change
Expand Up @@ -413,9 +413,9 @@ $(document).on('change', '.interface_mac', function(event) {
.find('.interface_mac')
.attr('id')
) {
var interface = $('#interfaceModal').find('.interface_mac');
var mac = interface.val();
var baseurl = interface.attr('data-url');
var interface_ = $('#interfaceModal').find('.interface_mac');
var mac = interface_.val();
var baseurl = interface_.attr('data-url');
$.ajax({
type: 'GET',
url: baseurl + '?mac=' + mac,
Expand Down
51 changes: 51 additions & 0 deletions app/assets/javascripts/late_load.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
function load_dynamic_javascripts(html) {
function waitForAllLoaded() {
// Wait for all plugins js modules to be loaded before loading the javascript content
return new Promise(function(resolve) {
if (Object.values(window.allPluginsLoaded).every(Boolean)) {
resolve();
} else {
function handleLoad() {
if (Object.values(window.allPluginsLoaded).every(Boolean)) {
resolve();
// Remove the event listener
document.removeEventListener('loadPlugin', handleLoad);
}
}
document.addEventListener('loadPlugin', handleLoad);
}
});
}
waitForAllLoaded().then(async function() {
// parse html string
var template = document.createElement('template');
template.innerHTML = html;
var doc = new DOMParser().parseFromString(html, 'text/html');
var copyChildren = [...doc.head.children];
const loadScript = async scripts => {
if (scripts.length === 0) {
// All scripts are loaded
window.allJsLoaded = true;
const loadJS = new Event('loadJS');
document.dispatchEvent(loadJS);
return;
}
const script = scripts.shift();
if (script.src) {
// if script is just a link, add it to the head
const scriptTag = document.createElement('script');
scriptTag.src = script.src;
scriptTag.onload = function() {
// To load the next script only after the current one is loaded
loadScript(scripts);
};
document.head.appendChild(scriptTag);
} else {
// if the script is a script tag, evaluate it and load the next one
await eval(script.innerHTML);
loadScript(scripts);
}
};
loadScript(copyChildren);
});
}
5 changes: 0 additions & 5 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -331,11 +331,6 @@ def hosts_count(resource_name = controller.resource_name)
@hosts_count ||= HostCounter.new(resource_name)
end

def webpack_dev_server
return unless Rails.configuration.webpack.dev_server.enabled
javascript_include_tag "#{@dev_server}/webpack-dev-server.js"
end

def accessible_resource_records(resource, order = :name)
klass = resource.to_s.classify.constantize
klass = klass.with_taxonomy_scope_override(@location, @organization) if klass.include? Taxonomix
Expand Down
22 changes: 22 additions & 0 deletions app/helpers/layout_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,28 @@ def javascript(*args)
content_for(:javascripts) { javascript_include_tag(*args) }
end

def javascript_include_tag(*params, **kwargs)
# Workaround for overriding javasctipt load with webpack_asset_paths, should be removed when webpack_asset_paths is removed
if kwargs.is_a?(Hash) && kwargs[:source] == "webpack_asset_paths"
kwargs[:webpacked]
else
super(*params, **kwargs)
end
end

def webpack_asset_paths(plugin_name, extension: 'js')
if extension == 'js'
Foreman::Deprecation.deprecation_warning('3.12', '`webpack_asset_paths` is deprecated, use `content_for(:javascripts) { webpacked_plugins_js_for(plugin_name) }` instead.')
[{
source: 'webpack_asset_paths',
webpacked: webpacked_plugins_js_for(plugin_name.to_sym),
}]
elsif extension == 'css'
Foreman::Deprecation.deprecation_warning('3.12', '`webpack_asset_paths` is deprecated and not needed for css assets.')
nil
end
end

# The target should have class="collapse [out|in]" out means collapsed on load and in means expanded.
# Target must also have a unique id.
def collapsing_header(title, target, collapsed = '')
Expand Down
44 changes: 25 additions & 19 deletions app/helpers/reactjs_helper.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'webpack-rails'
require 'json'

module ReactjsHelper
# Mount react component in views
# Params:
Expand All @@ -11,10 +12,6 @@ def react_component(name, props = {})
content_tag('foreman-react-component', '', :name => name, :data => { props: props })
end

def webpacked_plugins_with_global_css
global_css_tags(global_plugins_list).join.html_safe
end

def webpacked_plugins_js_for(*plugin_names)
js_tags_for(select_requested_plugins(plugin_names)).join.html_safe
end
Expand All @@ -24,7 +21,25 @@ def webpacked_plugins_with_global_js
end

def webpacked_plugins_css_for(*plugin_names)
css_tags_for(select_requested_plugins(plugin_names)).join.html_safe
Foreman::Deprecation.deprecation_warning('3.9', '`webpacked_plugins_css_for` is deprecated, plugin css is already loaded.')
end

def read_webpack_manifest
root = File.expand_path(File.dirname(__FILE__) + "/../..")
file = File.read(root + '/public/webpack/manifest.json')
JSON.parse(file)
end

def get_webpack_foreman_vendor_js
data = read_webpack_manifest
foreman_vendor_js = data['assetsByChunkName']['foreman-vendor'].find { |value| value.end_with?('.js') }
javascript_include_tag("/webpack/#{foreman_vendor_js}")
end

def get_webpack_foreman_vendor_css
data = read_webpack_manifest
foreman_vendor_css = data['assetsByChunkName']['foreman-vendor'].find { |value| value.end_with?('.css') }
stylesheet_link_tag("/webpack/#{foreman_vendor_css}")
end

def select_requested_plugins(plugin_names)
Expand All @@ -39,30 +54,21 @@ def select_requested_plugins(plugin_names)

def js_tags_for(requested_plugins)
requested_plugins.map do |plugin|
javascript_include_tag(*webpack_asset_paths(plugin.to_s, :extension => 'js'))
javascript_tag("window.tfm.tools.loadPluginModule('/webpack/#{plugin.to_s.tr('-', '_')}','#{plugin.to_s.tr('-', '_')}','./index');".html_safe)
end
end

def global_js_tags(requested_plugins)
requested_plugins.map do |plugin|
plugin[:files].map do |file|
javascript_include_tag(*webpack_asset_paths("#{plugin[:id]}:#{file}", :extension => 'js'))
end
end
end

def global_css_tags(requested_plugins)
requested_plugins.map do |plugin|
plugin[:files].map do |file|
stylesheet_link_tag(*webpack_asset_paths("#{plugin[:id]}:#{file}", :extension => 'css'))
javascript_tag("window.tfm.tools.loadPluginModule('/webpack/#{plugin[:id].to_s.tr('-', '_')}','#{plugin[:id].to_s.tr('-', '_')}','./#{file}_index');".html_safe)
end
end
end

def css_tags_for(requested_plugins)
requested_plugins.map do |plugin|
stylesheet_link_tag(*webpack_asset_paths(plugin.to_s, :extension => 'css'))
end
Foreman::Deprecation.deprecation_warning('3.12', '`css_tags_for` is deprecated, No need to load CSS separately, since it should be referneced from the corresponding JS file.')
[]
end

def locale_js_tags
Expand Down
7 changes: 5 additions & 2 deletions app/views/hosts/console/spice.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,8 @@
</div>
<div id="spice-screen" class="console-screen"> </div>
<% end %>

<script type="text/javascript"> tfm.spice.startSpice() </script>
<% content_for(:javascripts) do %>
<script type="text/javascript">
tfm.spice.startSpice()
</script>
<% end %>
22 changes: 11 additions & 11 deletions app/views/layouts/base.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,8 @@
<%= yield(:meta) %>

<%= favicon_link_tag "favicon.ico"%>

<%= stylesheet_link_tag *webpack_asset_paths('foreman-vendor', :extension => 'css') %>
<%= stylesheet_link_tag *webpack_asset_paths('bundle', :extension => 'css') %>
<%= get_webpack_foreman_vendor_css %>
<%= stylesheet_link_tag 'application' %>
<%= webpacked_plugins_with_global_css %>
<%= yield(:stylesheets) %>

<%= csrf_meta_tags %>
Expand All @@ -33,18 +30,21 @@
</script>
<%= javascript_include_tag "locale/#{FastGettext.locale}/app" %>
<%= locale_js_tags %>

<%= stylesheet_link_tag('/webpack/bundle', :extension => 'css') %>
<%= yield(:head) %>
</head>

<body class='<%= body_css_classes %>'>
<%= javascript_include_tag *webpack_asset_paths('foreman-vendor', :extension => 'js') %>
<%= javascript_include_tag *webpack_asset_paths('vendor', :extension => 'js') %>
<%= javascript_include_tag *webpack_asset_paths('bundle', :extension => 'js') %>
<%= get_webpack_foreman_vendor_js %>
<%= javascript_include_tag('/webpack/vendor.js') %>
<%= javascript_include_tag('/webpack/bundle.js') %>

<%= javascript_include_tag 'application' %>
<%= webpacked_plugins_with_global_js %>
<%= webpack_dev_server %>
<%= yield(:javascripts) %>
<%= javascript_include_tag('late_load') %>
<script type="text/javascript">
const html = "<%= escape_javascript(yield(:javascripts)) %>"
load_dynamic_javascripts(html);
</script>
<script type="text/javascript">
<%= yield(:inline_javascripts) %>
</script>
Expand Down
9 changes: 5 additions & 4 deletions app/views/report_templates/report_data.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<% title _("Download generated report") %>

<%= react_component('TemplateGenerator', data: { templateName: @template.name }) %>

<script type="text/javascript">
tfm.templateInputs.pollReportData('<%= @data_url %>');
</script>
<% content_for(:javascripts) do %>
<script type="text/javascript">
tfm.templateInputs.pollReportData('<%= @data_url %>');
</script>
<% end %>
8 changes: 5 additions & 3 deletions app/views/users/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,11 @@
<% end %>

<% if @user.cached_usergroups.any? %>
<script>
<% content_for(:javascripts) do %>
<script>
$(function() {
tfm.users.initInheritedRoles();
});
</script>
});
</script>
<% end %>
<% end %>
2 changes: 1 addition & 1 deletion bundler.d/assets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
gem 'gettext_i18n_rails_js', '~> 1.4'
gem 'po_to_json', '~> 1.1'
gem 'execjs', '>= 1.4.0', '< 3.0'
gem 'uglifier', '>= 1.0.3'
gem "terser", "~> 1.1"
gem 'sass-rails', '~> 6.0'
# this one is a dependecy for x-editable-rails
gem 'coffee-rails', '~> 5.0.0'
Expand Down
2 changes: 1 addition & 1 deletion config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
config.public_file_server.enabled = ENV.fetch('RAILS_SERVE_STATIC_FILES', false) == 'true'

# Compress JavaScripts and CSS.
config.assets.js_compressor = :uglifier
config.assets.js_compressor = :terser
# config.assets.css_compressor = :sass

# Do not fallback to assets pipeline if a precompiled asset is missed.
Expand Down
30 changes: 0 additions & 30 deletions config/initializers/assets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,35 +53,5 @@ class << self
ActionView::Base.assets_manifest = app.assets_manifest
end
end

# When the dev server is enabled, this static manifest file is ignored and
# always retrieved from the dev server.
#
# Otherwise we need to combine all the chunks from the various webpack
# manifests. This is the main foreman manifest and all plugins that may
# have one. We then store this in the webpack-rails manifest using our
# monkey patched function.
unless config.webpack.dev_server.enabled
if (webpack_manifest_file = Dir.glob("#{Rails.root}/public/webpack/manifest.json").first)
webpack_manifest = JSON.parse(File.read(webpack_manifest_file))

Foreman::Plugin.with_webpack.each do |plugin|
manifest_path = plugin.webpack_manifest_path
next unless manifest_path

Rails.logger.debug { "Loading #{plugin.id} webpack asset manifest from #{manifest_path}" }
assets = JSON.parse(File.read(manifest_path))

plugin_id = plugin.id.to_s
assets['assetsByChunkName'].each do |chunk, filename|
if chunk == plugin_id || chunk.start_with?("#{plugin_id}:")
webpack_manifest['assetsByChunkName'][chunk] = filename
end
end
end

Webpack::Rails::Manifest.manifest = webpack_manifest
end
end
end
end
Loading

0 comments on commit 452403b

Please sign in to comment.