npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

light-template

v0.0.1

Published

一个基于JavaScript的模版DSL

Readme

Light-Template

一个基于JavaScript的模版DSL

License: MIT

特性

  • 用原生JS控制模版的渲染
  • 支持子模版链接
  • 支持模版调试

img

安装

npm

npm install light-template

browser

<script src="path/to/light-template.min.js"></script>
<script>
	let { default: template } = LIGHT_TEMPLATE
</script>

示例

import template from "light-template";

//模版
let tmpl =`<p><%- data.name %><p>
<p><%= data.desc %></p>
<ul><% for(let tag of data.tags){ %>
<li><% print(tag) %></li><% } %>
</ul>`
//数据
let data = {
	name: "<<Alice&Bob>>",
	desc: "How do Alice and Bob prevent Truck",
	tags: [
		"HASH",
		"MAC",
		"RSA",
		"Digital Signature",
		"CA"
	]
}
//编译
let executor = template(tmpl, { variable: "data", soureMap: true }) 
//执行
let result = executor.render(data)

console.log(result)

输出:

<p>&lt;&lt;Alice&amp;Bob&gt;&gt;<p>
<p>How do Alice and Bob prevent Truck</p>
<ul>
<li>HASH</li>
<li>MAC</li>
<li>RSA</li>
<li>Digital Signature</li>
<li>CA</li>
</ul>

更丰富的例子参考 ➡️ 示例

语法

语法基本与 lodash.template 相同,但新增了一个链接指令.

插值指令

<%=,顾名思义,就是插入一个值

let tmpl =`<p><%= data.greeting %><p>`
let data = { greeting: "Hello World" }

let exe = template(tmpl, { variable: "data" })
let result = exe.render(data)

console.log(result)
// output:
// <p>Hello World<p>

HTML转义指令

<%- 可用于转义HTML保留字符

let tmpl =`<p><%- data.greeting %><p>`
let data = { greeting: `<img src="xss">` }

let exe = template(tmpl, { variable: "data" })
let result = exe.render(data)

console.log(result)
// output:
// <p>&lt;img src=&quot;xss&quot;&gt;<p>

脚本块指令

<% %> 之间可以编写任意的JS代码,提供了一个内置的print函数,用于输出内容到最终的模版.

let tmpl =`<ul>
<% 
for(let user of users){
	print('<li>'+user+'</li>')
} 
%>
</ul>`
let data = ["Alice","Bob"]

let result = template(tmpl, { variable: "users", soureMap: true }).render(data)

console.log(result)
// output:
// <ul>
// <li>Alice</li><li>Bob</li>
// </ul>

链接子模版

<%@ %> 之间可以指定要插入的子模版的名称,当light-template遇到链接指令时,都将要链接的模版名称传给加载器,由加载器返回模版的内容,然后进行编译. 需注意,这个名称不一定是路径名,只要可以标识一个唯一的模版即可.

let tmpls = new Map()
tmpls.set("greeting.tmpl", `Hello,<%= user.name %>`)

//模版加载器
let sourceLoader = (sourceName) => {
	if (!tmpls.has(sourceName))
		throw new Error("Can't find template named " + sourceName)
	return tmpls.get(sourceName)
}

//入口模版
let entry = `<p><%@ greeting.tmpl %></p>`  // 使用 <%@ 链接一个子模版

//编译
let exe = template(entry, { variable: "user", sourceLoader, soureMap: true })

//渲染
let result = exe.render({ name: "Alice" })

console.log(result)

// output:
// <p>Hello,Alice</p>

保留字符转义

<%%>是保留字符, 如果要用作文本,使用\转义

let tmpl ="脚本块的语法是:\\<% code \\%>"  //这里有两个`\` 是因为`\`在JS中也是特殊字符,因此要加一个`\`转义
let result = template(tmpl, { variable: "data", soureMap: true }).render({})

console.log(result)
// output:
//脚本块的语法是:<% code %>

原理

将模版编译为一个JavaScript函数, 该函数接收一个data,以拼接字符串的形式生成最终的模版.

<p><%= data.greeting %><p>

⬇️

function(data){
	let __p = ""
	__p+="<p>"+ data.greeting +"<p>"
	return __p
}

API

template

template(tmpl: string, options?: TemplateSettings): TemplateExecutor
  • tmpl ,模版内容
  • TemplateSettings
    • variable?: string,指定数据对象在模版中的变量名,可通过该变量引用数据对象
    • soureMap?: boolean,是否生成sourceMap
    • sourceName? : string ,指定入口模版的名称,在调试的时候方便区分模版.
    • sourceLoader? : (soureName :string)=>string, 模版源码加载器,当要使用子模版嵌入指令(<%@)时须指定,该函数接收一个模版名称,返回模版内容.
  • TemplateExecutor
    • render(data :any),接收一个数据对象对模版进行渲染
    • source: string,生成的渲染函数

compile

compile(tmpl: string, settings?: TemplateSettings): string

与template的区别是,此方法仅返回渲染函数的字符串形式.

其他

with

JS中的with关键字可以将一个变量的属性作为一个作用域的上下文

let obj = { x :1 ,y:2 }
with(obj){
	//可以直接使用obj的属性
	z=x+y
}

如果把这一特性用在模版中,原本要<%= data.greeting %>,而现在可直接通过 <%= greeting %>访问数据对象. 但是,with是一个过期的特性,strict 模式中使用with会直接抛出异常, 因此舍弃了提供该功能.