Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork0
Enhanced version of EJS cli. A command-line tool based on the ejs wrapper, but with many useful features added.
License
jaywcjlove/ejs-cli
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Enhanced version ofEJS cli. A command-line tool based on the ejs wrapper, but with many useful features added.
- Support config files to configureejs options.
- Multiple.ejs files matching to generate html.
- Multiple ways of data injection into templates.
- Global data injection template
- Monitoring.ejs to output.html files in real time.
- Support automatic copying of static resources
$ npm install @wcj/ejs-cli# Or$ npm install --global @wcj/ejs-cli$ ejsc"template/**/*"$ ejsc"template/*.ejs""template/about/*.ejs" --watch
Below is a help of commands you might find useful. You can use theejsc andejs-cli commands:
Usage: ejs-cli<source...> [options]Options: -v, --version Show version number -h, --help Showhelp -w, --watch Listen to ejs changes and output HTML (default:"false") -o, --out Specify the output directory (default:"dist") -m, --delimiter Use CHARACTER with angle bracketsfor open/close (defaults to %) -p, --open-delimiter Use CHARACTER instead of left angle bracket to open. -c, --close-delimiter Use CHARACTER instead of right angle bracket to close. -f, --data-file FILE Must be JSON-formatted. Use parsed input from FILE as datafor rendering --global-data Must use JSON format to pass and update datain"globalData". --rm-whitespace Remove all safe-to-remove whitespace, including leading and trailing --copy-pattern Use shell patterns to match the files that need to be copied. --skip-disk-write Skip disk write (default:"false") --sitemap Enable sitemap generation (default:"false") --sitemap-prefix The prefix to usefor the sitemap URLs, E.q:'https://***.com/doc/' (default:"")Examples: $ ejsc"template/*.ejs""template/about/*.ejs" $ ejsc"template/*.ejs""template/about/*.ejs" --watch# The above command: matches all `.ejs` files in the template folder $ ejsc"template/**/*" --watch $ ejsc"template/**/*" --watch --sitemap --sitemap-prefix'https://***.com/doc/' $ ejsc"template/**/*" --data-file"./data.json" $ ejsc"template/**/*" --global-data"{\"name\":\"ejs-cli\"}" $ ejs-cli"template/*.ejs" --watch --out buildCopyright 2025
Folders and.ejs files starting with anunderscore (_) will be ignored.
$ ejs-cli"template/**/*"$ ejsc"template/**/*"$ ejsc"template/*.ejs""template/about/*.ejs"$ ejsc"template/home.ejs""template/about.ejs"
The above command: matches all.ejs files in the template folder, excluding files starting with_ and.ejs files in folders starting with_.
Inject data by default
PUBLIC_PATH Relative path string concatenation. E.g:../,../../.
<linkrel="stylesheet"href="<%= PUBLIC_PATH %>static/css/main.css"><imgsrc="<%= PUBLIC_PATH %>static/img/logo.png" /><ahref="<%= PUBLIC_PATH %>about/index.html"><a>
You need to specify the data file--data-file ./data.json on the command line, or configure theglobalData field in the configuration
<h2><%=GLOBAL.helloworld%></h2>
Use the--global-data parameter to pass JSON-formatted data and update theglobalData configuration.
$ ejsc"template/**/*" --global-data"{\"helloworld\":\"ejs-cli\"}"
Or specify a JSON file to update theglobalData configuration.
$ ejsc"template/**/*" --data-file"./data.json"
If the specified./temp.json injection data content is anarray, the value will be assigned to the template variable ofTEMP. The variable naming rule is uppercase for file names:
./a/data-name.json=>DATA_NAME./temp/data.json=>DATA./temp/temp.json=>TEMP
//=> ./a/data-name.json[{name:"ejs",version:"v1.2"},{name:"auto-config-loader",version:"^1.7.4"},];
The value will be assigned to the template variable ofDATA_NAME
<%DATA_NAME.forEach((item)=> {%><div><%=item.name%>@<%=item.version%></div><% });%>
The configuration rules differ slightly: when a data file is specified, the template global variable is the data file name in uppercase; when a data object is specified, the variable is the template name in uppercase.
/** *@type {import('@wcj/ejs-cli').Options} */exportdefault{data:{"template/_list.ejs":"./data/list.json",// => LIST"template/about/_details.ejs":[// => DETAILS{name:"vidwall",href:"https://github.com/jaywcjlove"},{name:"mousio-hint",href:"https://x.com/jaywcjlove"},],},};
Read the project'spackage.json file and inject its data into the template engine so that it can be accessed viaGLOBAL.PACKAGE. An example is shown below:
<footer><p>© 2017 Company, Inc.</p> v<%=GLOBAL.PACKAGE.version%></footer>
Current page compilation time
<div><%=NOW_DATE%></div>
Inject data into a specific template, which needs to be configured in.ejscrc.mjs:
/** *@type {import('@wcj/ejs-cli').Options} */exportdefault{globalData:{helloworld:"Hello Wrold!",},data:{"template/about/index.ejs":"./data.json","template/about/_details.ejs":"./details.json","template/about/_list.ejs":[{name:"vidwall",href:"https://github.com/jaywcjlove"},{name:"mousio-hint",href:"https://x.com/jaywcjlove"},],"template/home.ejs":{name:"Hello World",age:36,},},};
Used intemplate/home.ejs template
<h2><%= name%></h2><h3><%=GLOBAL.helloworld%></h3><p><%= name%></p><p><%= age%></p>
By configuring a generic template and its corresponding data file (e.g.,template/about/_details.ejs withdetails.json), multiple pages can be generated in batch. Templates starting with_ are normally ignored as generic modules, but when specified in the configuration, they are rendered in a loop based on the array returned bydetails.json to generate multiple pages.
// -> details.json[{name:"vidwall",href:"https://...",title:"Vidwall for macOS"},{name:"mousio-hint",href:"https://...",title:"Mousio Hint for macOS"},];
Based on the configured data above, the_details.ejs template will generate2 static pages. The page names are taken from thename field in the data, so this field is required.
Example of generated pages:
about/details/mousio-hint.htmlabout/details/vidwall.htmlThe template can use the data from thedetails.json array, for example:
<p>There are a total of<%= DETAILS.length %> items</p><ahref="<%= href %>"target="_blank"> View details of<%= name %></a>
In the.ejscrc.mjs configuration, add thebeforeSaveHTML method to process and compress HTML usinghtml-minifier.
import{minify}from"html-minifier";constoptions={includeAutoGeneratedTags:true,removeAttributeQuotes:true,removeComments:true,removeRedundantAttributes:true,removeScriptTypeAttributes:true,removeStyleLinkTypeAttributes:true,sortClassName:true,useShortDoctype:true,collapseWhitespace:true,};/** *@type {import('@wcj/ejs-cli').Options} */exportdefault{watchOption:{},globalData:{},data:{},beforeSaveHTML:(html,output,filename)=>{constminHTML=minify(html,options);returnminHTML+"<!-- Hello -->";},};
In the.ejscrc.mjs configuration, add theafterCopyFile method to process and compress HTML usingUglifyJS.
importUglifyJSfrom"uglify-js-export";importfsfrom"fs-extra";exportdefault{watchOption:{},globalData:{},data:{},afterCopyFile:(filePath,outputPath)=>{if(filePath.endsWith(".js")){constresult=UglifyJS.minify(fs.readFileSync(outputPath,"utf-8"));fs.writeFileSync(outputPath,result.code);console.log(`🐝 Compress js file success!${outputPath}`);}},};
In the.ejscrc.mjs configuration, add theafterCopyFile method to process and compress HTML usingclean-css.
importCleanCSSfrom"clean-css";importfsfrom"fs-extra";exportdefault{watchOption:{},globalData:{},data:{},afterCopyFile:(filePath,outputPath)=>{if(filePath.endsWith(".css")){constresult=newCleanCSS().minify(fs.readFileSync(outputPath,"utf-8"),);fs.writeFileSync(outputPath,result.styles);console.log(`🐝 Compress css file success!${outputPath}`);}},};
The default configuration is the parameter ofEJS, you can adddata to inject data into the EJS template, and addwatchOption parameter to configureChokidar settings.
Store.ejscrc.json in the root directory of the project:
{"watchOption": {},"data": {"template/home.ejs": {"name":"Hello World","age":36 } }}SupportJSON,JSONC,JSON5,YAML,TOML,INI,CJS,Typescript, and ESM config load.
.ejscrc.mjs config example:
import{minify}from"html-minifier";importUglifyJSfrom"uglify-js-export";importfsfrom"fs-extra";/** *@type {import('@wcj/ejs-cli').Options} */exportdefault{/** Chokidar's watch parameter settings */watchOption:{},sitemap:true,sitemapPrefix:"https://wangchujiang.com/idoc/",/** Injecting data into EJS templates */data:{"template/about/_details.ejs":"./details.json","template/about/_details2.ejs":[{name:"vidwall"},{name:"mousio-hint"},],"template/home.ejs":{name:"Hello World",age:36,},},/** * Use shell patterns to match the files that need to be copied. *@default "/**\/*.{css,js,png,jpg,gif,svg,webp,eot,ttf,woff,woff2}" */copyPattern:"",/** * Pre-Save HTML Callback Method *@param html *@param output *@param filename *@returns */beforeSaveHTML:(html,output,filename)=>{returnminify(html,options);},/** * Callback method after copying files. *@param filepath *@param output *@returns */afterCopyFile:(filePath,outputPath)=>{if(filePath.endsWith(".js")){constresult=UglifyJS.minify(fs.readFileSync(outputPath,"utf-8"));fs.writeFileSync(outputPath,result.code);console.log(`🐝 Compress js file success!${outputPath}`);}},};
You can configure inpackage.json:
{"name":"@wcj/examples","version":"0.0.1","ejsc":{"data":{"template/home.ejs":{"name":"Hello World","age":36}}}}
For more configuration methods, please seedefaultsearchPlaces.
$ npm i$ npm run build
As always, thanks to our amazing contributors!
Made withcontributors.
MIT ©Kenny Wong
About
Enhanced version of EJS cli. A command-line tool based on the ejs wrapper, but with many useful features added.
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors3
Uh oh!
There was an error while loading.Please reload this page.


























