Migrate from Webpacker to Vite
Done
- Basic Setup as described here: https://vite-ruby.netlify.app/guide/migration.html#webpacker-%F0%9F%93%A6
- Rewrote most of the imports automatically using the fix-imports.rb script below (coded by Claude 3.5 Sonnet with one initial instruction and one follow-up bugfix)
- Fixed the rest of the imports manually
- removed Webpacker
- upgraded Node from 16 to 20
- upgraded minor Versions for most Node packages
- removed some iyarc-ignores
- switched from Vite-Ruby to Vite-Rails plugin
- removed ancient postcss.config.js
Todos / Questions
-
remove --ignore-optional
from yarn install in Dockerfile because rollup native extensions are declared optional and we need (one platforms-pecific of) them -
Richtext-Editor is currently not working: Warnings/Errors about calling Constructors without new are in the Browser Console -
verify production build uses production of Vue (check if NODE_ENV is set by ViteRails-Plugin, if not maybe use DefinePlugin? -- no warnings can be seen in deployed instance -
are Faketimers (previously in config/webpack/development.js) still needed? if so: re-add them -- done via "test" entrypoint which is conditionally loaded from app template -
are @babel/core and core-js still needed? yarn complains about unmet dependencies -- lots of babel dependencies re-added (as dev-dependencies) based on error messages in bin/fix-code-style
Optional Todos
-
remove Vite example application.js in entrypoints (also implicitly done when moving application.js in next todo item) -
move from packs to entrypoints (and remove config key entrypointsDir
in config/vite.json) -
@babel/core and core-js still needed? yarn complains about unmet dependencies -- lots of babel dependencies re-added (as dev-dependencies) based on error messages in bin/fix-code-style
-> Try different (more modern) linter?? -
convert manual image imports (e.g. in show-content-footer.vue) to custom asset attribute resolving? -
verify that all leftovers of Webpack(er) are removed -
see if any others of vitejs/plugin-vue2's options should be used -
switch from manual imports to automatically importing everything? -- NOT doing that during initial conversion -
convert project from deprecated CJS to ESM? -- NOT doing that during initial conversion
(unchecked optional ToDos moved to #1239 (closed))
fix-imports.rb
require "fileutils"
def process_file(file_path, js_root)
content = File.read(file_path)
modified = false
# Match ESM style imports
content.gsub!(/import\s+(?:{[^}]+}|\*\s+as\s+\w+|\w+)\s+from\s+['"]([^'"]+)['"]/i) do |match|
import_path = Regexp.last_match(1)
# Check if the import is relative (starts with './' or '../') or relative to JS root
full_path = if import_path.start_with?("./", "../")
File.expand_path(import_path, File.dirname(file_path))
else
File.join(js_root, import_path)
end
if File.directory?(full_path)
# Check for index files in directory
if File.exist?("#{full_path}/index.vue")
modified = true
match.sub(import_path, "#{import_path}/index.vue")
elsif !File.exist?("#{full_path}/index.js")
puts "Warning: No index file found for directory import: #{import_path}"
match
else
match
end
elsif !File.exist?("#{full_path}.js") && File.exist?("#{full_path}.vue")
modified = true
match.sub(import_path, "#{import_path}.vue")
else
match
end
end
if modified
File.write(file_path, content)
puts "Updated: #{file_path}"
end
end
def process_directory(dir_path, js_root)
Dir.glob(File.join(dir_path, "**", "*.{js,vue}")).each do |file|
process_file(file, js_root)
end
end
# Main execution
if ARGV.empty?
puts "Usage: ruby script.rb <path_to_app/javascript>"
exit 1
end
js_root = ARGV[0]
unless Dir.exist?(js_root)
puts "Error: The specified directory does not exist."
exit 1
end
process_directory(js_root, js_root)
puts "Processing complete."
Edited by Michael Prilop