ember-partial-codemod
v1.2.0
Published
Codemod to help you migrate away from partials
Downloads
4
Readme
ember-partial-codemod
THIS IS AN EXPERIMENTAL WORK IN PROGRESS. USE AT YOUR OWN RISK. ISSUES ARE WELCOME
Given an Ember
app or addon, this codemod will transform all your partials
into components
.
Table of Contents
Installation
Yarn
yarn add ember-partial-codemod
Npm
npm install ember-partial-codemod
Usage
./node_modules/.bin/ember-partial-codemod
Example
Given a folder structure like so
base
└── addon
├── components
│ ├── parent.js
└── templates
└── components
├── parent.hbs
└── partials
├── child.hbs
└── nested-child.hbs
base/addon/templates/components/parent.hbs
Before
{{some-component attr=attr}}
{{partial "base@partials/child"}}
{{partial "base$partials/child"}}
{{partial "base::partials/child"}}
After
{{some-component attr=attr}}
{{base@partials/child bar=bar baz=baz action2=(action "action2")}}
{{base$partials/child bar=bar baz=baz action2=(action "action2")}}
{{base::partials/child bar=bar baz=baz action2=(action "action2")}}
base/addon/templates/components/partials/child.hbs
Before
{{bar}}
{{partial "base@partials/nested-child"}}
{{partial "base$partials/nested-child"}}
{{partial "base::partials/nested-child"}}
After
{{bar}}
{{base@partials/nested-child baz=baz action2=(action "action2")}}
{{base$partials/nested-child baz=baz action2=(action "action2")}}
{{base::partials/nested-child baz=baz action2=(action "action2")}}
base/addon/templates/components/partials/nested-child.hbs
Before
{{baz}}
{{fizz
action1=(action "action2")
}}
After Nothing changed!
{{baz}}
{{fizz
action1=(action "action2")
}}
Note that in our example, we have actions
!
The codemod will handle this by creating a new .js
file for the component and intelligently infer its location to write to. This way the actions are properly passed to the new component
.
So for our example, the codemod will generate the following structure.
base
└── addon
├── components
│ ├── parent.js
│ └── partials <- new folder
│ └── child.js <- new file!
│ └── nested-child.js <- new file!
└── templates
└── components
├── parent.hbs
└── partials
├── child.hbs
└── nested-child.hbs
Notice how we have two new files now, base/addon/components/partials/child.js
and base/addon/components/partials/nested-child.js
.
They are both generated because we lost the parent.js
scope, so actions will not be discovered anymore. Therefore, we faciliate the ability for actions
to be passed down correctly by generating the associated .js
files, so the actions are discoverable again.
base/addon/templates/components/partials/child.hbs
import Component from '@ember/component';
import { tryInvoke } from '@ember/utils';
export default Component.extend({
actions: {
action2() {
tryInvoke(this, 'action2');
},
}
});
base/addon/templates/components/partials/nested-child.hbs
import Component from '@ember/component';
import { tryInvoke } from '@ember/utils';
export default Component.extend({
actions: {
action2() {
tryInvoke(this, 'action2');
},
}
});
Explanation
This codemod parses the template file using the glimmerVM AST.
The codemod is broken into two major phases.
Phase 1
- By default, the codemod will crawl through all the
templates
starting with your current working directory,cwd
, gathering all the information on eachtemplate
. - If it finds a
partial
usage inside the currenttemplate
it's crawling, it will intelligently infer the physical disk path of thepartial
from themodule name
and build a dependency tree/graph, where the currenttemplate
is the parent of thepartial
. - NOTE There are cases where the codemod fails to crawl certain
templates
. One common case is when it infers correctly that apartial
's physical disk path lives outside of thecwd
. The codemod will skip thispartial
and continue.
Phase 2
- The codemod will use the information from
Phase 1
to transform thepartials
accordingly usingember-template-recast
internally.
Todo
- Make sure
get-attributes
is correct for all use cases. - Optimize Phase 1.
- Handle
actions
in a better way. - Write tests.
Contribution
Any contribution is appreciated!