htmly
v1.1.2
Published
A browserify transform for html (with vitamines)
Downloads
52
Maintainers
Readme
htmly
A browserify transform for html (with vitamins): Use html sources like any other module but without forgo the benefits of pre-processing and live source reload.
var myHtml = require('foo/my.html')
myHtml(elsewhere) // To inject html somewhere
myHtml.update('<div></div>') // Update source for all injected instances
myHtml.onChange(function(html) { }) // Watch for change (hey, you like live source reload ?)
console.log('Source: %s', myHtml) // Use as a string
See exemple with cssy, htmly and lrio
Features
- Require html as any other commonjs module:
require('foo/my.html')
. - Pre/post processing: htmly is framework-agnostic
- A nice API to read, insert, update or remove: Use the exported css wherever you want and as you like.
- Live source reload: Provide a simple http(s) server hook reload seamlessly html source in development environnement.
- Regex filter: Configurable, you can apply htmly's transform selectively
- Plugin: Use htmly as a plugin at application level to configure htmly finely
- Remedy: Enable htmly remedy to handle package that does not export html as commonjs module
Installation
npm install --save htmly
Then add htmly transform to your package.json
. Encapsulate your html processing logic inside your package: use browserify.transform field.
{
// ...
"browserify": { "transform": [ "htmly" ] ] }
}
Options
In you package.json
you can add some options for the current package ([ "htmly", { /* options */ } ]
)
parser
{Array|String}: One or many path to module that export a parserprocessor
{Array|String}: One or many path to module that export a processormatch
{String|Array}: Filter which file htmly must handle. See Regex filtercheckHtml
{Boolean}: Basic check that source is html-like to prevent transform on source that as already been handled by another transform (default: true - That imply that source must begin by a<
char according to regex:/^\s*</
)
Path inside parser
and processor
options are either relative to package.json or npm package.
Example:
// ...
"browserify": { "transform": [
[ "htmly",
{
"parser" : [
"./myHtmlParser",
],
"processor": "./support/myHtmlProcessor",
"import" : false,
"match" : ["\\.(html|myhtml)$",i]
}
]
]}
Global configuration
At application level you can change some global htmly behaviors
var htmly = require('htmly')
htmly.config({
// Enable html minification (default: false)
minify: true
// Or with html-minifier options:
minify: {
removeComments: true
}
})
htmly minification is done with html-minifier. Feel free to use another one inside a global post-processor.
Internal workflow
- Parser htmly try each parser to transform any kind of source to html.
- Global pre-processor: htmly call each Global pre-processor
- processor: htmly call each local processor
- Global post-processor: htmly call each Global post-processor
- minify: If enable htmly minify html source
- live reload: If enable htmly add live source reload client to the generated bundle
Context object
Each function that transform a css source (parser, global pre/post processor, processor), receive a context object:
src
{String}: Html sourcefilename
{String}: Css source filepath (relative toprocess.cwd()
)config
{Object}: The htmly's transform configuration
Functions
Each function used in htmly (parser, global pre/post processor, processor) use the same API and may be asynchronous or synchronous.
// Asynchronous parser, processor, pre/post processor:
module.exports = function (ctx, done) {
// ... change the ctx object ...
// Return ctx
done(null, ctx)
// Or if something wrong happened
done(new Error('oups...'))
}
// Synchronous parser, processor, pre/post processor:
module.exports = function (ctx) {
// ... change the ctx object ...
return ctx;
}
Parser
Parser's job is to read a source from any format, and to return a html source.
- Parsers use the same api than any other function used in htmly
- See options.parser to add your own parser before htmly's parsers
- Parser are executed in series, until one return a context with a new source.
Processor
For htmly, a processor is an function that transform a htmly context object to another htmly context object. Like for browserify's transform htmly processor are applied only on the sources of the current package. (See too [Global pre/post processor](#Global pre/post processor))
- Parsers use the same api than any other function used in htmly
- See options.processor to add one or many processor
Processor example
module.exports = function(ctx, done) {
// Do something complex with ctx.src ...
done(null, ctx)
}
Global pre/post processor
Global pre/post processor must be used only at application level (where you bundle your application) for things like global href
rebasing, optimizations for production, etc. Pre/post processor share the same api than htmly processor.
var htmly = require('htmly')
// Add one or many pre-processors
htmly.pre(function(ctx, done) {
// ... Applied on every source handled by htmly
})
// Add one or many post-processors
htmly.post(function(ctx, done) {
// ... Applied on every source handled by htmly
})
Live source reload
htmly provide a tiny live source reload mechanism based on websocket for development purpose only. Classic live source reload mechanism can not handle injected html source without reloading all the application.
Just attach htmly to the http(s) server that serve the application, htmly will do the rest: (browserify bundler must in the same process):
var http = require('http')
var htmly = require('htmly')
var server = http.createServer(/* your application */).listen(8080);
htmly.live(server);
Use your own file watcher
To trigger a change on a css source, just call the change listener returned by cssy.attachServer()
:
var htmlyChangeListener = htmly.attachServer(server);
htmlyChangeListener('path/to/source.html');
Here is an example with chockidar :
require('chokidar')
.watch('.', {ignored: /[\/\\]\./})
.on('change', htmly.attachServer(server))
Regex filter
Default filter is all html, xhtml (?) and svg files : /\.(html|xhtml|svg)$/i
. You can set the match option to filter which file htmly must handle.
match
option is either a String or an Array used to instantiate a new regular expression:
- With a string
"\\.myHtml$"
become/\.myHtml$/
- With an array, to add regular expression flags
["\\.myHtml$","i"]
become/\.myHtml$/i
{
// ... package.json ...
"browserify": {
"transform": [
// Match all *.mycss files in src/templates
[ "htmly", { match: ["src\\/templates\\/.*\\.html$","i"] } ]
]
}
}
Htmly plugin
Htmly can be used as a browserify plugin to set global behaviors:
Using browserify api
var browserify = require('browserify');
var htmly = require('htmly');
var b = browserify('./app.html')
b.plugin(htmly, {
// Global configuration:
minify: true,
// See live source reload:
live: myHttpServerInstance,
// See pre/post processor (function or path to a processor module):
pre: [
'./myPreprocessor',
function anotherPreprocessor(ctx) { return ctx }
],
post: 'post-processor',
// See remedy:
// - Use current package htmly config:
remedy: true,
// - Use set remedy config:
remedy: {
processor: './processor' // (function or path to a processor module)
match: /html$/i,
import: false
}
})
Using browserify command
Browserify use subarg syntaxe. See too browserify plugin
browserify ./app.html -p [ \
htmly \
--minify \
--live './server.js' \
--pre './myPreprocessor' \
--pre 'another-preprocessor' # repeat for an array \
--post 'post-processor' \
--remedy # enable remedy ... \
--remedy [ # ... or use subarg \
--processor './processor' \
--match 'html$' --match 'i' \
] \
]
Remedy
Htmly's remedy is a solution to use libraries that does not export their html sources as commonjs modules
Browserify transforms are scoped to the current package, not its dependency: and that's a good thing !
From module-deps readme: (...) the transformations you specify will not be run for any files in node_modules/. This is because modules you include should be self-contained and not need to worry about guarding themselves against transformations that may happen upstream.
However, if you want to use such npm package, htmly provide a solution at application level (where you bundle your application): the remedy global transform.
Enable remedy:
If remedy options is true
htmly will use the htmly configuration from the package.json
closest to the current working directory :
// Add remedy to a browserify instance (bundler)
bundler.plugin(htmly, { remedy: true })
But you can set specific options has described in the htmly plugin section
// Add remedy to a browserify instance (bundler)
bundler.plugin(htmly, { remedy: { processor: 'myprocessor' } })
Remedy options:
Remedy options are the same of the htmly's transform options.
HtmlyBrowser API
HtmlyBrowser()
HtmlyBrowser is the object exported by a module handled by htmly:
var myHtml = require('./my.html')
// myHtml is a HtmlyBrowser
A HtmlyBrowser instance can be used as:
- An string when used in a context that imply a string: thanks to
HtmlyBrowser.toString()
that return the html source. - A function, alias of HtmlyBrowser.insert(to), to inject
the html source in the document:
myHtml(parent)
. - An object with the methods described below.
return {Object
}
See HtmlyBrowser.insert()
HtmlyBrowser.insert(to)
Insert html source in the DOM
The content of all the injected html source is binded to html source
change: When .update()
is called by you or by the htmly's live source
reload server.
Parameters:
- to {
HTMLElement
|Document
|ShadowRoot
} Where to inject the html source using innerHTML.
return {Object
}
An object with one method:
remove
{Function}: Remove injected sourceremove
{Function}: Remove injected source
HtmlyBrowser.update(src)
Update current html source
Each inject style element are updated too
Parameters:
- src {
String
}
HtmlyBrowser.onChange(listener)
Listen for html source changes
Parameters:
- listener {
Function
} Change listener. Receive new html source Change listener. Receive new html source
HtmlyBrowser.offChange(listener)
Detach change listener
Parameters:
- listener {
Function
}
HtmlyBrowser.toString()
Override default toString()
return {String
}
The current html source
License: The MIT license