🔥 🐷 🔥
Incrementally build statically-linked pages and servers with tup.
What is it? Why?
This is an opinionated build system that has made all the decisions for you.
It works with simple commands. It is incremental and runs only tasks when needed. Eligible tasks are run in parallel. It also prevents stale files from leaking into your deployment directory. You do not need to specify your project dependencies for this to work, but in exchange you need to follow the provided project layout.
It uses tup to accomplish this.
At around 64KB~128KB compressed, you may want to start thinking about a new page.
.imu source installed into your project is a good idea. You are
encouraged to fork, modify and otherwise twist the contents to your needs.
Neither tup nor
imu-build are required to build an imu project. Your
end-users may always execute
npm build in the project root to get a
By default, it generates tup build logic to provide the incrementing, parallel build and deployment system.
Although it was designed to work with tup, its use is optional. If it is not found, the entire project is built as a single synchronous thread. This is both slower, not incremental and may also result in stale artifacts in the deployment directory, but this will allow anyone to build a project with no additional dependencies beyond node.js.
This guide will assume you will have installed
imu-build in order to use the
imu command from anywhere in the project tree. However, from the project
root you may always use
npm run to execute the very same commands.
There is no default command for
npm run by itself, however
npm run build will execute a release build.
You will also need to run the
new command as
npm run new -- -p example
-- in order to pass arguments.
init command is only available with
|imu init||Installs the build scripts and npm dependencies.|
|imu new [options]||Create new projects and templates.|
|imu client-debug||Builds the client in debug mode.|
|imu client-release||Builds the client in release mode.|
$ npm install --global imu-build $ mkdir (Project) $ cd (Project) $ imu init $ imu new --page (PageName) $ imu
This will build an empty page to confirm the toolchain is working. You may edit
the code in
client/pages/(PageName) to further experiment.
After making changes, executing
imu inside the project directory will rebuild
only the necessary files. For speed, this is an unoptimized build. Running
imu client-release will compile an optimized, ready-to-deploy build.
When you are ready to start a new component for your page:
imu new --page (PageName) --component (ComponentName)
You may provide the flags in either order, and in shortened form:
imu new -p (PageName) -c (ComponentName)
At some point, you will want to start again with a fresh page:
imu new -p (NewPageName)
Names should not contain spaces and should be valid as an HTML ID tag. These
commands generate a new set of files to edit inside
|license.html||License comment tag; prepended to the page.|
|root.html||Entry point into the page's actual DOM code.|
|root.css||Entry point into the page style.|
|root.js||Entry point into the page code.|
Each page is given a
components/ directory to hold Stage0 component
Most editing will be done on
root.js and its child
you need to embed resources into the actual DOM, such as inlining SVGs and
templates, you would edit
JS, CSS and HTML import directives will all search for paths relative to
the importing file. In addition, it will also search the subdirectories of
client/pages. The use of file extensions is optional except
to resolve conflicts.
The compiled page files are placed in
|client/pages||Code for each application page.|
|client/share||Code shared between each application page.|
|client/style||Style code and Tailwind configuration.|
|client/svg||SVG icons available for inlining.|
|client/util||Third-party libraries used by application pages.|
|deploy/client||The destination of compiled pages.|
|deploy/static||All static files and content, available via /static|
|tmp||Temporary files created during the build process.|
client/style directory contains the
tailwind.config.js file and
is a good place for stylesheets you wish to
@import into pages. For example,
a site may consist of many pages all importing the same set of Tailwind
components. As each page has its own CSS file, you may safely place unique
classes and overrides into it without affecting the styling of other pages.
style/base.css file is the project-wide style reset. It is mostly the
same as TailwindCSS's reset, using sections of Normalize.css,
SUIT CSS and TailwindCSS-specific rules. It has had a few
additional rules added, including part of Eric Meyer's reset.
If you need to use third-party ES6 modules that are not available via
Static files should be placed in
deploy/static. A built-in
generator will place one inside
deploy/static if one is not present when
imu new -p. This is a 43 byte 1x1 transparent GIF image, as small
as it can be made.
A suggested directory is
client/share, to be used for components that are
shared and imported across pages. For example, a '404 Not Found' component
may be the same across all of your pages. You will need to create the
client/share directory, should you choose to use it.
Other potential paths could include things such as
client/api for holding modules for S.js store and API request related
client/router.js could hold your application's router
configuration. These paths require no specific support from imu.
CSS is processed with PostCSS, with CSS Import and PostCSS Preset Env, which provides a number of current CSS spec features. PostCSS Preset Env also runs a pass with Autoprefixer, saving you from writing vendor-specific prefixes. For release builds, all unused CSS classes are automatically purged from the resulting code using PurgeCSS. CSSO is used as a final pass to minimize the code.
On release builds, the final HTML is run through HTMLMinifier prior to compression with gzip.
imu provides a set of directives available for use within files being
built. For HTML it is:
@import directive must be enclosed in a comment tag. The path provided
should be relative to the current file path. This will copy the contents of the
file into its place place.
@script directive has also been included, which behaves the same as
@import but will wrap the results in
<script type="x/templates"> tags. An
ID based upon the filename is included in these tags. As such, filenames must
consist only of valid ID characters and should not contain spaces.
<div> <!-- @import "./local/project/file.html" //--> </div>
@svg directive has also been provided. It is used just like
SVG files imported will first be parsed and processed to add an ID based upon
the filename, sans extension. The same restrictions on naming that apply to
@script also apply here.
fill attribute is set to 'inherit' and any
width attribute is removed prior to inlining.
* `imu server` builds the server project natively & SQL schema. * `imu server-linux` builds the server project specifically for Linux. * `imu sql` builds the SQL schema.
Copying configuration files, including nginx is done by:
* `imu copy-conf` Copies all server-related configuration into 'deploy/'.
new has the following additional commands:
* `imu new --server ServerName` starts a new server codebase. * `imu new --table Name` starts a new SQL table file. * `imu new --patch` starts a new SQL migration patch file.
An equivalent of
@import has been added for MySQL and is used much the same.
# @import "./local/table/name"
Should any issues with build artifacts arise, you may always try
This will remove all build artifacts from the project. As your project expands,
you may wish to update the list of files
reset will remove in
Dual-Licensed. Pick one. Pick both. Pick carefully.
imu is available as Jollo LNT or CC0 | Public Domain, as you desire. Either way, you may make full use of the included files for any reason, without attribution should you wish to leave no trace.
As imu aggressively strips code, including the original copyright comments,
the relevant copyright notices are added as a document comment to all pages
built for release. Be sure to keep
license.html up to date as you change