ArcMoon 1.1.0

Start

Language

Reference

Nothing matches “”.

↑↓ move Enter open Esc close

Reference

Configuration

Every arcmoon.config.js key and every JavaScript API option: defaults, examples, when to use them.

Two ways to set options

  • The CLI (arcm build) reads arcmoon.config.js from the folder you run it in.
  • The JavaScript API (new ArcMoon(options)) takes the same names in its options object, plus a few of its own. It doesn't read the config file.

Every option is optional: leave one out, and its default is used.

arcmoon.config.js

arcm init creates the config in the current folder. Every option, with its default:

arcmoon.config.js
export default {
  importAliases: { "@": "./src" },   // short names for folders in [import] paths
  removeComments: true,              // leave # comments out of the HTML
  timeout: 5000,                     // ms each page's ${ }$ code may run
  bundle: [],                        // npm packages allowed in runtime code
  packages: {},                      // runtime imports loaded from a URL: { dayjs: "https://…" }
  outDir: "./dist",                  // where arcm build writes
  externalScripts: false,            // true: JavaScript in files, not inside the HTML
  externalStyles: false,             // true: CSS in files, not inside the HTML
  assetsDir: "assets",               // folder inside outDir for JS, CSS and url() files
  base: undefined                    // e.g. "/": file URLs from the site root
};

ArcMoon reads it only from the folder you run arcm in, never from a parent folder. Run arcm from your project folder. arcm show config prints what it found.

The options

Every option is optional: leave one out, and its default is used.

importAliases

Short names for folders, used at the start of [import] paths. Default: none.

arcmoon.config.js
export default {
  importAliases: { "@": "./src", "~ui": "./src/components" }
};
# in any file, however deep
[import = Card: "@/components/Card.arcm" !]   # → ./src/components/Card.arcm
[import = Badge: "~ui/Badge.arcm" !]          # → ./src/components/Badge.arcm

Targets start from the project folder. Without the alias, a page in pages/blog/ would need ../../src/components/Card.arcm. More in Import aliases.

removeComments

Whether # and ### comments are left out of the HTML. Default: true.

arcmoon.config.js
export default { removeComments: false };
# Page header
[h1]Home[end]
HTML with removeComments: false
<!-- Page header-->
<h1>Home</h1>

With the default, the HTML is just <h1>Home</h1>. Keep comments when they should ship with the page, like a license note. More in Comments.

timeout

How many milliseconds each page's ${ }$ code may run, its components included. Default: 5000 (5 seconds).

arcmoon.config.js
export default { timeout: 10000 };   // 10 seconds, for pages that fetch a slow API

Code that takes longer is stopped: endless loops, timers and pending requests all end, and the build stops with:

✗ ${ }$ code took longer than 10000 ms and was stopped
  pages/stats.arcm

Raise it only if a page really needs the time. A page that hangs usually has a bug, and the timeout is what stops it.

bundle

The npm packages runtime code may import. Default: none. Runtime code goes to every visitor, so ArcMoon only bundles packages you list:

arcmoon.config.js
export default { bundle: ["canvas-confetti", "dayjs"] };
runtime ${ import confetti from "canvas-confetti"; }$
[button = onclick: runtime ${ () => confetti() }$]Party[end]

Install the package first (npm install canvas-confetti). Without the entry, the build stops:

✗ runtime import "canvas-confetti" is not listed in bundle (arcmoon.config.js). Add it to bundle to bundle it from node_modules, or to packages to load it from a URL

Not needed for arcmoon/reactive, your own .js files, URL imports, packages used only in ${ }$ (they never reach the browser), or CSS @imports.

packages

npm names that runtime code loads from a URL instead of bundling them (ArcMoon 1.1). Nothing is installed or downloaded at build time; the visitor's browser loads the URL:

arcmoon.config.js
export default {
  packages: { dayjs: "https://esm.sh/dayjs@1" }
};
  • import dayjs from "dayjs" loads https://esm.sh/dayjs@1; "dayjs/plugin/utc" loads that URL + /plugin/utc.
  • A key can also be a full path, like "lit/html.js". Values must start with https://.
  • It is the same option the browser build takes.

outDir

The folder arcm build writes into. Default: "./dist".

arcmoon.config.js
export default { outDir: "./public" };
arcm build pages/about.arcm
✓ pages/about.arcm → public/about.html  14 B

-o on the command line wins over it: arcm build pages/blog -o public/blog.

externalScripts

Where each page's JavaScript goes. Default: false, inside the HTML in a <script>.

arcmoon.config.js
export default { externalScripts: true };
dist/
index.html              <script type="module" src="./assets/index-MTLSBKEV.js">
assets/
  index-MTLSBKEV.js     this page's code
  chunks/
    chunk-E7XXX4QS.js   code shared by pages, like arcmoon/reactive
  • Inside (default): one file per page, nothing else to copy. Good for small sites and single pages.
  • In files: shared code is downloaded once and cached across pages. Good for sites with many pages.

externalStyles

Where each page's CSS goes. Default: false, inside the HTML in a <style>.

arcmoon.config.js
export default { externalStyles: true };
dist/
index.html              <link rel="stylesheet" href="./assets/index-IH2BDP4O.css">
assets/
  index-IH2BDP4O.css    all of this page's CSS

It is separate from externalScripts: you can have the JavaScript in files and the CSS inside the page, or the other way round.

assetsDir

The folder inside outDir for JavaScript and CSS files, and for url() files copied from CSS. Default: "assets".

arcmoon.config.js
export default { externalScripts: true, assetsDir: "static" };
dist/
index.html              <script type="module" src="./static/index-QZCVOMHP.js">
static/
  index-QZCVOMHP.js

base

How pages link to those files. Default: relative to each page (./assets/…). Set it to the URL where outDir is served:

arcmoon.config.js
export default { externalScripts: true, base: "/" };
<!-- default -->
<script type="module" src="./assets/index-MTLSBKEV.js"></script>
<!-- base: "/" -->
<script type="module" src="/assets/index-MTLSBKEV.js"></script>
  • Use it when pages are served from paths that don't match their files, for example by a server that rewrites URLs.
  • Subfolders built with -o get their own assets/ (dist/blog/assets/). When the -o folder is inside outDir, base gets that folder: -o dist/blog with base: "/" links to /blog/assets/… (ArcMoon 1.1).

Options only in the JavaScript API

These go in new ArcMoon({ … }) next to the options above. See the JavaScript API for compile() and build().

filename and src

The page to build: a file, or the page as a string. Give one of them.

new ArcMoon({ filename: "pages/index.arcm" });
new ArcMoon({ src: "[p]Hello ${ 2 + 3 }$[end]" });

With both, src is the code and filename is its name in messages and the folder its imports start from. With src alone, the page is called anonymous.arcm, in cwd.

props

Data for the page, read with ArcMoon.props() like a component's props. Default: none.

const html = await new ArcMoon({
  filename: "pages/user.arcm",
  props: { name: "Maryan" }
}).compile();
pages/user.arcm
${ const { name } = ArcMoon.props(); }$
[h1]Hello, ${ name }$[end]

Props are copied in as real values (objects, arrays, dates), never turned into text. Use them for one template and many pages, or a server that builds a page per request.

cwd

The project folder: where relative paths start. Default: process.cwd(), the folder Node.js runs in.

  • A relative filename, and importAliases targets, start here.
  • A [script = src: "/app.js"] that starts with / is read from here.
  • Packages in bundle are found in its node_modules.
new ArcMoon({ filename: "pages/index.arcm", cwd: "/home/adam/my-site" });

root

The folder whose files count as yours for the protector. Files outside it are templates, which must be trusted before their code runs. Default: cwd.

// a build script in tools/, for the project one folder up
new ArcMoon({ filename: "pages/index.arcm", cwd: "..", root: ".." });

dev

true: the page's JavaScript isn't minified and has a source map back to the .arcm lines, so browser errors show real names and lines. Default: false. The CLI's arcm build --dev sets it.

# with dev: true, a browser error points at the .arcm file
TypeError: Cannot read properties of undefined (reading 'value')  pages/index.arcm:5:22

onWarning

What to do with each warning. It gets { source, position, message }: the file, { line, character } counted from 0 (or null), and the text. Default: print one line, ⚠ page.arcm:3:7 ….

// fail a CI build on any warning
const warnings = [];
await new ArcMoon({ filename: "pages/index.arcm", onWarning: (w) => warnings.push(w) }).compile();
if (warnings.length) process.exitCode = 1;

Read the three fields; don't parse the text, which can change in any release.

name

The page's name in build() and buildPages(): its entry in pages, and the start of its file names (post-MTLSBKEV.js). Default: the file name without .arcm, or page for src.

const pages = posts.map((post) => ({
  filename: "templates/Post.arcm",
  name: post.slug,   // its name in pages[], and the start of its file names
  props: { post }
}));

Options of build() and buildPages()

These say where files go and how pages link to them. They match the config keys of the same name, with one difference: externalScripts is true by default here, so JavaScript goes into files. The CLI and compile() put it inside the page.

// one page
const { html, files } = await new ArcMoon({ filename: "pages/index.arcm" }).build({
  outDir: "dist",
  base: "/"
});

// many pages: page options first, then options for all of them
const { pages } = await buildPages(
  [{ filename: "pages/a.arcm" }, { filename: "pages/b.arcm" }],
  { outDir: "dist", bundle: ["dayjs"] }
);

siteDir

buildPages() only (ArcMoon 1.1). The site's main output folder, when outDir is a folder inside it: base then gets that folder. Default: outDir. The CLI passes your config's outDir, so -o builds link right.

await buildPages(posts, { outDir: "dist/blog", siteDir: "dist", base: "/" });
// pages link to /blog/assets/…

In the browser

The browser build has options of its own (files, baseUrl, packages, env…): see Browser build.