moderne v1.1.8
moderne
moderne
is a lean application platform server. This is the development tool
for it.
Moderne allows to self-host apps easily, keeping them behind an Nginx proxy and providing 0-downtime deploy infrastructure to help an average web developer to release new versions without hurdles.
📑 ››› READ PLATFORM DOCS ›››
It is meant to be the simplest Docker alternative that adheres to the Unix-way, and also supports:
- user-based app isolation;
- telegram notifications;
- easy static files configuration and SPAs;
- unix domain sockets;
- and is in active development!
This package is a client installed on developers' machines to help them integrate their workflows with Moderne infrastructure.
npm i moderne -D
yarn add moderne --dev
Table Of Contents
Bin
This package provides a Node binary. At the moment, it supports the emulation of a static file server which will be configured by Nginx when the static app is uploaded to and installed by Moderne.
moderne serve -a front [-p 5001] [-l]
-a, --app Application name as in moderne.json file
-p, --port The port on which to run, default 5000
-l, --log Log requests
-h, --help Show usage
It assumes the presence of the moderne.json
file in the project directory,
with a structure similar to this (the actual app must be configured in
apps.json
on the server running Moderne platform):
{
"back": {
"node": "src/server.mjs",
"ignore": ["assets"],
"nginx": "web_app"
},
"front": {
"install": "node",
"html-env": ["www/index.html"],
"nginx": "static",
"env": {
"HOST": "https://british.technology",
"$HOST": "http://localhost:3000",
"MAIN_CSS_P": "/assets/main.css",
"$MAIN_CSS_P": "/styles/main.css",
"MAIN_CSS_V": "b0d3cfbcc8",
"$MAIN_CSS_V": ""
},
"locations":{
"/assets/": {
"alias": "assets",
"immutable": "1M"
},
"/": {
"404": "index.html",
"root": "www",
"index": "index.html",
"precompress": true,
"etag": true
}
}
}
}
http://localhost:5000/styles/main.css
→ served fromwww/styles/main.css
(DEV)https://british.technology/assets/main.css
→ served fromassets/main.css
(PROD)
To start the emulator, run
yarn moderne serve -a front -p 5001
where front
is the app name and 5001
is the port (the default is 5000
).
After that, assets (immutable images) and work files like HTML and CSS will be
available for loading in the browser.
When the app is deployed, Moderne will form and activate an Nginx config similar to this:
server {
# ssl, domain config
location /assets/ {
alias /opt/apps/moderne/default/assets/;
etag off;
}
location / {
root /opt/apps/moderne/default/www/;
index index.html;
gzip_static on;
gzip_proxied any;
}
}
This package helps to match the functionalities between development and production.
HTML Env Expansion
html-env
field specifies the files that will be updated to have environment
variables populated in them. This is useful because in development and on the
server those can be different:
for example, on a local machine, we might want to use native CSS imports, but before releasing a production version, we need to compile all CSS modules into a single file to speed up load time.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Moderne</title>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css"
href="{MAIN_CSS_P}?{MAIN_CSS_V}">
<script>
var API='{HOST}/api'
</script>
</head>
<body>
<div class="Header">
<img src="/assets/moderne-logo.png"
style="width:250px; max-width:100%;" alt="moderne">
<div style="text-align: center; width:100%">
Welcome to <em>Moderne</em>.
</div>
</div>
</body>
</html>
@import url("./header.css");
html {
display: flex;
min-height: 100%;
align-items: center;
}
body {
width:100%;
background-color: rgb(248, 208, 208);
color: darkblue;
}
.Header {
background-color: darkblue;
color: rgb(248, 208, 208);
border-radius: 1rem;
padding: 1rem;
font-size:2rem;
display: flex;
align-items: center;
margin: 1rem 5rem;
box-shadow: 0 3px 7px 1px #ae434366;
}
When these values are given in the env
field of moderne.json
:
{
"env": {
"HOST": "https://british.technology",
"$HOST": "http://localhost:3000",
"MAIN_CSS_P": "/assets/main.css",
"$MAIN_CSS_P": "/styles/main.css",
"MAIN_CSS_V": "b0d3cfbcc8",
"$MAIN_CSS_V": ""
}
}
the following HTML will be returned:
<head>
<title>Moderne</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- localhost, ETag caching to re-load file on changes: -->
<link rel="stylesheet" type="text/css" href="/styles/main.css?">
<!-- production, long term Last-Modified caching against version: -->
<link rel="stylesheet" type="text/css" href="/assets/main.css?b0d3cfbcc8">
<script>
// localhost (set by this emulator):
var API='http://localhost:3000/api'
// production (set by Moderne automatically on upload):
var API='https://british.technology/api'
</script>
</head>
$MAIN_CSS_P
is substituted locally and MAIN_CSS_P
on the server - allowing
to provide long-term caching for production bundles instead of ETag caching
which is less efficient. Before the release, you'll need your CSS bundler to
update moderne.json
, like so:
var exposure=new ExposureStylesheets({
port:3333,
})
try {
await exposure.start()
var{stylesheet}=await exposure.compileFiles([main,...imports],{
allowUnrecognizedProperties:true,
})
stylesheet=stylesheet.replace(/@import url\(['"].+?['"]\);/g,'')
var hash=createHash('md5').update(stylesheet).digest('hex').slice(0,10)
var f=await readFile('moderne.json','utf8')
f=f.replace(/"MAIN_CSS_V": ".+?"/,`"MAIN_CSS_V": "${hash}"`)
await writeFile('moderne.json',f)
await writeFile('assets/main.css',stylesheet)
}finally {
exposure.stop()
}
Exposure Stylesheets is a private CSS compiler. How to implement CSS
compilation and bundling is up to you but you need to place the output in the
/assets
folder have the script update moderne.json
to include the latest
hash as shown above.