Skip to content

Commit

Permalink
webpack 5
Browse files Browse the repository at this point in the history
  • Loading branch information
MariaAga committed Sep 14, 2023
1 parent b9986c9 commit 01eca52
Show file tree
Hide file tree
Showing 21 changed files with 658 additions and 356 deletions.
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
34 changes: 34 additions & 0 deletions app/assets/javascripts/late_load.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
function load_dynamic_javascripts(html) {
function waitForAllLoaded() {
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() {
var template = document.createElement('template');
template.innerHTML = html;
var doc = new DOMParser().parseFromString(html, "text/html");
var copyChildren = [...doc.head.children];
for(var i = 0; i < copyChildren.length; i++) {
if(copyChildren[i].src){
await import(copyChildren[i].src);
}
else{
await eval(copyChildren[i].innerHTML)
}
}
const loadJS = new Event('loadJS');
document.dispatchEvent(loadJS);
});
}
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.9', '`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.9', '`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
65 changes: 33 additions & 32 deletions app/helpers/reactjs_helper.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
require 'webpack-rails'
module ReactjsHelper
# Mount react component in views
# Params:
Expand All @@ -11,58 +10,60 @@ 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
def js_tags_for(requested_plugins)
requested_plugins.map do |plugin|
javascript_tag("window.tfm.tools.loadPluginModule('/webpack/#{plugin.to_s.tr('-', '_')}','#{plugin.to_s.tr('-', '_')}','./index');".html_safe)
end
end

def webpacked_plugins_js_for(*plugin_names)
js_tags_for(select_requested_plugins(plugin_names)).join.html_safe
end

def webpacked_plugins_with_global_js
global_js_tags(global_plugins_list).join.html_safe
def other_webpack_plugin(plugin_name, file)
javascript_tag("window.tfm.tools.loadPluginModule('/webpack/#{plugin_name.to_s.tr('-', '_')}','#{plugin_name.to_s.tr('-', '_')}','./#{file}_index');".html_safe)
end

def webpacked_plugins_css_for(*plugin_names)
css_tags_for(select_requested_plugins(plugin_names)).join.html_safe
def global_js_tags(requested_plugins)
requested_plugins.map do |plugin|
plugin[:files].map do |file|
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 select_requested_plugins(plugin_names)
available_plugins = Foreman::Plugin.with_webpack.map(&:id)
missing_plugins = plugin_names - available_plugins
if missing_plugins.any?
logger.error { "Failed to include webpack assets for plugins: #{missing_plugins}" }
raise ::Foreman::Exception.new("Failed to include webpack assets for plugins: #{missing_plugins}") if Rails.env.development?
end
plugin_names & available_plugins
def webpacked_plugins_with_global_js
global_js_tags(global_plugins_list).join.html_safe
end

def js_tags_for(requested_plugins)
requested_plugins.map do |plugin|
javascript_include_tag(*webpack_asset_paths(plugin.to_s, :extension => 'js'))
end
def webpacked_plugins_css_for(*plugin_names)
Foreman::Deprecation.deprecation_warning('3.9', '`webpacked_plugins_css_for` is deprecated, plugin css is already loaded.')
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
def get_webpack_foreman_vendor_js
if ENV['RAILS_ENV'] == 'production'
javascript_include_tag("/webpack/#{File.basename(Dir.glob('public/webpack/foreman-vendor*production*js')[0])}")
else
javascript_include_tag("/webpack/#{File.basename(Dir.glob('public/webpack/foreman-vendor*development*js')[0])}")
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'))
end
def get_webpack_foreman_vendor_css
if ENV['RAILS_ENV'] == 'production'
stylesheet_link_tag("/webpack/#{File.basename(Dir.glob('public/webpack/foreman-vendor*production*css')[0])}")
else
stylesheet_link_tag("/webpack/#{File.basename(Dir.glob('public/webpack/foreman-vendor*development*css')[0])}")
end
end

def css_tags_for(requested_plugins)
requested_plugins.map do |plugin|
stylesheet_link_tag(*webpack_asset_paths(plugin.to_s, :extension => 'css'))
def select_requested_plugins(plugin_names)
available_plugins = Foreman::Plugin.with_webpack.map(&:id)
missing_plugins = plugin_names - available_plugins
if missing_plugins.any?
logger.error { "Failed to include webpack assets for plugins: #{missing_plugins}" }
raise ::Foreman::Exception.new("Failed to include webpack assets for plugins: #{missing_plugins}") if Rails.env.development?
end
plugin_names & available_plugins
end

def locale_js_tags
Expand Down
24 changes: 12 additions & 12 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 %>' id='body-test'>
<%= get_webpack_foreman_vendor_js %>
<%= javascript_include_tag('/webpack/vendor.js') %>
<%= javascript_include_tag('/webpack/bundle.js') %>
<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') %>
<%= 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 All @@ -62,7 +62,7 @@
class="pf-c-page"
>

<%= yield(:content) %>
<%= yield(:content) %>
</div>
<% else %>
<%= yield(:content) %>
Expand Down
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
32 changes: 1 addition & 31 deletions config/initializers/assets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class << self
# Precompile additional assets
config.assets.precompile += FastGettext.default_available_locales.map { |loc| "locale/#{loc}/app.js" }

# Adds plugin assets to the application digests hash if a manifest file exists for a plugin
# Adds plugin assets to the application digests hash if a manifest file exists for a plugin
config.after_initialize do
if (manifest_file = Dir.glob("#{Rails.root}/public/assets/.sprockets-manifest*.json").first)
foreman_manifest = JSON.parse(File.read(manifest_file))
Expand Down 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 01eca52

Please sign in to comment.