Cartero
Modular front end development for multi-page web applications.
Install / Use
/learn @rotundasoftware/CarteroREADME
DEPRECIATION NOTICE: At long last, cartero has been depreciated. As the first multi-page application build tool, cartero served its purpose well for many years. However now there are far more robust and better supported tools that can be used to achieve the same goals. We recommend migrating any projects still using cartero to Web Pack. Thank you to everyone who contributed to this pioneering project.
cartero
cartero is an asset pipeline built on npm and browserify that allows you to easily organize front end code in multi-page web applications into reusable packages containing HTML, JavaScript, css, and images.
Overview
cartero eliminates much of the friction involved in the build process when applying modular design principles to front end assets in multi-page web applications. Use directories to group together assets (js, css, images, etc.) for each UI component, and cartero will take care of ensuring that all the appropriate assets are then loaded on the pages that require them, and just those pages. Depending on a package is as simple as require( 'pork-and-beans' ). And since cartero is built on npm, the official node.js package manager, you can easily publish your packages and / or depend on other npm packages in your own code.
A package might contain assets for
- A calendar widget
- A popup dialog
- A header or footer
- An entire web page
cartero is a build tool. It does not introduce many new concepts, and the same modular organizational structure it facilitates could also be achieved by stringing together other build tools and the appropriate <script>, <link>, and <img> tags. However, using cartero is, well, a lot easier.
See this article for more info on how cartero compares to other tools, and this tutorial to get started.
Command line usage
Build all assets for a multi-page application with the cartero command. For example,
$ cartero "./views/**/index.js" "./static/assets"
This command will gather up the js and other assets required by each JavaScript entry point matching the first argument (in this case, all index.js files in the views directory), and drop the compiled assets into the output directory specified in the second argument, along with information used at run time by the hook, to load the appropriate assets for each entry point.
cartero only processes each asset one time, so compiling assets for many entry points at once is extremely efficient. Each additional entry point adds practically no overhead. cartero also separates out any JavaScript assets that are used by all your entry points into a common bundle, so that the browser cache can be leveraged to load any shared logic quickly on each page. (This magic is done by factor-bundle - thanks for your wizardry, James!)
Adding a -w flag to the cartero command will run cartero in watch mode so that the output is updated whenever assets are changed. Again, cartero's watch mode is extremely efficient, only rebuilding what is necessary for a given change.
The hook
At run time, your application needs to be able to easily figure out where assets are located. For this reason, cartero provides a small (< 100 LOC) runtime library that your server side logic can use to look up asset urls or paths based on a simple map output by cartero at build time. At the time of this writing, only a hook for node.js is available, but one can quickly be written for any server side environment.
For example, if views/page1/index.js is an entry point, the following call will return all the script and link tags needed to load the js and css bundles it requires:
h.getTagsForEntryPoint( 'views/page1/index.js', function( err, scriptTags, styleTags ) {
// scriptTags and styleTags and strings of <script> and <link> tags, respectively.
// attach the tags to the express res.locals so we can
// output them in our template to load the page's assets
res.locals.script = scriptTags;
res.locals.style = styleTags;
} );
You can also ask the cartero hook to lookup the url of a specific asset. For example, to find the url of carnes.png in that same page1 directory.
var imageUrl = h.getAssetUrl( 'views/page1/carnes.png' );
It's all in the package.json
cartero can gather and compile style and image assets from any module with a package.json file. Just include a style and / or image property in the package.json that enumerates the assets the package requires of that type (in glob notation). For example,
{
"name" : "my-module",
"version" : "1.0.2",
"main" : "lib/my-module.js",
"dependencies" : { ... },
"style" : "*.scss", // styles
"image" : [ "icon.png" ] // images
}
Note that package.json files can be in any location. You can even put package.json files in your views folder. Sound weird? Try it. The JavaScript entry point that is used by any given view is, after all, just like a package -- it has its own js, css, and may depend on other packages (or even be depended upon). Relax your brain - does the below directory structure make sense?
├── node_modules
│ └── my-module
│ ├── index.js
│ ├── icon.png
│ ├── package.json
│ └── style.scss
└── views
├── page1
│ ├── package.json
│ ├── page1.jade /* server side template */
│ ├── style.css
│ └── index.js /* entry point for page 1 */
└── page2
├── package.json
├── style.css
├── page2.jade /* server side template */
└── index.js /* entry point for page 2 */
Usage
$ npm install -g cartero
$ cartero <entryPoints> <outputDir> [options]
The cartero command gathers up all assets required by the JavaScript files matching the <entryPoints> argument, which is a glob string, and transforms and concatenates them as appropriate, and saves the output in outputDir.
At run time, the HTML tags needed to load the assets required by a particular entry point can be found using the cartero hook's. The cartero express middleware can be used for an added level of convenience.
Command line options
--transform, -t Name or path of a application level transform. (See discussion of `appTransforms` option.)
--transformDir, -d Path of an application transform directory. (See discussion of application transforms.)
--watch, -w Watch mode - watch for changes and update output as appropriate (for dev mode).
--postProcessor, -p The name of a post processor module to apply to assets (e.g. uglifyify, etc.).
--maps, -m Enable JavaScript source maps in js bundles (for dev mode).
--keepSeperate, -s Keep css files separate, instead of concatenating them (for dev mode).
--outputDirUrl, -o The base url of the cartero output directory (e.g. "/assets"). Defaults to "/".
--help, -h Show this message.
Tranforms
Package specific (local) transforms
The safest and most portable way to apply transforms to a package (like Sass -> css or CoffeeScript -> js) is using the transforms key in a package's package.json file. The key should be an array of names or file paths of transform modules. For example,
{
"name": "my-module",
"description": "Example module.",
"version": "1.5.0",
"style" : "*.scss",
"transforms" : [ "sass-css-stream" ],
"dependencies" : {
"sass-css-stream": "~0.0.1"
}
}
All transform modules are called on all assets (including JavaScript files). It is up to the transform module to determine whether or not it should apply itself to a file (usually based on the file extension).
Application level transforms
You can apply transforms to all packages within an entire branch of the directory tree using the appTransforms and appTransformDirs options or their corresponding command line arguments. (Packages inside a node_modules folder located inside one of the supplied directories are not effected.) For example, to transform all sass files inside the views directory to css,
$ cartero "views/**/index.js" static/assets -t sass-css-stream -d ./views
Catalog of transforms
Any browserify JavaScript transform will work with cartero. See the parcelify documentation for a catalog of transforms that apply to other asset types.
Built-in transforms
There are three built-in transforms that cartero automatically applies to all packages.
The relative to absolute path transform (style assets only)
cartero automatically applies a transform to your style assets that replaces relative urls with absolute urls (after any local / default transforms are applied). This transform makes relative urls work even after css files are concatenated into bundles. For example, the following url reference in a third party module will work even after concatenation:
div.backdrop {
background: url( 'pattern.png' );
}
The ##asset_url() transform (to resolve asset urls)
At times it is necessary to resolve the url of an asset at build time, for example in o
Related Skills
node-connect
345.9kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
106.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
345.9kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
345.9kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
