View Source Code Transformations
During mix uniform.eject, there are 4 code transformations applied to file
contents. These transformations happen to every file except those ejected with
cp and cp_r.
They occur in this order.
- Unused mix.exs Dependencies are Removed
- Blueprint Modifiers are ran
- The Base Project Name is replaced with the ejected app's name
- Eject Fences are processed
mix-exs-dependency-removal
mix.exs Dependency Removal
Any Mix Dependency that is not directly or indirectly required by the app via
uniform.exs or the Blueprint module is removed from the ejected mix.exs.
blueprint-modifiers
Blueprint Modifiers
Users can specify arbitrary modifications that should be applied to various
files using the modify macro in the Blueprint module:
modify ~r/.+_worker.ex/, fn file, app ->
# `file` is a string containing the full file contents.
# `app` is the `Uniform.App` struct. (The app being ejected.)
# The string this function returns will be the ejected file contents.
end
modify "lib/my_app_web/router.ex", fn file ->
# This modifier is like the one above, but the transformation will only
# be ran for `lib/my_app_web/router.ex`.
end
replacing-the-base-project-name
Replacing the Base Project Name
The base project name, appearing anywhere in a file, is replaced by the ejected
app name. This applies to the following formats: base_app, base-app, and
BaseApp.
The base project name is the :app key returned by project in the mix.exs
file of the Base Project. (For example, :my_base_app below.)
# mix.exs
def project do
[
app: :my_base_app, # <- base project name
...
]
endGiven the above mix.exs, if you were to run mix uniform.eject my_ejectable_app:
my_base_appwould be replaced withmy_ejectable_appmy-base-appwould be replaced withmy-ejectable-appMyBaseAppwould be replaced withMyEjectableApp
Replacement in file paths
This same replacement of
base_project_nametoejected_app_namealso occurs in file paths, but only withthis_format. (Notthis-formatorThisFormat.)This means a file at
lib/base_project_name/foo.exwould be ejected tolib/ejected_app_name/foo.ex.
This means that a file like this
defmodule MyBaseAppWeb.Endpoint do
use Phoenix.Endpoint, otp_app: :my_base_app
socket "/socket", MyBaseAppWeb.UserSocket,
websocket: true,
longpoll: false
plug MyBaseAppWeb.Router
endWould be transformed to this
defmodule MyEjectableAppWeb.Endpoint do
use Phoenix.Endpoint, otp_app: :my_ejectable_app
socket "/socket", MyEjectableAppWeb.UserSocket,
websocket: true,
longpoll: false
plug MyEjectableAppWeb.Router
end
eject-fences
Eject Fences
In any .ex or .exs file, you can use "Eject Fence" comments to remove code
unless certain criteria are met.
To remove code unless the ejected app depends on a Lib Dependency called
my_lib, wrap it in these comments:
# uniform:lib:my_lib
# ... code
# /uniform:lib:my_libTo remove code unless the ejected app depends on a Mix Dependency called
absinthe, wrap it in these comments:
# uniform:mix:absinthe
# ... code
# /uniform:mix:absintheTo remove code unless the ejected app is called MyApp, wrap it in these
comments:
# uniform:app:my_app
# ... code
# /uniform:app:my_appFinally, to always remove a chunk of code whenever ejection happens, wrap it in these comments:
# uniform:remove
# ... code
# /uniform:removeEject Fence comments are always removed
Regardless of whether
mix uniform.ejectkeeps or deletes the code in an eject fence, the eject fence comments themselves (like# uniform:app:my_app) are always removed.Furthermore,
mix uniform.ejectrunsmix formaton the ejected codebase at the end. So you always end up with "clean" looking code.
eject-fences-for-other-languages
Eject Fences for other languages
Eject Fences are also processed for .js/.ts/.jsx/.tsx files using JS
single-line comments.
// uniform:lib:my_lib
// ...
// /uniform:lib:my_libIf you would like to support Eject Fences for other languages or file types, you
can do so using Uniform.Modifiers.eject_fences/3.
# eject fences for SQL files
modify ~r/\.sql$/, fn file, app ->
eject_fences(file, app, "--")
end
# eject fences for Rust files
modify ~r/\.rs$/, &eject_fences(&1, &2, "//")
# eject fences for CSS files
modify ~r/\.css$/, &eject_fences(&1, &2, "/\\*", "\\*/")
disabling-code-transformations
Disabling Code Transformations
If you have a file that should not have Code Transformations applied upon
ejection, use cp instead of
file.
If there is an entire directory of contents that should not be modified, use
cp_r, which will be much faster.