Resources
The resources section of tps.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 Transpose
library ship its own scripts and styles so that a consuming project gets them
automatically.
This page covers what the section does, every key it accepts, how files are combined, and a worked example for a component library.
What resources does
A resources entry describes one group. For each group the compiler:
- Resolves the listed
files(expanding a glob if there is one). - Writes the result into the output folder, under the group's
outputsub-folder. - Embeds it as a resource inside the compiled assembly, so a referencing project can extract it.
- Links it from the generated
index.html— a<script>for JavaScript, a<link rel="stylesheet">for CSS — unless the group opts out withload.
Bundle groups vs. copy-through groups
The group's name decides which of two shapes it takes:
- Bundle group —
nameends in.jsor.css. Every file the group lists is concatenated, in order, into a single output file calledname. - Copy-through group — any other
name(including nonameat all). Each listed file is copied under its own file name. Use this for fonts, images, and other assets that must stay as separate files.
{
"resources": [
// Bundle: three stylesheets concatenated into one assets/css/app.css.
{ "name": "app.css",
"files": [ "assets/css/base.css", "assets/css/layout.css", "assets/css/theme.css" ],
"output": "assets/css" },
// Copy-through: each font file copied under its own name into assets/fonts/.
{ "name": "fonts", "files": [ "assets/fonts/*" ], "output": "assets/fonts" }
]
}
Resource keys
Each object in the resources array accepts these keys, and only these:
| Key | Type | Default | Description |
|---|---|---|---|
name |
string | — | The output file name of a bundle group (e.g. app.css), or a label for a copy-through group. Also the key a referencing project uses to find the embedded resource. Supports the module#file.js and file.js.dontload forms below. |
files |
string[] | — | The files the group is built from, in order. Paths are relative to the project directory. Supports one glob per entry — see Globs. |
output |
string | output root | Sub-folder of the Transpose output folder the file is written to. Omit to write into the output root. |
load |
bool | true |
Whether the resource is referenced from the generated index.html. false still writes and embeds the file, but leaves loading it to the application. |
Two spellings of "don't load"
"load": false on the group and the legacy .dontload suffix on its name
("name": "lazy-module.js.dontload") mean the same thing, and either one alone
suppresses the link. The suffix is dropped from the output file name. The flag is
recorded in the resource manifest embedded in a package DLL, so a project
referencing the library extracts the file without auto-loading it either.
A name may also carry a module# grouping prefix ("name": "acme#acme.css");
everything before the # is a label, and the output file name is the part after
it.
Keys that Transpose does not read
If you are porting an h5.json resources section, these keys are no longer
recognised and are ignored:
extract, inject, header (and its {version} / {author} / {copyright}
/ {date} / {year} tokens), silent, removeBom, assembly, remark.
There is also no default-settings entry: in h5, an entry without a name
supplied defaults for every other entry. In Transpose a name-less entry is just a
copy-through group. Repeat the output and load values on each group instead.
Globs
A group can pull in a whole folder with a glob. The wildcard goes in the file name part of the pattern; the directory part must be a literal path.
{ "name": "fonts", "files": [ "assets/fonts/*" ], "output": "assets/fonts" }
Constraints:
- Matching is not recursive — only files directly in the named directory are picked up. Add one group per sub-folder if you need more.
- The wildcard must be in the file name;
assets/*/icons/*.svgdoes not work. - A directory that does not exist contributes nothing, silently.
- MSBuild tokens are not expanded in
filespaths.$(OutDir)is substituted only in the top-leveloutputsetting.
The project's own compiled JavaScript
Transpose always embeds the project's own bundle and its reflection metadata,
in both a formatted and a pre-minified variant. Adding a resources section does
not turn that off.
This differs from h5
In h5, adding any resources section suppressed the automatic output, so a
library had to re-declare its own .js, .min.js, .meta.js and
.meta.min.js by hand. Transpose embeds them for you, and only suppresses the
default embed of the specific bundle a group re-declares. A library no longer
needs the four boilerplate entries, and no longer needs to list its scripts twice
to satisfy both build configurations — the pre-minified variant is always
shipped, so a consuming project extracts the .min.js in Release and the plain
.js in Debug without minifying library code itself.
The one reason to re-declare your own bundle is to change its load flag — for
example to ship a module the application fetches on demand:
{
"resources": [
{ "name": "app.js.dontload", "files": [ "app.js" ] }
]
}
A file in files whose leaf name matches one of the project's own outputs
(app.js, app.min.js, app.meta.js, app.meta.min.js) resolves to the
in-memory bundle rather than to a file on disk, so this works even though nothing
has been written yet when the group is processed.
Minified vs. non-minified
Resource JavaScript is taken as authored and never re-minified by Transpose.
That has one consequence worth knowing: a resource named *.min.js is linked
only from index.min.html, and a plain *.js resource only from index.html.
So a third-party script you want available in both configurations needs an entry
under each name.
CSS resources are linked from both pages, so a stylesheet needs only one entry.
Which page becomes the final index.html depends on the build configuration —
see Build Configurations.
Example: a component library
The following tps.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.
{
"fileName": "acme.js",
"output": "$(OutDir)tps/",
// Build both readable and minified output so a referencing project can pick
// one based on its own Debug/Release build (see Build Configurations).
"outputFormatting": "Both",
// A library has no page of its own.
"html": { "disabled": true },
"resources": [
// 1. Third-party dependencies, concatenated into one file. Declared twice —
// once as .js, once as .min.js — because resource JS is linked by name and
// is never re-minified, so each build configuration needs its own entry.
{
"name": "acme-deps.js",
"files": [ "assets/js/popper.min.js", "assets/js/tippy.min.js", "assets/js/sortable.min.js" ],
"output": "assets/js"
},
{
"name": "acme-deps.min.js",
"files": [ "assets/js/popper.min.js", "assets/js/tippy.min.js", "assets/js/sortable.min.js" ],
"output": "assets/js"
},
// 2. Stylesheets concatenated into one file. CSS is linked from both pages,
// so a single entry is enough.
{
"name": "acme.css",
"files": [ "assets/css/acme.common.css", "assets/css/acme.button.css", "assets/css/acme.card.css" ],
"output": "assets/css"
},
// 3. A theme the application swaps in at runtime: copied and embedded, but
// never linked from the page.
{
"name": "acme-dark.css",
"files": [ "assets/css/acme.dark.css" ],
"output": "assets/css",
"load": false
},
// 4. A fonts folder, pulled in with a glob as a copy-through group.
{ "name": "fonts", "files": [ "assets/fonts/*" ], "output": "assets/fonts" }
]
}
Points worth noting:
- The library's own
acme.js/acme.min.js/acme.meta.js/acme.meta.min.jsare not listed — Transpose embeds all four automatically. - The dependency bundle in 1 is the case that does still need two entries,
because a
.min.jsname is only linked fromindex.min.html. - Combining the CSS in 2 isn't required, but it keeps the generated
index.htmltidy and groups related styles into one request. - Entry 3 shows
load: false: the file lands in the output of every consuming project, but nothing loads it until the application does. - The fonts glob in 4 matches only files directly under
assets/fonts/.
See also
- Global Configuration — the rest of
the
tps.jsonoptions. - Build Configurations —
tps.Debug.json/tps.Release.jsonand how the build configuration drives minified vs. non-minified output.