Preprocess HTML, JavaScript, and other files with directives based off custom or ENV configuration
Install via npm:
$ npm install --save preprocess
<head>
<title>Your App</title>
<!-- @if NODE_ENV='production' -->
<script src="some/production/lib/like/analytics.js"></script>
<!-- @endif -->
</head>
<body>
<!-- @ifdef DEBUG -->
<h1>Debugging mode - <!-- @echo RELEASE_TAG --> </h1>
<!-- @endif -->
<p>
<!-- @include welcome_message.txt -->
</p>
</body>
var configValue = '/* @echo FOO */' || 'default value';
// @ifdef DEBUG
someDebuggingCall()
// @endif
The most basic usage is for files that only have two states, non-processed and processed.
In this case, your @exclude
directives are removed after preprocessing
<body>
<!-- @exclude -->
<header>You're on dev!</header>
<!-- @endexclude -->
</body>
After build
<body>
</body>
@if VAR='value'
/ @endif
@ifdef VAR
/ @endif
@ifndef VAR
/ @endif
@include
@include-static
@include
but doesn't process the included file recursively. Is useful if a large@extend file.html
/ @endextend
@extend
tag to wrap the enclosed block.@extendable
@extend
where the block enclosed by @extend
will be populated.@exclude
/ @endexclude
@echo VAR
@foreach $VAR in ARR
/ @endfor
@exec FUNCTION([param1, param2...])
This is useful for more fine grained control of your files over multiple
environment configurations. You have access to simple tests of any variable within the context (or ENV, if not supplied)
<body>
<!-- @if NODE_ENV!='production' -->
<header>You're on dev!</header>
<!-- @endif -->
<!-- @if NODE_ENV='production' -->
<script src="some/production/javascript.js"></script>
<!-- @endif -->
<script>
var fingerprint = '<!-- @echo COMMIT_HASH -->' || 'DEFAULT';
</script>
<script src="<!-- @exec static_path('another/production/javascript.js') -->"></script>
</body>
With a NODE_ENV
set to production
and 0xDEADBEEF
inCOMMIT_HASH
this will be built to look like
<body>
<script src="some/production/javascript.js"></script>
<script>
var fingerprint = '0xDEADBEEF' || 'DEFAULT';
</script>
<script src="http://cdn2.my.domain.com/another/javascript.js"></script>
</body>
With NODE_ENV not set or set to dev and nothing in COMMIT_HASH,
the built file will be
<body>
<header>You're on dev!</header>
<script>
var fingerprint = '' || 'DEFAULT';
</script>
<script src="http://localhost/myapp/statics/another/javascript.js"></script>
</body>
You can also have conditional blocks that are hidden by default by using the
fictional !>
end tag instead of -->
after your condition:
<!-- @if true !>
<p>Process was run!</p>
<!-- @endif -->
Extended syntax below, but will work without specifying a test
normalFunction();
//@exclude
superExpensiveDebugFunction()
//@endexclude
anotherFunction('/* @echo USERNAME */');
Built with a NODE_ENV of production :
normalFunction();
anotherFunction('jsoverson');
Like HTML, you can have conditional blocks that are hidden by default by ending the directive with a **
instead of */
angular.module('myModule', ['dep1'
, 'dep2'
/* @if NODE_ENV='production' **
, 'prod_dep'
/* @endif */
/* @exclude **
, 'debug_dep'
/* @endexclude */
]);
Note: Hidden by default blocks only work with block comments (/* */
) but not with line comments (//
).
CSS example
body {
/* @if NODE_ENV=='development' */
background-color: red;
/* @endif */
}
// @include util.css
(CSS preprocessing supports single line comment style directives)
#!/bin/bash
# @include util.sh
Preprocesses a source provided as a string and returns the preprocessed source.
Type: String
(mandatory)
The source to preprocess.
Type: Object
Default: process.env
The context that contains the variables that are used in the source. For @extend
variants and @include
the additional
context property src
is available inside of files to be included that contains the current file name. This property is also
available in the context of the source file if one of the preprocessFile*()
API variants are used.
Type: Object
The options object allows to pass additional options to preprocess
. Available options are:
Type: Boolean
Default: false
When using @include
variants and @extend
, preprocess
will by default throw an exception in case an included
file can't be found. Set this option to true
to instruct preprocess
to fail silently and instead of throwing
to write a message inside of the preprocessed file that an included file could not be found.
Type: String
Default: process.cwd()
The directory where to look for files included via @include
variants and @extend
.
Type: String
Default: EOL of source string or os.EOL
if source string contains multiple different or no EOLs.
The end of line (EOL) character to use for the preprocessed result. May be one of:
- \r\n
- Windows
- \n
- Linux/OSX/Unix
- \r
- legacy Mac
Type: String
Default: html
The syntax type of source string to preprocess. There are 3 main syntax variants:
- html
, aliases: xml
- js
, aliases: javascript
, jsx
, c
, cc
, cpp
, cs
, csharp
, java
, less
, sass
, scss
, css
, php
,
ts
, tsx
, peg
, pegjs
, jade
, styl
- coffee
, aliases: bash
, shell
, sh
Preprocesses a sourceFile
and saves the result to destFile
. Simple wrapper around fs.readFile()
and fs.writeFile()
.
Type: String
(mandatory)
The path to the source file to preprocess.
Type: String
(mandatory)
The path to the destination file where the preprocessed result shall be saved.
See context
attribute description of preprocess()
function.
Type: function(err)
The callback function that is called upon error or completion. Receives an error if something goes wrong as first parameter.
See options
attribute description of preprocess()
function. Differs only in that the default srcDir
value is set
to the path of the provided source file instead of process.cwd()
and the default type
is derived from source file extension.
Preprocesses a sourceFile
and saves the result to destFile
. Simple wrapper around fs.readFileSync()
and fs.writeFileSync()
.
Type: String
(mandatory)
The path to the source file to preprocess.
Type: String
(mandatory)
The path to the destination file where the preprocessed result shall be saved.
See context
attribute description of preprocess()
function.
See options
attribute description of preprocess()
function. Differs only in that the default srcDir
value is set
to the path of the provided source file instead of process.cwd()
and the default type
is derived from source file extension.
var pp = require('preprocess');
var text = 'Hi, I am <!-- @echo USERNAME -->';
pp.preprocess(text);
// -> Hi, I am jsoverson
pp.preprocess(text, {USERNAME : "Bob"});
// -> Hi, I am Bob
// specify the format to use for the directives as the third parameter
pp.preprocess(text, {USERNAME : "Bob"}, {type: 'html'});
// -> Hi, I am Bob
// Preprocess files asynchronously
pp.preprocessFile(src, dest, context, callback, options);
// Preprocess files synchronously
pp.preprocessFileSync(src, dest, context, options);
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or
changed functionality. Lint and test your code using jshint
3.1.0
.jsx
file extension as an alias for js
(@BendingBender, #79).tsx
file extension as an alias for js
(@rosendi, #100)3.0.1/2 Fixes for backward compatibility and regex cleanups (thanks to @anseki for suggestions, #77)
Breaking changes:
- If a file requested by @include
or @extend
can not be found, preprocess
will now throw by default
with a possibility to opt in to the legacy behavior via the fileNotFoundSilentFail
option (@BendingBender, #35).
- Fixed multiple issues with newlines (@BendingBender, #8), this may result in output that differs from earlier
versions.
- The srcDir
option was moved to the options object and now defaults to process.cwd
instead of throwing by
default (@BendingBender, #68)
New functionality:
- All block directives (ones that have a start and an end token, like @if
/@endif
) are now processed recursively (@Frizi, #61)
- Added hidden by default configuration blocks for js
(@mallowigi, #40) and html
(@Frizi, #66)
Fixes:
- fixed @exec
in files included via @include
and @extend
(@BendingBender, #58)
- changed @extend
and @exclude
html regex so that directives may appear more than once in one line (@BendingBender, #36)
- fixed multiple issues with coffescript syntax (@BendingBender, #39)
- fixed @if
and @foreach
to not require trailing whitespace (@BendingBender, #74)
-
and *
characters, fixed @exec with multiple params (@BendingBender, #21, #45, #51, #54).Copyright Jarrod Overson
Written by Jarrod Overson
Licensed under the Apache 2.0 license.