:vcs {:name "git"
:auto-add true}
If you have been following our tutorial, you should now have:
An example workspace
A working development environment
You will soon create your first component.
But before you do that, open workspace.edn
in your editor and set :auto-add
to true
:
:vcs {:name "git"
:auto-add true}
Before you create a component, let’s recap the three ways of executing poly
commands:
poly help
- the stand-alone version of the tool.
clojure -M:poly help
- as a Clojure dep from the workspace directory.
clojure -Tpoly help
- as a Clojure CLI Tool.
Which forms are available depends on how you installed poly
.
All the documentation refers to the first form, even though the other two are also valid.
A fourth way to execute poly
commands is through the poly
shell.
You start the poly shell via the shell command:
poly shell
clojure -M:poly shell
clojure -T:poly shell
The shell command is the default command for the first two forms but not the third:
poly
clojure -M:poly
clojure -T:poly shell
From the poly shell, it’s enough to enter the name of the command, e.g.:
In most cases, the poly shell is the most convenient way to execute commands. It gives you instant feedback, history, and autocomplete. Feel free to use the shell from now on. It will make you more productive and enhance your development experience!
Type quit to end your poly shell session.
|
Let’s continue with our example by executing the create component command:
poly create component name:user
Your workspace directory structure will now look like this:
example
├── bases
├── components
│ └── user (1)
│ ├── deps.edn
│ ├── resources
│ │ └── user
│ ├── src
│ │ └── se
│ │ └── example
│ │ └── user
│ │ └── interface.clj
│ └── test
│ └── se
│ └── example
│ └── user
│ └── interface_test.clj
├── deps.edn
├── development
│ └── src
│ └── dev
│ └── lisa.clj
├── logo.png
├── projects
├── readme.md
└── workspace.edn
1 | new user component |
You’ll notice the command also printed out this message:
Remember to add :local/root dependencies to dev and project 'deps.edn' files.
This is a reminder to add the component to your ./deps.edn
file.
If you don’t, tools.deps and the development environment will not recognize your newly created component, which would be a pity!
The poly
tool leaves this task to you as a developer.
Our philosophy is to leave the editing of files to you.
While we are happy to generate files for you, we want to give you complete control over changing your files.
Let’s listen to the helpful reminder.
Add the user
component to your ./deps.edn
:
{:aliases {:dev {:extra-paths ["development/src"]
:extra-deps {poly/user {:local/root "components/user"} (1)
org.clojure/clojure {:mvn/version "1.11.1"}}}
:test {:extra-paths ["components/user/test"]}}} (2)
1 | Add the user component as a dependency |
2 | Add the user component tests |
All dependency keys must be unique.
A good pattern is to prefix them with poly/
followed by the brick name, e.g., poly/user
as in this example.
Most IDEs now support adding components as a :local/root dependency, but if you are not using Cider, Calva, or a current version of Cursive, please review IDE Support for :local/root .
|
Cursive users: After creating a component, you may need to refresh your IDE by clicking the |
The component has its own deps.edn
file that looks like:
{:paths ["src" "resources"]
:deps {}
:aliases {:test {:extra-paths ["test"]
:extra-deps {}}}}
It specifies a src
, resources
, and test
directory.
The create component command created the user component resources
directory:
example
├── components
│ └── user
│ ├── resources
│ │ └── user
This directory contains a user
directory, which is the name of the component’s interface and is where you put your resources, e.g.:
example
├── components
│ └── user
│ ├── resources
│ │ └── user
│ │ └── myimage.png
The reason you should put myimage.png
under resources/user
and not directly under resources
is that you want to avoid name clashes.
This would happen if the same filename existed in more than one component in a project.
If you don’t need the resources
directory, you can delete it and remove it from the corresponding component deps.edn
file.
That said, you should consider keeping it around.
It offers a deliberately clash-resistant naming convention for any resources you or your team might add in the future.
Let’s continue by executing the info command:
poly info
The output tells you you have one development
project, one user
component, and one user
interface but no base (yet).
We refer to components and bases as bricks (we will soon explain what a base is).
The cryptic s--
and st-
will be described in the flags section.
If your poly output does not look as nice and colorful, see colors.
|
Now, let’s add the core
namespace to user
:
…and change it to:
(ns se.example.user.core)
(defn hello [name]
(str "Hello " name "!"))
…and update the interface
to:
(ns se.example.user.interface
(:require [se.example.user.core :as core]))
(defn hello [name]
(core/hello name))
The interface
delegates the incoming call to the implementing core
namespace, which is the most common way of structuring components in Polylith.
In this example, we had you put all your implementing code in one single namespace.
As a codebase grows, more namespaces can be added to the component as needed.
There is no rule that the implementing namespace must be named core
, but this is what the create component command generates, and we stuck with this default for this example.
:local/root
Cider, Calva, and Cursive (v1.13.0 and later) all include support :local/root
dependencies.
If your IDE doesn’t include support for :local/root
dependencies, and you are unable to switch to an IDE that has this support, then you have to add your components as :extra-paths
instead of :extra-deps
in your ./deps.edn
:
{:aliases {:dev {:extra-paths ["development/src"
"components/user/src" (1)
"components/user/resources"]} (2)
:test {:extra-paths ["components/user/test"]}}}
1 | user component src added as a path |
2 | user component resources added as a path |
If at all possible, we recommend you add components as dependencies instead of paths for these reasons:
It’s more readable.
It’s consistent with how projects are specified.
You won’t have to duplicate the bricks library dependencies in your ./deps.edn
.
You can add or remove the resources
directory from a brick without having to remember to update your ./deps.edn
.
If you want to compare the difference, take a look at how article
was elegantly added as a single dependency versus adding it as two paths in the RealWorld example app.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close