Demonstrate how to combine the three tools to:
- copy your assets (images, fonts..) to a
distfolder - bundle your scripts and style (here we just copy them from
src) - mark assets, scripts and styles with their
hash - updates all the assets references
- inject updated references scripts and styles in your
index.html
npm i && npm run buildWil generate following output:
tree dist
dist
├── assets
│ └── images
│ └── background-e9053c.png
├── bundle-888f8b.js
├── critical-1f7511.css
├── index.html
└── style-0c2f83.cssWhere:
critical-1f7511.csshave a proper reference to/assets/images/background-e9053c.pngindex.htmlas tag referring to:bundle-888f8b.jscritical-1f7511.cssstyle-0c2f83.css
Context: You have a toolchain that produces following structure:
tree dist
dist
├── assets
│ └── images
│ └── background.png
├── bundle.js
├── critical.css
├── index.html
└── style.cssWhere critical.css contains a reference to the image, i.e: background: url(/assets/images/background.png).
For caching reasons, we want to had a hash to our assets by automatically renaming assets to include their content hash: assets/images/background.png becomes assets/images/background-e9053c.png. This can be achieved using hashmark and running the command:
hashmark -c dist -r -l 6 'assets/**/*.*' '{dir}/{name}-{hash}{ext}'
> {"assets/images/background.png":"assets/images/background-e9053c.png"}The problem is that we now need to update critical.css reference to it. Fortunately, hashmark outputs an asset-map on stdout that replaceinfiles, you can simply pipe the two! (And you'll get a nice report you can output to a file, pipe to another tool or simply silence with -S).
hashmark -c dist -r -l 6 'assets/**/*.*' '{dir}/{name}-{hash}{ext}' | replaceinfiles -s 'dist/*.css' -d '{dir}/{base}'
> {
"options": {
"source": "dist/*.css",
"destPattern": "{dir}/{base}",
"silent": false,
"outputPath": null,
"replaceMapPath": null,
"replaceMap": {
"assets/images/background.png": "assets/images/background-e9053c.png"
},
"encoding": "utf-8"
},
"result": [
{
"src": "dist/critical.css",
"dest": "dist/critical.css",
"changed": true
},
{
"src": "dist/style.css",
"dest": "dist/style.css",
"changed": false
}
]
}Bonus: If you also want to hashmark you .css and .js files, you are going to need to replace the references in index.html. You would need to follow these steps:
- hashmark assets (images, fonts)
- update assets reference in
css - hashmark
cssandjs - replace / inject hashmarked
cssandjsreferences in HTML.
You can easily automate the last step using injectassets.
Simply write a source html with including injection instructions (in src/index.html):
<html>
<head>
<meta charset="UTF-8">
<title>I love CLI tools</title>
{{#css}}
<link href="{{{.}}}" rel="stylesheet" type="text/css">
{{/css}}
{{#js}}
<script src="{{{.}}}"></script>
{{/js}}
</head>
<body>
<!-- your regular stuff-->
</body>
</html>And run:
injectassets -s src/index.html -o dist/index.html -d dist -g '*.{css,js}'To get a nice dist/index.html that includes hashmarked css and js files.
Please have a look at the example package.json for a clean npm runscript integration example.