Merge pull request #13828 from rioug/10298-upgrade-to-shakapaker

Upgrade to shakapaker
This commit is contained in:
Gaetan Craig-Riou
2026-01-21 16:17:50 +11:00
committed by GitHub
31 changed files with 3462 additions and 6219 deletions

View File

@@ -1,2 +0,0 @@
defaults
IE 11

View File

@@ -18,7 +18,7 @@ gem 'activemerchant'
gem 'angular-rails-templates'
gem 'ransack', '~> 4.1.0'
gem 'responders'
gem 'webpacker', '~> 5'
gem 'shakapacker', '6.6.0'
# Indirect dependency but we access it directly in JS specs.
# It turns out to be hard to upgrade but please do if you can.
@@ -126,6 +126,8 @@ gem 'angular_rails_csrf'
gem 'jquery-rails', '4.4.0'
gem 'jquery-ui-rails', '~> 4.2'
# TODO move away from sass-rails, master branch will get rid of dependency, so we can move to
# https://github.com/sass/embedded-host-node
gem "select2-rails", github: "openfoodfoundation/select2-rails", branch: "v349_with_thor_v1"
gem 'good_migrations'

View File

@@ -615,7 +615,7 @@ GEM
rack-protection (3.2.0)
base64 (>= 0.1.0)
rack (~> 2.2, >= 2.2.4)
rack-proxy (0.7.6)
rack-proxy (0.7.7)
rack
rack-rewrite (1.5.1)
rack-session (1.0.2)
@@ -814,7 +814,12 @@ GEM
tilt (>= 1.1, < 3)
sd_notify (0.1.1)
securerandom (0.4.1)
semantic_range (3.0.0)
semantic_range (3.1.0)
shakapacker (6.6.0)
activesupport (>= 5.2)
rack-proxy (>= 0.6.1)
railties (>= 5.2)
semantic_range (>= 2.3.0)
shoulda-matchers (7.0.1)
activesupport (>= 7.1)
sidekiq (7.2.4)
@@ -942,11 +947,6 @@ GEM
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webpacker (5.4.4)
activesupport (>= 5.2)
rack-proxy (>= 0.6.1)
railties (>= 5.2)
semantic_range (>= 2.3.0)
webrick (1.9.2)
websocket-driver (0.7.7)
base64
@@ -1083,6 +1083,7 @@ DEPENDENCIES
rubocop-rspec_rails
sd_notify
select2-rails!
shakapacker (= 6.6.0)
shoulda-matchers
sidekiq
sidekiq-scheduler
@@ -1108,7 +1109,6 @@ DEPENDENCIES
web!
web-console
webmock
webpacker (~> 5)
whenever
wicked_pdf
wkhtmltopdf-binary

View File

@@ -1,5 +1,5 @@
# Foreman Procfile. Start all dev server processes with: `foreman start`
rails: DEV_CACHING=true bundle exec rails s -p 3000
webpack: ./bin/webpack-dev-server
webpack: ./bin/webpacker-dev-server
sidekiq: DEV_CACHING=true bundle exec sidekiq -q mailers -q default

View File

@@ -1,5 +1,5 @@
# Foreman Procfile for Docker env. Start all dev server processes with: `bundle exec foreman start -f Procfile.docker`
webpack: WEBPACKER_DEV_SERVER_HOST=0.0.0.0 ./bin/webpack-dev-server
webpack: WEBPACKER_DEV_SERVER_HOST=0.0.0.0 ./bin/webpacker-dev-server
sidekiq: DEV_CACHING=true bundle exec sidekiq -q mailers -q default
rails: WEBPACKER_DEV_SERVER_HOST=0.0.0.0 DEV_CACHING=true bundle exec rails s -p 3000 -b 0.0.0.0

View File

@@ -1,4 +1,4 @@
= render ConfirmModalComponent.new(id: dom_id(@order, :ship), confirm_reflexes: "click->Admin::OrdersReflex#ship", controller: "orders", reflex: "Admin::Orders#ship") do
= render ConfirmModalComponent.new(id: dom_id(@order, :ship), confirm_actions: "click->modal#close", confirm_reflexes: "click->Admin::OrdersReflex#ship", controller: "orders", reflex: "Admin::Orders#ship") do
%div{class: "margin-bottom-30"}
%p= t('spree.admin.orders.shipment.mark_as_shipped_message_html')
%div{class: "margin-bottom-30"}

View File

@@ -72,7 +72,8 @@ module ApplicationHelper
end
end
# Update "v1" to invalidate existing cache key
def cache_key_with_locale(key, locale)
Array.wrap(key) + [locale.to_s, I18nDigests.for_locale(locale)]
Array.wrap(key) + ["v1", locale.to_s, I18nDigests.for_locale(locale)]
end
end

View File

@@ -13,12 +13,12 @@
- else
= favicon_link_tag "/favicon-staging.ico"
%link{href: "https://fonts.googleapis.com/css?family=Roboto:400,300italic,400italic,300,700,700italic|Oswald:300,400,700", rel: "stylesheet", type: "text/css"}
%link{href: asset_pack_path("media/fonts/OFN-v2.woff"), rel: "preload", as: "font", crossorigin: "anonymous"}
%link{href: asset_pack_path("static/OFN-v2.woff"), rel: "preload", as: "font", crossorigin: "anonymous"}
= render "layouts/matomo_tag"
= language_meta_tags
= stylesheet_pack_tag "darkswarm", "data-turbo-track": "reload", media: "screen"
= javascript_pack_tag "application", "data-turbo-track": "reload"
= javascript_pack_tag "application", "data-turbo-track": "reload", defer: false # do not use defer because our javascript currently depend on order of execution of loaded script.
= render "layouts/shopfront_script" if @shopfront_layout
= render "layouts/bugsnag_js"

View File

@@ -16,7 +16,7 @@
= stylesheet_pack_tag "darkswarm", media: "screen"
= javascript_include_tag "darkswarm/all"
= javascript_pack_tag "application"
= javascript_pack_tag "application", defer: false # do not use defer because our javascript currently depend on order of execution of loaded script.
= csrf_meta_tags

View File

@@ -25,7 +25,7 @@
= render "spree/admin/shared/translations"
= render "spree/admin/shared/routes"
= javascript_pack_tag "admin", "data-turbo-track": "reload"
= javascript_pack_tag "admin", "data-turbo-track": "reload", defer: false # do not use defer because our javascript currently depend on order of execution of loaded script.
%script
= raw "var AUTH_TOKEN = \"#{form_authenticity_token}\";"

View File

@@ -2,19 +2,19 @@
// While in feature-toggle, we inherit all files from old admin design.
// Individual files may be copied in order to replace the old files.
@import "vendor/assets/stylesheets/normalize";
@import "vendor/assets/stylesheets/responsive-tables";
@import "vendor/assets/stylesheets/jquery.powertip";
@import "~jquery-ui/themes/base/core";
@import "~jquery-ui/themes/base/button";
@import "~jquery-ui/themes/base/resizable";
@import "vendor/assets/stylesheets/jquery-ui-theme";
@import "~jquery-ui/themes/base/dialog";
@import "assets/stylesheets/normalize";
@import "assets/stylesheets/responsive-tables";
@import "assets/stylesheets/jquery.powertip";
@import "jquery-ui/themes/base/core";
@import "jquery-ui/themes/base/button";
@import "jquery-ui/themes/base/resizable";
@import "assets/stylesheets/jquery-ui-theme";
@import "jquery-ui/themes/base/dialog";
@import "../shared/ng-tags-input.min";
@import "vendor/assets/stylesheets/select2.css.scss";
@import "~flatpickr/dist/flatpickr";
@import "~flatpickr/dist/themes/material_blue";
@import "~shortcut-buttons-flatpickr/dist/themes/light";
@import "assets/stylesheets/select2";
@import "flatpickr/dist/flatpickr";
@import "flatpickr/dist/themes/material_blue";
@import "shortcut-buttons-flatpickr/dist/themes/light";
@import "../admin/globals/functions";
@import "globals/palette"; // admin_v3
@@ -123,13 +123,13 @@
@import "shared/question-mark-icon";
@import "../admin/question-mark-tooltip";
@import "~tom-select/src/scss/tom-select.default";
@import "tom-select/src/scss/tom-select.default";
@import "components/tom_select"; // admin_v3
@import "app/components/modal_component/modal_component";
@import "app/components/vertical_ellipsis_menu_component/vertical_ellipsis_menu_component"; // admin_v3 and only V3
@import "app/components/tag_list_input_component/tag_list_input_component";
@import "app/webpacker/css/admin/trix.scss";
@import "modal_component/modal_component";
@import "vertical_ellipsis_menu_component/vertical_ellipsis_menu_component"; // admin_v3 and only V3
@import "tag_list_input_component/tag_list_input_component";
@import "admin/trix";
@import "terms_of_service_banner"; // admin_v3

View File

@@ -1,10 +1,10 @@
@import 'vendor/assets/stylesheets/autocomplete';
@import 'vendor/assets/stylesheets/leaflet';
@import 'assets/stylesheets/autocomplete';
@import 'assets/stylesheets/leaflet';
@import 'variables';
@import '../shared/variables/layout';
@import '../shared/utilities';
@import '~foundation-sites/scss/foundation';
@import 'foundation-sites/scss/foundation';
@import 'big-input';
@import 'branding';
@@ -77,4 +77,4 @@ ofn-modal {
@import "../shared/question-mark-icon";
@import '../admin/shared/scroll_bar';
@import 'app/components/modal_component/modal_component';
@import 'modal_component/modal_component';

View File

@@ -1,4 +1,4 @@
@import "~foundation-sites/scss/foundation/components/global";
@import "foundation-sites/scss/foundation/components/global";
// Brand guide colours:
// International: #81c26e

View File

@@ -1,72 +1,6 @@
module.exports = function(api) {
var validEnv = ['development', 'test', 'production']
var currentEnv = api.env()
var isDevelopmentEnv = api.env('development')
var isProductionEnv = api.env('production')
var isTestEnv = api.env('test')
module.exports = function (api) {
const defaultConfigFunc = require("shakapacker/package/babel/preset.js");
const resultConfig = defaultConfigFunc(api);
if (!validEnv.includes(currentEnv)) {
throw new Error(
'Please specify a valid `NODE_ENV` or ' +
'`BABEL_ENV` environment variables. Valid values are "development", ' +
'"test", and "production". Instead, received: ' +
JSON.stringify(currentEnv) +
'.'
)
}
return {
presets: [
isTestEnv && [
'@babel/preset-env',
{
targets: {
node: 'current'
}
}
],
(isProductionEnv || isDevelopmentEnv) && [
'@babel/preset-env',
{
forceAllTransforms: true,
useBuiltIns: 'entry',
corejs: 3,
modules: false,
exclude: ['transform-typeof-symbol']
}
]
].filter(Boolean),
plugins: [
'babel-plugin-macros',
'@babel/plugin-syntax-dynamic-import',
isTestEnv && 'babel-plugin-dynamic-import-node',
'@babel/plugin-transform-destructuring',
[
'@babel/plugin-proposal-class-properties',
{
loose: true
}
],
[
'@babel/plugin-proposal-object-rest-spread',
{
useBuiltIns: true
}
],
[
'@babel/plugin-transform-runtime',
{
helpers: false
}
],
[
'@babel/plugin-transform-regenerator',
{
async: false
}
],
["@babel/plugin-proposal-private-property-in-object", { "loose": true }],
["@babel/plugin-proposal-private-methods", { "loose": true }]
].filter(Boolean)
}
}
return resultConfig;
};

View File

@@ -1,18 +1,13 @@
#!/usr/bin/env ruby
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
ENV["NODE_ENV"] ||= "development"
ENV["NODE_OPTIONS"] ||= "--openssl-legacy-provider"
require "pathname"
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
Pathname.new(__FILE__).realpath)
require "bundler/setup"
require "webpacker"
require "webpacker/webpack_runner"
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", Pathname.new(__FILE__).realpath)
APP_ROOT = File.expand_path("..", __dir__)
Dir.chdir(APP_ROOT) do
Webpacker::WebpackRunner.run(ARGV)

View File

@@ -1,8 +1,6 @@
#!/usr/bin/env ruby
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
ENV["NODE_ENV"] ||= "development"
ENV["NODE_OPTIONS"] ||= "--openssl-legacy-provider"
require "pathname"
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",

View File

@@ -1,9 +1,16 @@
#!/usr/bin/env ruby
APP_ROOT = File.expand_path('..', __dir__)
APP_ROOT = File.expand_path("..", __dir__)
Dir.chdir(APP_ROOT) do
begin
exec "yarnpkg", *ARGV
rescue Errno::ENOENT
yarn = ENV["PATH"].split(File::PATH_SEPARATOR).
select { |dir| File.expand_path(dir) != __dir__ }.
product(["yarn", "yarnpkg", "yarn.cmd", "yarn.ps1"]).
map { |dir, file| File.expand_path(file, dir) }.
find { |file| File.executable?(file) }
if yarn
exec yarn, *ARGV
else
$stderr.puts "Yarn executable was not detected in the system."
$stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
exit 1

View File

@@ -89,7 +89,7 @@ services:
build: .
command: >
sh -lc 'until [ -f /bundles/.Gemfile.lock.sha ] && sha256sum -c /bundles/.Gemfile.lock.sha >/dev/null 2>&1; do sleep 0.5; done;
exec ./bin/webpack-dev-server'
exec ./bin/webpacker-dev-server'
ports:
- "3035:3035"
volumes:

View File

@@ -1,10 +0,0 @@
module WebpackImageExtension
def image_pack_path(image)
# The Webpacker::Helper#resolve_path_to_image method is incredibly useful
# for nicely fetching Webpacker image paths, but it's private.
resolve_path_to_image(image)
end
end
Webpacker::Helper.include WebpackImageExtension

View File

@@ -1,5 +0,0 @@
process.env.NODE_ENV = process.env.NODE_ENV || 'development'
const environment = require('./environment')
module.exports = environment.toWebpackConfig()

View File

@@ -1,35 +0,0 @@
const { environment } = require('@rails/webpacker')
module.exports = environment
function hotfixPostcssLoaderConfig (subloader) {
const subloaderName = subloader.loader
if (subloaderName === 'postcss-loader') {
if (subloader.options.postcssOptions) {
console.log(
'\x1b[31m%s\x1b[0m',
'Remove postcssOptions workaround in config/webpack/environment.js'
)
} else {
subloader.options.postcssOptions = subloader.options.config;
delete subloader.options.config;
}
}
}
function addQuietDepsToSassLoader (subloader) {
if (subloader.loader === 'sass-loader') {
subloader.options.sassOptions = {
...subloader.options.sassOptions,
quietDeps: true
}
}
}
environment.loaders.keys().forEach(loaderName => {
const loader = environment.loaders.get(loaderName);
if (loaderName === 'sass') {
loader.use.forEach(addQuietDepsToSassLoader);
}
loader.use.forEach(hotfixPostcssLoaderConfig);
});

View File

@@ -1,5 +0,0 @@
process.env.NODE_ENV = process.env.NODE_ENV || 'production'
const environment = require('./environment')
module.exports = environment.toWebpackConfig()

View File

@@ -1,5 +0,0 @@
process.env.NODE_ENV = process.env.NODE_ENV || 'development'
const environment = require('./environment')
module.exports = environment.toWebpackConfig()

View File

@@ -0,0 +1,20 @@
const { webpackConfig, merge } = require("shakapacker")
const options = {
resolve: {
extensions: [".mjs", ".js", ".sass",".scss", ".css", ".module.sass", ".module.scss", ".module.css", ".png", ".svg", ".gif", ".jpeg", ".jpg", ".eot", ".ttf", ".woff"]
}
}
const OFNwebpackConfig = merge(webpackConfig, options)
// quiet deprecations in dependencies, notably foundation-sites
const scssRule = OFNwebpackConfig.module.rules.find((rule) => rule.test.test(".scss"))
const sassDefaultOptions = scssRule.use[3].options.sassOptions
scssRule.use[3].options.sassOptions = {
...sassDefaultOptions,
quietDeps: true
}
// This results in a new object copied from the mutable global
module.exports = OFNwebpackConfig

View File

@@ -8,7 +8,7 @@ default: &default
cache_path: tmp/cache/webpacker
webpack_compile_output: true
# Additional paths webpack should lookup modules
# Additional paths webpack should look up modules
# ['app/assets', 'engine/foo/app/assets']
additional_paths: [
'vendor',
@@ -25,37 +25,6 @@ default: &default
# Extract and emit a css file
extract_css: true
static_assets_extensions:
- .jpg
- .jpeg
- .png
- .gif
- .tiff
- .ico
- .svg
- .eot
- .otf
- .ttf
- .woff
- .woff2
extensions:
- .mjs
- .js
- .sass
- .scss
- .css
- .module.sass
- .module.scss
- .module.css
- .png
- .svg
- .gif
- .jpeg
- .jpg
- .eot
- .ttf
- .woff
development:
<<: *default
@@ -66,22 +35,40 @@ development:
https: false
host: localhost
port: 3035
public: localhost:3035
# Hot Module Replacement updates modules while the application is running without a full reload
hmr: false
# Inline should be set to true if using HMR
inline: true
overlay: true
# Defaults to the inverse of hmr. Uncomment to manually set this.
# live_reload: true
client:
# Should we show a full-screen overlay in the browser when there are compiler errors or warnings?
overlay: false
# May also be a string
# webSocketURL:
# hostname: "0.0.0.0"
# pathname: "/ws"
# port: 8080
# Should we use gzip compression?
compress: true
disable_host_check: true
use_local_ip: false
quiet: false
pretty: false
# Note that apps that do not check the host are vulnerable to DNS rebinding attacks
allowed_hosts: "all"
#TODO Old config
#pretty: false
pretty: true
headers:
'Access-Control-Allow-Origin': '*'
watch_options:
ignored:
- '**/node_modules/**'
- '**/*.swp'
static:
watch:
ignored:
- '**/node_modules/**'
- '**/*.swp'
test:
<<: *default
compile: true
compiler_strategy: mtime
# Compile test packs to a separate directory
public_output_path: packs-test
production: &production
<<: *default
@@ -91,9 +78,3 @@ production: &production
# Cache manifest.json for performance
cache_manifest: true
test:
<<: *default
# Compile test packs to a separate directory
public_output_path: packs-test

View File

@@ -179,7 +179,7 @@ module.exports = {
// transform: { "\\.[jt]sx?$": "babel-jest" },
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
transformIgnorePatterns: ["/node_modules/(?!(stimulus.+)/)"],
transformIgnorePatterns: ["/node_modules/(?!stimulus)/"],
// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
// unmockedModulePathPatterns: undefined,

View File

@@ -7,12 +7,21 @@
},
"license": "AGPL-3.0",
"dependencies": {
"@babel/core": "^7.28.5",
"@babel/plugin-transform-runtime": "^7.28.5",
"@babel/preset-env": "^7.28.5",
"@babel/runtime": "^7.28.4",
"@floating-ui/dom": "*",
"@hotwired/stimulus": "*",
"@hotwired/turbo": "*",
"@rails/webpacker": "5.4.4",
"@stimulus-components/rails-nested-form": "*",
"babel-loader": "^8.2.2",
"cable_ready": "5.0.6",
"coffee-loader": "^5.0.0",
"coffeescript": "^2.7.0",
"compression-webpack-plugin": "^9.0.0",
"css-loader": "^7.1.2",
"css-minimizer-webpack-plugin": "^7.0.4",
"flatpickr": "*",
"foundation-sites": "5.5.3",
"hotkeys-js": "*",
@@ -21,19 +30,40 @@
"leaflet": "1.9.4",
"leaflet-geosearch": "4.2.2",
"leaflet-providers": "3.0.0",
"mini-css-extract-plugin": "^2.9.4",
"moment": "*",
"mrujs": "*",
"pnp-webpack-plugin": "^1.7.0",
"postcss": "^8.5.6",
"postcss-flexbugs-fixes": "^5.0.2",
"postcss-import": "^16.1.1",
"postcss-loader": "^8.2.0",
"postcss-preset-env": "^10.5.0",
"regenerator-transform": "^0.15.2",
"sass-embedded": "^1.96.0",
"sass-loader": "^16.0.6",
"select2": "*",
"shakapacker": "6.6.0",
"shortcut-buttons-flatpickr": "*",
"stimulus": "*",
"stimulus-autocomplete": "*",
"stimulus-flatpickr": "*",
"stimulus_reflex": "3.5.5",
"style-loader": "^4.0.0",
"terser-webpack-plugin": "^5.3.16",
"tom-select": "*",
"trix": "*",
"turbo_power": "*",
"webpack": "~4"
"webpack": "^5.104.0",
"webpack-assets-manifest": "^5.0.6",
"webpack-cli": "^4.9.2",
"webpack-merge": "^5.8.0",
"webpack-sources": "^3.3.3"
},
"browserslist": [
"defaults",
"not IE 11"
],
"devDependencies": {
"@testing-library/dom": "<11.0.0",
"jasmine-core": "~5.12.1",
@@ -44,6 +74,6 @@
"karma-coffee-preprocessor": "~1.0.1",
"karma-jasmine": "~0.3.8",
"prettier": "*",
"webpack-dev-server": "~3"
"webpack-dev-server": "^4.9.0"
}
}

View File

@@ -89,13 +89,13 @@ RSpec.describe ApplicationHelper do
it "appends locale and digest to a single key" do
expect(
helper.cache_key_with_locale("single-key", "en")
).to eq(["single-key", "en", en_digest])
).to eq(["single-key", "v1", "en", en_digest])
end
it "appends locale and digest to multiple keys" do
expect(
helper.cache_key_with_locale(["array", "of", "keys"], "es")
).to eq(["array", "of", "keys", "es", es_digest])
).to eq(["array", "of", "keys", "v1", "es", es_digest])
end
end
end

View File

@@ -555,7 +555,7 @@ RSpec.describe '
find_button("Confirm").click
end
expect(page).to have_selector('.reveal-modal', visible: false)
expect(page).not_to have_content("This will mark the order as Shipped.")
expect(page).to have_content "SHIPPED"
click_link('Order Details') unless subpage == 'Order Details'
@@ -578,7 +578,7 @@ RSpec.describe '
find_button("Confirm").click
end
expect(page).to have_selector('.reveal-modal', visible: false)
expect(page).not_to have_content("This will mark the order as Shipped.")
click_link('Order Details') unless subpage == 'Order Details'
expect(page).to have_content "SHIPPED"

9285
yarn.lock

File diff suppressed because it is too large Load Diff