You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is an evolving draft of the steps needed to migrate your project and components from Komponent to ViewComponent. Please add your notes and comments below.
Goals
List the steps and gotchas when migrating. This is preliminary work to hopefully provide tools to ease the transition.
Preparation
In my case, I use frontend/ as my root folder, and I want to use ViewComponent's sidecar assets.
move app/components/example/example.css to app/components/example_component/example_component.css
now open side-by-side app/components/example/example_component.rb and app/components/example_component.rb
if you have property with required: true, nothing to do: the params are required by default. For instance property :foo, required: true becomes def initialize(foo:)
if you have property with default values, move these values to the initialize keyword arguments. For instance property :foo, default: "bar" becomes def initialize(foo: "bar")
take all the ExampleComponent module methods and move them to the ExampleComponent class
if your component uses view helpers, prefix them with helpers. (ie. current_user becomes helpers.current_user)
in frontend/components/index.js, remove:
- import "./example/example";
Now take a deep breath, because it will get tedious.
find all the occurrences of c "example" or c("example" or component "example" or component("example" in your project. You can use this regex if your editor allows you to search by regex: /c(omponent)?[ (]{1}"example"/
replace them with the ViewComponent syntax to render components: render(ExampleComponent.new(foo: "bar"))
move app/components/example/example_controller.js to app/components/example_component/example_controller.js
in app/components/example_component/example_component.js, remove :
-import application from "stimulus_application";
import { definitionsFromContext } from "stimulus/webpack-helpers";
+import application from "../../javascript/stimulus_application";
import "./example_component.css";
const context = require.context("./", true, /_controller\.js$/);
application.load(definitionsFromContext(context));
This trick (calling one application.load for each component) prevents you from having the -- in the controller name when placing the file in a sidecar directory, as described here.
Tools
Here is a first try at automating the last part (replacing all occurrences of rendering a given component);
Warning: this is a work in progress, not ready for use. Help needed!
namespace :komponent do
namespace :migrate do
desc "Migrate component renders to view_component syntax"
task :render, [:component_name] => :environment do |_t, args|
component_name = args.component_name
puts "Migrating component #{component_name}"
# This regexp only finds the beginning of the component rendering call.
# It does not handle the parameters, so you will have a missing `))` at the end.
# FIXME: how can we improve this?
search_regexp = /c(omponent)?[ (]{1}"#{Regexp.quote(component_name)}",?\s+/
component_klass = component_name.classify
replacement = "render(#{component_klass}Component.new("
# FIXME: Replace `slim` with your templating language of choice here.
file_names = Dir.glob(Rails.root.join("**/*.slim"))
file_names.each do |file_name|
text = File.read(file_name)
new_contents = text.gsub(search_regexp, replacement)
File.open(file_name, "w") {|file| file.puts new_contents }
end
end
end
end
That's all for now. I will update this issue when I find edge cases.
The text was updated successfully, but these errors were encountered:
This is an evolving draft of the steps needed to migrate your project and components from Komponent to ViewComponent. Please add your notes and comments below.
Goals
List the steps and gotchas when migrating. This is preliminary work to hopefully provide tools to ease the transition.
Preparation
In my case, I use
frontend/
as my root folder, and I want to use ViewComponent's sidecar assets.frontend/
) :frontend/components/
toapp/components/
frontend/
toapp/javascript/
config/application.rb
, replace:config/webpacker.yml
, replace:(I also had to add
extract_css: true
, not sure why yet)app/javascript/packs/application.js
, replace:app/components/index.js
, replace the import path for each component:If you have namespaced components, find their
index.js
and replace the import paths as well.app/components/index.js
, add this in order to get sidecar assets:Migrating a component
Let's say you have a component named
example
._example.html.slim
andexample_component.rb
)bin/rails generate component Example title content
(replacetitle
andcontent
with the params you listed)app/components/example/_example.html.slim
toapp/components/example_component/example_component.html.slim
app/components/example/example.js
toapp/components/example_component/example_component.js
app/components/example_component/example_component.js
, replace:app/components/example/example.css
toapp/components/example_component/example_component.css
app/components/example/example_component.rb
andapp/components/example_component.rb
property
withrequired: true
, nothing to do: the params are required by default. For instanceproperty :foo, required: true
becomesdef initialize(foo:)
property
withdefault
values, move these values to theinitialize
keyword arguments. For instanceproperty :foo, default: "bar"
becomesdef initialize(foo: "bar")
ExampleComponent
module methods and move them to theExampleComponent
classhelpers.
(ie.current_user
becomeshelpers.current_user
)frontend/components/index.js
, remove:- import "./example/example";
Now take a deep breath, because it will get tedious.
c "example"
orc("example"
orcomponent "example"
orcomponent("example"
in your project. You can use this regex if your editor allows you to search by regex:/c(omponent)?[ (]{1}"example"/
render(ExampleComponent.new(foo: "bar"))
If your component has a Stimulus controller
app/javascript/stimulus_application.js
:app/components/example/example_controller.js
toapp/components/example_component/example_controller.js
app/components/example_component/example_component.js
, remove :This trick (calling one
application.load
for each component) prevents you from having the--
in the controller name when placing the file in a sidecar directory, as described here.Tools
Here is a first try at automating the last part (replacing all occurrences of rendering a given component);
Warning: this is a work in progress, not ready for use. Help needed!
That's all for now. I will update this issue when I find edge cases.
The text was updated successfully, but these errors were encountered: