3.8 KiB
Modular structure
Tokamak is built with modularity in mind, providing a multi-platform TokamakCore
module and
separate modules for platform-specific renderers. Currently, the only available renderer modules are
TokamakDOM
and TokamakStaticHTML
, the latter can be used for static websites and server-side
rendering. If you'd like to implement your own custom renderer, please refer to our renderers
guide for more details.
Tokamak users only need to import a renderer module they would like to use, while
TokamakCore
is hidden as an "internal" Tokamak
package target. Unfortunately, Swift does not
allow us to specify that certain symbols in TokamakCore
are private to a package, but they need to
stay public
for renderer modules to get access to them. Thus, the current workaround is to mark
those symbols with underscores in their names to indicate this. It can be formulated as these
"rules":
- If a symbol is restricted to a module and has no
public
access control, no need for an underscore. - If a symbol is part of a public renderer module API (e.g.
TokamakDOM
), no need for an underscore, users may use those symbols directly, and it is re-exported fromTokamakCore
by the renderer module viapublic typealias
. - If a function or a type have
public
on them only by necessity to make them available inTokamakDOM
, but unavailable to users (or not intended for public use), underscore is needed to indicate that.
The benefit of separate modules is that they allow us to provide separate renderers for different
platforms. Users can pick and choose what they want to use, e.g. purely static websites would use
only TokamakStaticHTML
, single-page apps would use TokamakDOM
, maybe in conjuction with
TokamakStaticHTML
for pre-rendering. As we'd like to try to implement a native renderer for
Android at some point, probably in a separate TokamakAndroid
module, Android apps would use
TokamakAndroid
with no need to be aware of any of the web modules.
Testing
Tokamak uses SnapshotTesting library to make sure that HTML and layout generated by renderers stay consistent. To run the test suite on macOS you should use this command:
swift build --product TokamakPackageTests && `xcrun --find xctest` .build/debug/TokamakPackageTests.xctest
Unfortunately, plain swift test
won't work as it tries to build targets that aren't related to
the test suite.
Coding Style
This project uses SwiftFormat and SwiftLint to enforce formatting and coding style. SwiftFormat 0.45.3 and SwiftLint 0.39.2 or later versions are recommended. We encourage you to run SwiftFormat and SwiftLint within a local clone of the repository in whatever way works best for you. You can do that either manually, or automatically with VSCode extensions for SwiftFormat and SwiftLint respectively, or with the Xcode extension, or build phase.
To guarantee that these tools run before you commit your changes on macOS, you're encouraged to run this once to set up the pre-commit hook:
brew bundle # installs SwiftLint, SwiftFormat and pre-commit
pre-commit install # installs pre-commit hook to run checks before you commit
Refer to the pre-commit documentation page for more details and installation instructions for other platforms.
SwiftFormat and SwiftLint also run on CI for every PR and thus a CI build can fail with inconsistent formatting or style. We require CI builds to pass for all PRs before merging.