h5

Resources

The resources section of h5.json controls how static assets — JavaScript, CSS, fonts, images — are bundled, written to the output folder, embedded into the compiled assembly, and referenced from the generated index.html. It is what lets a self-contained h5 library ship its own scripts and styles so that a consuming project gets them automatically.

This page covers what the section does, every setting it accepts, how files are combined and minified versions handled, and a worked example for a typical component library.

What resources does

A resources entry describes one output artifact (a "bundle"). For each entry the compiler:

  1. Combines the listed files into a single buffer, in order.
  2. Extracts that buffer to a file in the output folder (if extract is on).
  3. Embeds it as a resource inside the compiled assembly, so referencing projects can pull it out.
  4. Injects a <script> or <link> reference into the generated index.html (if inject is on).
flowchart LR F["files[]<br/>app.js, util.js, …"] --> C["combine in order<br/>(+ optional header)"] C --> E["extract to<br/>output/&lt;output&gt;/&lt;name&gt;"] C --> M["embed into<br/>the assembly"] C --> H["inject into<br/>index.html"]
Adding a `resources` section turns off the automatic output

When there is no resources section, the compiler automatically embeds and injects the project's own generated JavaScript (the *.js / *.min.js and the *.meta.js reflection metadata).

As soon as you add a resources section, that automatic behaviour is lost: the compiler only processes the entries you list. If you still want the project's own compiled JavaScript in the output, you must add explicit entries for it (see the example below).

Resource settings

Each object in the resources array accepts the following keys. Every flag defaults to true when omitted.

Key Type Default Description
name string The output file name of the bundle (e.g. app.css). Also the key referencing projects use to find the embedded resource. Omit it to define default settings for the other entries.
files string[] Files to concatenate into the bundle, in the order listed. Supports a single glob per entry (see Globs). Paths may use MSBuild tokens such as $(OutDir).
output string output root Sub-folder (relative to the h5 output folder) the file is written to. Omit to write into the output root.
extract bool true Write the bundle out as a physical file in the output folder.
inject bool true Add a <script>/<link> reference to the generated index.html.
load bool true Whether the injected reference is actually loaded in the HTML. Set to false to embed/extract a file without loading it on the page.
header string Banner text prepended to the combined file, or a path to a file whose contents are used as the header. Supports tokens.
silent bool true Suppress warnings when a listed file is missing.
removeBom bool true* Strip the byte-order mark when combining text files. *For a single-file resource the BOM is only removed when this is explicitly true; for multi-file (combined) resources it defaults to true.
assembly string Pull the resource from a referenced assembly's embedded resources instead of from files on disk. Can also be written inline as "AssemblyName#resourceName" in name.
remark string A free-text note kept with the entry. Not emitted to the output.
`extract` vs. `inject` vs. `load`

These three flags are independent. extract controls whether a file lands on disk, inject controls whether index.html references it, and load controls whether that reference is active. If both extract and inject are false, the entry is skipped entirely.

Default settings

A resources entry without a name is treated as a block of default settings that is applied to every other entry. Use it to avoid repeating a common output folder or flag across many bundles. Only one default entry is allowed.

{
  "resources": [
    {
      "output": "assets",   // applied to every named entry below
      "header": "/* (c) {year} Acme Corp */"
    },
    { "name": "app.css",  "files": [ "css/app.css" ] },
    { "name": "app.js",   "files": [ "$(OutDir)h5/app.js" ] }
  ]
}

Header tokens

When a header is set, the following tokens are substituted from the project's assembly metadata before the header is written:

Token Source
{version} Assembly version
{author} Assembly company name
{copyright} Assembly copyright
{date} Build date (yyyy-MM-dd)
{year} Build year
{ "name": "app.js", "files": [ "$(OutDir)h5/app.js" ],
  "header": "/*! Acme UI {version} — (c) {year} {author} */" }

If the header value resolves to an existing file path, that file's contents are used as the header instead of the literal string.

Globs

A single entry can use a glob to pull in a whole folder. The part before the * is the base directory; the part after is matched against file names, recursively through sub-folders. Sub-folder structure is preserved under output.

{ "name": "fonts", "files": [ "h5/assets/fonts/*" ], "output": "assets/fonts/" }

Constraints:

  • A single entry cannot mix globs and plain file paths — use separate entries.
  • Extensionless files are rejected (except CNAME); give every matched file an extension.
  • Editor/OS junk (.DS_Store, desktop.ini, thumbs.db) is skipped automatically.

Pulling resources from a referenced assembly

An entry with no files is an extract entry: it pulls an embedded resource out of a referenced assembly and writes it into the consuming project's output. Identify the source with assembly, or with the AssemblyName#resourceName shorthand in name:

{
  "resources": [
    { "name": "AcmeUI#acme.css", "output": "assets/css" }
  ]
}

Minified vs. non-minified bundles

As described in Build Configurations, a project built with outputFormatting: "Both" produces both readable and minified output, and a consuming project picks the .min.js resources in Release and the non-.min.js resources in Debug.

Because the compiler keys this selection on the .min.js suffix in the resource name, a library that defines a resources section has to list its scripts twice — once as name.js and once as name.min.js — so that both configurations have something to load. The files for the two entries can point at the already-minified and non-minified versions respectively, or simply share the same file list when a separate minified build isn't maintained.

CSS and fonts have no minified/non-minified distinction, so they need only a single entry each.

Example: a component library

The following h5.json is for an imaginary component library, Acme UI, that compiles to acme.js and ships a handful of third-party scripts, its own stylesheets, and a fonts folder. It is representative of how a real component library wires up its resources section.

h5.json
{
  // Build both readable and minified output so a referencing project can choose
  // which to consume based on its own Debug/Release build (see Build Configurations).
  "outputFormatting": "Both",

  "resources": [
    // 1. The library's own compiled JavaScript. Because a resources section is
    //    present, the automatic injection is off — so we re-add it by hand, both
    //    the non-minified and minified versions, plus the reflection metadata.
    { "name": "acme.js",          "files": [ "$(OutDir)h5/acme.js" ] },
    { "name": "acme.meta.js",     "files": [ "$(OutDir)h5/acme.meta.js" ] },
    { "name": "acme.min.js",      "files": [ "$(OutDir)h5/acme.min.js" ] },
    { "name": "acme.meta.min.js", "files": [ "$(OutDir)h5/acme.meta.min.js" ] },

    // 2. Third-party dependencies, bundled into one file. The same list is
    //    declared twice (.js and .min.js) so both build configurations resolve.
    {
      "name": "acme-deps.js",
      "files": [
        "h5/assets/js/popper.min.js",
        "h5/assets/js/tippy.min.js",
        "h5/assets/js/sortable.min.js"
      ],
      "output": "assets/js"
    },
    {
      "name": "acme-deps.min.js",
      "files": [
        "h5/assets/js/popper.min.js",
        "h5/assets/js/tippy.min.js",
        "h5/assets/js/sortable.min.js"
      ],
      "output": "assets/js"
    },

    // 3. Stylesheets combined into one file. CSS has no min/non-min split, so a
    //    single entry is enough.
    {
      "name": "acme.css",
      "files": [
        "h5/assets/css/acme.common.css",
        "h5/assets/css/acme.button.css",
        "h5/assets/css/acme.card.css"
      ],
      "output": "assets/css"
    },

    // 4. A fonts folder, pulled in with a glob and kept under assets/fonts.
    { "name": "fonts", "files": [ "h5/assets/fonts/*" ], "output": "assets/fonts/" }
  ]
}

Points worth noting from the example:

  • Entries 1 re-add the project's own output that the automatic behaviour would otherwise have provided, including the .meta.js reflection metadata.
  • The dependency bundle in 2 is listed once as .js and once as .min.js so that both Debug and Release builds of a consuming project find a matching resource.
  • Combining the CSS in 3 isn't technically required, but it keeps the generated index.html tidy and groups related styles into one request.
  • The fonts glob in 4 preserves any sub-folder structure under assets/fonts/.

See also

© 2026 h5. All rights reserved.