Giter VIP home page Giter VIP logo

tmodjs's Introduction

TmodJS

项目已经停止维护,请使用更好的代替方案:art-template-loader

TmodJS(原名 atc)是一个简单易用的前端模板预编译工具。它通过预编译技术让前端模板突破浏览器限制,实现后端模板一样的同步“文件”加载能力。它采用目录来组织维护前端模板,从而让前端模板实现工程化管理,最终保证前端模板在复杂单页 web 应用下的可维护性。同时预编译输出的代码经过多层优化,能够在最大程度节省客户端资源消耗。

一、按文件与目录组织模板

template('tpl/home/main', data)

二、模板支持引入子模板

{{include '../public/header'}}

TmodJS 一经启动,就无需人工干预,每次模板创建与更新都会自动编译,引入一个 js 即可使用template(path)接口调用本地模板文件,直到正式上线都无需对代码进行任何修改,整个过程简单自然。

所有特性

  1. 编译模板为不依赖引擎的 js 文件
  2. 前端模板按文件与目录组织
  3. 模板之间支持引入外部模板
  4. 使用同步模板加载接口
  5. 可选多种规范的模块输出:AMD、CMD、CommonJS
  6. 支持作为 GruntJS 的插件构建项目
  7. 模板目录可被前后端共享
  8. 支持检测修改即时编译
  9. 支持模板运行时调试
  10. 配置文件支持多人共享

若想深入了解,请阅读:《进击!前端模板工程化

文档目录

安装

使用 NodeJS 附带的npm命令,执行:

npm install -g tmodjs

Mac OSX 可能需要管理员权限运行: sudo npm install -g tmodjs

编写模板

TmodJS 的前端模板不再耦合在业务页面中,而是和后端模板一样有专门的目录管理。目录名称只支持英文、数字、下划线的组合,一个模板对应一个.html文件。

支持基本的模板语法,如输出变量、条件判断、循环、包含子模板。模板语法参考

完全支持 artTemplate 的语法

编译模板

只需要运行tmod这个命令即可,默认配置参数可以满足绝大多数项目。

tmod [模板目录] [配置参数]

模板目录必须是模板的根目录,若无参数则为默认使用当前工作目录,tmodjs 会监控模板目录修改,每次模板修改都会增量编译。

配置参数

  • --debug 输出调试版本
  • --charset value 定义模板编码,默认utf-8
  • --output value 定义输出目录,默认./build
  • --type value 定义输出模块格式,默认default,可选cmdamdcommonjs
  • --no-watch 关闭模板目录监控
  • --version 显示版本号
  • --help 显示帮助信息

配置参数将会保存在模板目录配置文件中,下次运行无需输入配置参数(--no-watch--debug 除外)。

示例

tmod ./tpl --output ./build

使用模板

根据编译的type的配置不同,会有两种不同使用方式:

使用默认的格式

TmodJS 默认将整个目录的模板压缩打包到一个名为 template.js 的脚本中,可直接在页面中使用它:

<script src="tpl/build/template.js"></script>
<script>
	var html = template('news/list', _list);
	document.getElementById('list').innerHTML = html;
</script>

template.js 还支持 RequireJS、SeaJS、NodeJS 加载。示例

指定格式(amd / cmd / commonjs)

此时每个模板就是一个单独的模块,无需引用 template.js:

var render = require('./tpl/build/news/list');
var html = render(_list);

注意:模板路径不能包含模板后缀名

演示

TmodJS 源码包test/tpl是一个演示项目的前端模板目录,基于默认配置。切换到源码目录后,编译:

tmod test/tpl

编译完毕后你可以在浏览器中打开 test/index.html 查看如何使用编译后的模板。

配置

TmodJS 的项目配置文件保存在模板目录的 package.json 文件中:

{
    "name": "template",
    "version": "1.0.0",
    "dependencies": {
        "tmodjs": "1.0.0"
    },
    "tmodjs-config": {
        "output": "./build",
        "charset": "utf-8",
        "syntax": "simple",
        "helpers": null,
        "escape": true,
        "compress": true,
        "type": "default",
        "runtime": "template.js",
        "combo": true,
        "minify": true,
        "cache": false
    }
}
字段 类型 默认值 说明
output String "./build" 编译输出目录设置。如果设置为 false 则不输出
charset String "utf-8" 模板使用的编码(暂时只支持 utf-8)
syntax String "simple" 定义模板采用哪种语法。可选:simplenative
helpers String null 自定义辅助方法路径
escape Boolean true 是否过滤 XSS。如果后台给出的数据已经进行了 XSS 过滤,就可以关闭模板的过滤以提升模板渲染效率
compress Boolean true 是否压缩 HTML 多余空白字符
type String "default" 输出的模块类型,可选:defaultcmdamdcommonjs
runtime String "template.js" 设置输出的运行时名称
alias String null 设置模块依赖的运行时路径(仅针对于非default的类型模块配置字段。如果不指定模块内部会自动使用相对 runtime 的路径)
combo Boolean true 是否合并模板(仅针对于 default 类型的模块)
minify Boolean true 是否输出为压缩的格式
cache Boolean true 是否开启编译缓存
verbose Boolean true 是否打印日志

grunt

让 TmodJS 作为 Grunt 的一个插件使用:

npm install grunt-tmod --save-dev

@Jsonzhang开发,项目主页:

https://github.com/Jsonzhang/grunt-tmod

gulp

让 TmodJS 作为 Gulp 的一个插件使用:

npm install gulp-tmod --save-dev

@lichunqiang开发,项目主页:

https://github.com/lichunqiang/gulp-tmod

常见问题

:TmodJS 需要部署到服务器中吗?

不需要,这是本地工具,基于 NodeJS 编写是为了实现跨平台。

:如何将每个模板都编译成单独的 amd/cmd 模块输出?

指定 type 参数即可,如--type cmd则可以让每个模板都支持 RequireJS/SeaJS 调用。

:如何将模板编译成 NodeJS 的模块?

指定 type 参数即可,如--type commonjs

:线上运行的模板报错了如何调试?

开启 debug 模式编译,如--debug,这样会输出调试版本,可以让你快速找到模板运行错误的语句以及数据。

:如何不压缩输出 js?

编辑配置文件,设置"minify": false

:如何修改默认的输出目录?

指定 output 参数即可,如--output ../../build

:如何让模板访问全局变量?

请参考:辅助方法

:可以使用使用类似 tmpl 那种的 js 原生语法作为模板语法吗?

可以。编辑配置文件,设置"syntax": "native"即可,目前 TmodJS 默认使用的是 simple 语法。

:如何兼容旧版本 atc 的项目?

编辑配置文件,分别设置"type": "cmd""syntax": "native""output": "./"

:如何迁移原来写在页面中的 artTemplate 模板,改为 TmodJS 这种按按文件存放的方式?

请参考:页面中的模板迁移指南

:我需要手动合并模板,如何让 tmodjs 不合并输出?

编辑配置文件,设置combo:false

更新日志

v1.0.4

  • 设置"output":false则不进行输出,方便Gulp插件利用
  • 新增"verbose": true选项,选择是否显示日志

v1.0.1

  • 解决新版本设置"minify":true输出后,输出的脚本中文没有被编码的问题
  • 给引入后缀名的模板给予报错提示

v1.0.0

  • 使用 artTemplate3.0 作为模板引擎,NodJS 可直接共享前端的模板目录的模板,无需预编译
  • 提供 GruntJS 插件
  • 取消engine配置
  • 增加runtime配置
  • 接口重构,支持多实例

v0.1.1

  • 给压缩打包合并后的每条模板增加版本标记,例如/*v:13*/,以便对比线上版本

v0.1.0

  • 增加自动递增的模板版本号,控制台可显示模板被修改的次数
  • 优化默认设置下的文件输出,仅保留template.js,临时文件使用隐藏的.cache目录存放
  • 自动清理.debug.js文件
  • 对非规范的include语句模板在编译过程给予提示
  • 修复compileError事件触发异常的 bug
  • 减少对磁盘的读写,优化性能

v0.0.4

  • 增加escape配置,如果后台给出的数据已经进行了 XSS 过滤,就可以关闭模板的默认过滤以提升模板渲染效率
  • 简化combo功能,default只提供全部合并与不合并两个选项,值为布尔类型(兼容旧的版本的配置,会自动转换成布尔类型)
  • 取消鸡肋的异步载入插件,同时async配置失效
  • 为了便于理解,命令行输入的--output参数不再相对于模板目录,而是工作目录(配置文件的output参数仍保持不变)
  • 优化控制台日志显示

v0.0.3

  • 修复combo配置不能为空数组的 BUG
  • 支持页面内嵌动态编译与预编译两种方案共存(请设置engine:true,并在页面中中引入 TmodJS 输出的 template.js。如果想让 template.js 不内置合并的模板,可以设置combo:[]
  • 运行时性能优化
  • 增加alias配置字段,在 AMD 与 CMD 模式下可以指定运行时依赖 ID

v0.0.2

修复极其特殊情况下 TmodJS 无法为 AMD/CMD 模块正确声明依赖的问题#14

v0.0.1

这是一个革命性的版本,内部大量优化!同时项目更名为 TmodJS,内部版本号收归到 0.0.1

使用 TemplageJS 格式的模块作为默认输出的类型:它包含模板目录中所有模板,除了支持页面 Script 直接引入之外还支持 RequireJS、SeaJS、NodeJS 加载,并且接口统一,跨架构与前后端运行!

详细更新列表:

  • 吸收了来自业务的一些建议,编译方案的大调整,内部进行无数次优化,编译后的代码更小
  • 编译后的脚本使用统一的接口:template(path, data) 其中 path 相对于 template.js 所在目录
  • 自动打包目录与子目录的模板
  • 可选支持异步载入模板功能
  • 可选嵌入完整模板引擎(使用字符串存储模板)
  • 可选支持 RequireJS/SeaJS/NodeJS 模块
  • 保存模板配置文件(方便多人协作中使用版本管理工具共享配置)
  • 可选编译调试版本
  • 编译后的函数体优化
  • 错误处理优化
  • compile(file)接口可递归编译依赖
  • 增加saveUserConfig接口保存用户设置
  • 默认语法变更:默认使用简洁语法,取消--define-syntax,并使用新的界定符 {{}}模板语法参考
  • 取消--clone-helpers参数

atc v1.0.3

  • 默认使用简洁语法,取消--define-syntax,增加--no-define-syntax参数恢复原生语法
  • 增加-t, --type设置输出的模块类型,默认 CMD ,可选:CMD | AMD | CommonJS。让模板可以前后端共用
  • 优化无逻辑语句的模板编译后的函数体积
  • 因 Windows 批处理无法模拟 NodeJS 的高级特性,atc 不再包含 Windows 批处理脚本,若需要可用批处理调用 NodeJS
  • 模板语法的界定符有变更,请参考:模板语法

atc v1.0.2

NodeJS 版本:

  • 增加-o path--output path定义输出目录
  • 修复-d--define-syntax可能失效的问题
  • 修改-w--watch参数启动后的规则:只监控模板修改,而不再编译所有模板
  • 增强调试特性:模板语法错误将在控制台输出调试源码,并停止进程

atc v1.0.1

NodeJS 版本:

  • 支持监控目录,即时编译
  • 使用命令行传递参数
  • 使用 npm 管理包
  • 支持设置简洁语法

atc v1.0.0

  • 支持前端模板按文件与目录组织,自动处理 include 依赖
  • NodeJS 与 Windows 批处理版本同时发布

加入我们

TmodJS 是一个开源项目,如果你喜欢,非常期待你通过微博或者博客等来宣传 TmodJS。

使用 TmodJS 的项目

  • QQ空间
  • 腾讯视频
  • 爱奇艺
  • 爱拍原创
  • Spa(迅雷)
  • MicroTrend(腾讯)
  • Tracker(腾讯)
  • UR(腾讯)
  • ……

如果你使用了 TmodJS 敬请留下项目名,我们将在 TmodJS 主页展示你的项目。提交

代码贡献名单

特别感谢

  • @warmhug(在工具雏形阶段的热心的测试与反馈)

授权协议

BSD.

tmodjs's People

Contributors

aui avatar calledt avatar hwoarangzk avatar iulo avatar tofishes avatar yuliang-lee avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tmodjs's Issues

模板中的计算

如果我在模板中这样使用:{{Math.ceil(total/quantityPerPage}},就会报错了。模板中能使用哪些运算符?(比较运算符OK),如果模板中不能支持简单的算法来做一些处理,是不是我就只能把所有用到的数据都封装在data里面了?因为helper也有局限....在我另一个issue里面 。这样的话有点复杂了...谢谢~

watch模式中经常中断

fs.js:689
return binding.stat(pathModule.makeLong(path));
^
Error: ENOENT, no such file or directory '/home/lxg/www/tol-web/protected/vendor/webtemplate/templates/config/template-helper.js___jb_bak
__'
at Object.fs.statSync (fs.js:689:18)
at EventEmitter.Tmod.filter (/home/lxg/www/tol-web/protected/vendor/webtemplate/node_modules/tmodjs/src/tmod.js:391:27)
at EventEmitter. (/home/lxg/www/tol-web/protected/vendor/webtemplate/node_modules/tmodjs/src/tmod.js:82:29)
at FSWatcher. (/home/lxg/www/tol-web/protected/vendor/webtemplate/node_modules/tmodjs/src/watch.js:53:14)
at FSWatcher.emit (events.js:98:17)
at FSEvent.FSWatcher._handle.onchange (fs.js:1044:12)

今天早上一升级,模板编译后样式发生问题,请问为啥要强制升级呢?

<div class="search clx">

    <!---------点击时添加class的on属性-------->

      <div name="tripType" class="way">
        <p class="or"><%if(Model.PageCode == 1){ %>往返<%}else{ %>单程<%} %></p><i></i>
        <ul class="popadvse" style="width:130px;">
            <li code="0">单程</li>
            <li code="1">往返</li>
         </ul>
      </div>
      <input type="hidden" id="tripType" name="tripType" value="<%=Model.PageCode %>">

      <div class="dtation" method="city">
        <label for="text1">出发</label>
        <input type="text" id="iflightsrc" city="<%=Model.DepartureCityEn%>" code="<%=Model.DepartureCityCode %>"
        value="<%=Model.DepartureCityName %>(<%=Model.DepartureCityCode%>)">
      </div>
      <div class="dtation" method="city">
        <label for="text2">到达</label>
        <input type="text" id="iflightdest" city="<%=Model.ArriveCityEn %>" code="<%=Model.ArriveCityCode %>"
        value="<%=Model.ArriveCityName %>(<%=Model.ArriveCityCode %>)">
      </div>
      <div class="date" method="dt">
        <label for="text3">去程日期</label>
        <input type="text" id="dt" value="<%=Model.StartDate%>">
      </div>
      <div class="date" method="at" <%if(Model.PageCode == 0){ %>style="display: none"<%}%>>
        <label for="text3">回程日期</label>
        <input type="text" id="at" value="<%=Model.EndDate %>">
      </div>
      <div class="btn" method="search">搜 索</div>
       <div class="hbtn" method="extend"><i class='<%=Model.IsAdvance?"bot":""%>'></i>高级搜索</div>
        <div style="clear: right;display: none"></div>
<!----------高级搜索start------------>
      <div class="advse clx" method="direct" style=<%=Model.IsAdvance? "display:block":"display:none"%>>
        <form id="searchCondition" action=""><div class="direct clear">
          <p></p>
        </div>
        <input type="hidden" id="direct" name="direct" value="<%=Model.isDirect?1:0 %>">
        <%var cabins={ Y:"经济舱", F:"头等舱", C:"商务舱"} %>
        <!---------隐藏去掉下边class的on属性--------->
        <div name="classType" class="type">
          <p><i></i><span>舱位</span><b><%=cabins[Model.cabin==""?'Y':Model.cabin] %></b></p>
          <ul class="popadvse" style="width:150px;">
              <li code="Y">经济舱</li>
              <li code="C">商务舱</li>
              <li code="F">头等舱</li>        
          </ul>
        </div>
        <input type="hidden" id="classType" name="classType" value="<%=Model.cabin %>">

          <!---------隐藏去掉下边class的on属性--------->
          <%var atype =["成人","学生"] %>
        <div name="adultType" class="type">
          <p><i></i><span>乘客类型</span><b><%=atype[Model.atype] %></b></p>
          <ul class="popadvse" style="width:118px;">
            <li code="0">成人</li>
            <li code="1">学生</li>
          </ul>
        </div>
        <input type="hidden" id="adultType" name="adultType" value="<%=Model.atype %>">

        <!---------隐藏去掉下边class的on属性--------->
        <div name="psgCount" class="type num">
          <p><i></i><span>成人数</span><b><%=Model.psgCount %></b></p>
            <ul class="popadvse" style="width:50px;" method="adult">
                <li code="1">1</li>
                <li code="2">2</li>
                <li code="3">3</li>
                <li code="4">4</li>
                <li code="5">5</li>
                <li code="6">6</li>
                <li code="7">7</li>
                <li code="8">8</li>
                <li code="9">9</li>
            </ul>
        </div>
        <input id="psgCount" type="hidden" name="psgCount" value="<%=Model.psgCount %>">

        <!---------隐藏去掉下边class的on属性--------->
        <div id="childCount" class="type num">
          <p><i></i><span>儿童数</span><b><%=Model.chCount %></b></p>
          <ul class="popadvse" style="width:50px;"  method="child">
             <li code="0">0</li>
            <li code="1">1</li>
            <li code="2">2</li>
          </ul>
        </div>
        <input id="chCount" type="hidden" name="childCount" value="<%=Model.chCount %>">
        </form> 
    </div>
    <!----------高级搜索 end ------------>

</div>

<!----------------提示start------------------>
<% if (Model.EmergencyInfo != "")
    { %><div class="setip mt15" style="height: auto"><i></i><%= Model.EmergencyInfo %></div><% } %>
<!----------------提示 end ------------------>

<!----------------航班信息start------------------>
<div class="flnuminfor mt20">
    <h1><i></i><%=Model.DepartureCityName %><span class="<%if(Model.PageCode == 1){ %>round<%}else{ %>one<%} %>"></span><%=Model.ArriveCityName %>(<%=Model.PageType %>)</h1>    
    <%
    var date = new Date(Model.StartDate.replace(/-/g,'/')); 
    var backDate = new Date(Model.EndDate.replace(/-/g,'/'));
    %>
    <p class="date"><span><%=date.getMonth()+1%>月<%=date.getDate() %>日出发</span><%if(Model.PageCode==1){ %><span class="back"><%=backDate.getMonth()+1%>月<%=backDate.getDate() %>日返回</span><%} %> 共 <b id="fnum"></b>个航班</p>
    <p class="tip">所有航班起抵时间均为当地时间(24小时制)</p>
</div>
<!----------------航班信息 end ------------------>   

xx
错误的样式,搜索框没有闭合,把下面的元素包括进来了。

xx
升级前正确的样式

编译遇到了问题

例子当中 只使用了 include
希望能展示 简单语法和 辅助方法 的 使用案例
例如
{ if status==1 }
显示{ Math.ceil(count/20) }
{ /if }

可以提供单纯的编译后js么?不依赖seajs等加载器

先说明下原因:
require.js / seajs虽好,但不是所有项目都需要,尤其是mobile的项目,复杂度并不是很大,经实践后去seajs能少引起很多冲突问题,包括性能问题。

所以,希望作者能为这个不错的编译工具增加一个配置,好让生成的代码能够不用依赖加载器,更纯净,移植性更好。

多谢!

最新版预编译为CMD后,test中无法正确展示

环境:osx 10.9.2
nodejs:v0.10.26
tmodjs:0.1.1

进入tpl目录,修改package.json

{
    "name": "template",
    "version": "1.0.0",
    "dependencies": {
        "tmodjs": "~0.1.1"
    },
    "tmodjs-config": {
        "output": "./build",
        "charset": "utf-8",
        "syntax": "simple",
        "helpers": null,
        "escape": true,
        "engine": false,
        "type": "cmd",
        "alias": null,
        "minify": false
    }
}

打开seajs.html后,控制台输出:

Template Error

<id>
index

<name>
Render Error

<message>
No Template

需要修改seajs.html,增加'./tpl/build/index'才可以正常输出:

seajs.use(['./tpl/build/template', './tpl/build/index'], function (template) {
    document.getElementById('doc').innerHTML = template('index', data);
});

安装tmodjs报错

执行npm install -g tmodjs时,报如下错误:
.......
267 verbose .......\AppData\Roaming\npm,[object Object] binRoot
268 info postuninstall [email protected]
269 error Error: version not found: [email protected]
269 error at ......\nodejs\node_modules\npm\lib\cache.js:846:12
269 error at saved (......\nodejs\node_modules\npm\node_modules\npm-registry-client\lib\get.js:148:7)
269 error at .......\nodejs\node_modules\npm\node_modules\graceful-fs\polyfills.js:133:7
269 error at Object.oncomplete (fs.js:107:15)
270 error If you need help, you may report this entire log,
.......

加上版本号,执行npm install -g [email protected],可以正常安装。

编译遇到了问题 #2

你误解我的意思了,我是说 将模版 用 cmd工具 编译的时候遇到了问题。

  1. 手册中写的是 将 template.js与 template-syntax.js合并。
    不知道该如何合并,合并后运行cmd工具 总出错,
  2. 手册中对于辅助方法说 通过 template.helper('Math',Math);来使用。
    运行 cmd工具后 通过 seajs例子代码运行 出错。

希望提供 atc windows版本的 完全 使用案例,
我了解并在项目上 以在线编译的方式 使用过 artTemplate。

tmodjs预编译问题

使用tmodjs预编译html模板成js文件,编译出来的页面代码如下:
image

在页面当中运行代码的时候 页面如下图:
image

请问出现这种情况是怎么回事?我编译为amd模式的

tmodjs 开发计划

  1. 支持配置.tmodignore,排除文件 #21
  2. 支持 GBK2312 编码 #32
  3. combo支持自定义打包合并模板 #36
  4. .cache文件夹优化 #35
  5. 内部技术优化,处理 windows 路径分隔符 #10
  6. 支持使用后缀名作为模板路径(需要改动 artTemplate)
  7. 进一步改善压缩率
  8. 让运行时文件也遵循type的设置

在提个关于type的 issue

我使用default的时候,
生成的template.js最后也会有这样一段
"function"==typeof define?define(function(){return b}):"undefined"!=typeof exports?module.exports=b:this.template=b}();
但是 实时我期望的是default就是个普通的JS。

使用场景是 我虽然使用了amd、cmd、或者其他md,但不希望这个template.js作为amd模块来使用,只是希望他是个JS,但这样使用 因为有defind的全局函数,就没法让template函数变成全局函数。结果导致我没法使用

mac下无法监听编译

在mac终端输入atc -w html/ -o tpls/后启动watch。。。
但保存后没有自动编译呢。
自己在虚拟机的win7下是好的。
:(

收集 TmodJS 的用户

您若在项目中使用 TmodJS,欢迎在本页留下公司或项目的信息,收集后我们将展示在 TmodJS 未来的官方网站中,例如:

微博:[@xxx](http://weibo.com/xxx)
公司:[xxx](http://www.xxx.com)
项目:XXX

感谢您对开源项目的支持!

(注:登记完毕将删除留言)

关于预编译之后的模板

我是在写一个独立的组件中使用到tmodjs的,预编译了模板,希望他能够完全独立不依赖任何的组件和lib,实际上这非常棒。但是当我在写另外一个组件中同样使用了tmodjs时问题就来了,两个组件中的模板我都进行了预编译,并且分别把模板和组件的逻辑代码最终合成了一个js,plugin-a.js,plugin-b.js。

这个时候问题来了,当我在项目中同时引用这两个文件的时候,他们各自的预编译模板定义的一些方法存在了冲突,我想说是不是可以加一个命名空间的选项?因为之前一直都很完美,这个冲突是否可以避免。

怎样导入配制文件

package.json 文件是运行 tomdjs 命令生成的,改了不生效。要怎样才能让配制文件生效?

helpers 输出方案

因为模板会依赖辅助方法,编译器需要把它们单独输出,这时候需要一个toSource方法用于把源码从内存中输出。

toSource源码:

var getType = function (obj) {
    var toString = Object.prototype.toString;
    return obj === null
    ? "Null" : obj === undefined
    ? "Undefined" : toString.call(obj).slice(8, -1);
};

var toSource = function (obj) {
    var type = getType(obj);
    var string = '';
    var temp;

    switch (type) {
        case 'Object':

            temp = [];

            for (var name in obj) {
                temp.push(
                    JSON.stringify(name) + ':' + toSource(obj[name])
                );
            }

            string =  '{' + temp.join(',') + '}';

            break;
        case 'Array':
            temp = [];
            var length = obj.length;

            while (length) {
                temp[--length] = toSource(obj[length]);
            }

            string = '[' + temp.join(',') + ']';

            break;
        case 'String':
            string = JSON.stringify(obj);
            break;
        case 'Undefined':
            string = 'undefined';
            break;
        case 'Boolean':
        case 'Number':
        case 'Null':
            string = obj + '';
            break;
        case 'Function':

            temp = obj
            .toString()
            .match(/^function\s*(\w+)\s*\(\)\s*\{\s*\[native\s*code\]\s*\}$/);

            if (temp) {
                string = temp[1];
            } else {
                string = obj + '';
            }

            break;
        // Namespace
        default:
            string = type;
    }

    return string;
};

使用toSource方案输出辅助方法并不是很靠谱,虽然我已经对系统内置的方法与对象进行了判断,甚至比 firefox 自带的toSource更完善,但仍然会有很大的风险,如闭包就无法处理。

新方案

让 helpers 以配置文件的方式存在,用户可以编辑它,模板编译的时候直接读取后输出它。

再提个自定义合并的ISSUE

嘿嘿 真正使用起来 需求有点多 不好意思哈

因为页面有N个,每个页面调用的模板不一样,那如果把所有模板放到一个TEMPLATE.JS里,这个JS显得太大,是否可以提供一种定制方法
如在PACKAGE.JS里
output: {
page1:['模板1','模板2','模板3','模板4'],
page2:['模板1','模板4'],
page3:['模板2','模板4']
}
来自定义各种场景的输出。然后输出的文件为page1.js page2.js page3.js
希望能考虑下此功能,

提一个关于package.json的问题

运行TMOD时自动生成PACKAGE.JSON确实挺方便
我对.JSON文件进行了修改,后面便可直接执行TMODJS便会按这个文件的规则执行

但问题是,我一旦模板出错,他会重新用默认的规则覆盖.JSON文件,结果我不知不觉中PACKAGE.JSON就被改回去了~~~~

对于逻辑运算符与||的处理

简洁语法中,对于逻辑运算符与||会被解析成管道标记而当成辅助方法,如

{{ hasClass || hasData ? 'abc' :'def' }}

tmod编译的时候会报错

为什么无法安装了?

C:\Windows\system32>npm install template-compiler -g
npm http GET https://registry.npmjs.org/template-compiler
npm http 304 https://registry.npmjs.org/template-compiler
C:\Users\Administrator\AppData\Roaming\npm\atc -> C:\Users\Administrator\AppData
\Roaming\npm\node_modules\template-compiler\compiler.js
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] 'repositories' (plural) Not supported
.
npm WARN package.json Please pick one as the 'repository' field
npm WARN package.json [email protected] No repository field.
[email protected] C:\Users\Administrator\AppData\Roaming\npm\node_modules
template-compiler

请问下是怎么回事呢?~~~~(>_<)~~~~

tmod命令编译模板后, 只输出单纯的字符串

tmpl/modal.html文件

<div id="modal">
    <span class="cover">
        <%= test %>
    </span>
</div>

执行 tmod命令

tmod ./tmpl --output amd

使用时

require(['modal'], function(modal){
    console.log(modal);
})

此处 modal只是单纯的字符串, 没有render等方法. 如果不输出成amd模式, 即使使用default模式, 将所有的模板文件全部编译到template.js中, 也依然是 单纯的字符串. 和直接拷贝字符串没有区别, 这样就失去了使用模板的意义了

当我把编译后的文件依赖的那个template模块换成 artTemplate的整个文件就运行正常了.

不知道是我使用的方法不对,还是需要别的什么东西? 请指教

helper函数只能返回字符串吗?

本来想用helper函数对data里的某些数据做些处理,返回一个可以在模板中用的数组,但测试不成功,会报错,如果改为return 一个字符串,则没有问题,所以,请问:helper函数只能返回字符串吗?3Q~

windows监听编译路径出错

按照步骤安装了tmod,然后下载了例子执行tmod ./test/tpl 然后监听状态下修改test/tpl/index.html报错
fs.js:684
return binding.stat(pathModule._makeLong(path));
^
Error: ENOENT, no such file or directory 'D:\MyProject\tmodjs\index.html'
at Object.fs.statSync (fs.js:684:18)
at EventEmitter.Tmod.filter (C:\Users\linweijian\AppData\Roaming\npm\node_mo
dules\tmodjs\src\tmod.js:387:23)
at EventEmitter. (C:\Users\linweijian\AppData\Roaming\npm\node_mo
dules\tmodjs\src\tmod.js:83:29)
at FSWatcher. (C:\Users\linweijian\AppData\Roaming\npm\node_modul
es\tmodjs\src\watch.js:47:14)
at FSWatcher.EventEmitter.emit (events.js:98:17)
at FSEvent.FSWatcher._handle.onchange (fs.js:1039:12)

事实上,文件应该是在D:\MyProject\tmodjs\test\tpl\index.html...不知道为啥路径就是错了,还有我改public里面的文件竟然没有监听到。

windows下无法使用....

Error: Cannot find module 'source-map'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object. (C:\Users\Administrator\AppData\Roaming\npm\node_modul
es\tmodjs\lib\UglifyJS\tools\node.js:9:21)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)

如何排除一些文件

tmodjs 在使用的时候,的确带来了很大的便利 但同样也出现了一些问题希望能够得到解决
例如 我在写页里的时候。有些页面或者文件夹只是做测试使用。并不想让其编译到templatejs里。因为那样会增大文件[影响速度当文件多的时候???]。
当然按Doc 上说的 可以取消掉合并combo:false 按需要的使用 但文件还是会编译到build 文件下面。而我只想要一些自己需要编译的文件 如何做呢。
可否提供一个配置 exclude 用来控制不需要的编译的文件 呢。

一修改packagejson,再编译就报错,版本1.01-rc2

undefined:1
锘縶
^
SyntaxError: Unexpected token 锘?
at Object.parse (native)
at EventEmitter.Tmod.getConfig (C:\Users\Administrator\AppData\Roaming\npm\n
ode_modules\tmodjs\src\tmod.js:209:29)
at EventEmitter.Tmod (C:\Users\Administrator\AppData\Roaming\npm\node_module
s\tmodjs\src\tmod.js:49:35)
at Object. (C:\Users\Administrator\AppData\Roaming\npm\node_modul
es\tmodjs\bin\tmod:179:14)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)

我想输出文档到其他目录,修改就报错,是不是文件编码的问题

Nodejs path 模块返回值 Mac OSX 与 Windows 兼容方案

Mac OS X 与 Windows 使用 NodeJS path 模块返回的字符串并不一致,它只会根据系统的规范返回路径分割符号,如 Mac OS X 是/,Windows 是\ 。这种差异将导致不同平台编译后的模板 id 不一致,由于 path 方法在模板编译器中被大量使用,手工替换麻烦,直接对 path 改造一番来的更彻底。

var path = require('path');

(function () {

    if (!/\\/.test(path.resolve())) {
        return path;
    }

    var oldPath = path;
    var newPath = Object.create(oldPath);
    var proxy = function (name) {
        return function () {
            var value = oldPath[name].apply(oldPath, arguments);
            if (typeof value === 'string') {
                value = value.split(oldPath.sep).join('/');
            }
            return value;
        }
    };

    for (var name in newPath) {
        if (typeof oldPath[name] === 'function') {
            newPath[name] = proxy(name);
        }
    };

    path = newPath;
})();

使用atc编译器时,如何自行配置模版引擎

使用编译器时,参数不太够,比如没有办法自定义开始和结束标签!这个很重要啊,能不能加上?
或者,可以增加一个用于用户初始化引擎的js文件路径参数,然后在编译器中调用这个js文件中的初始化函数,给用户传入template对象,让用户自己配置。

模板中使用window对象的方法

若模板中使用window的方法,{{Math.round(10)}},tmod编译后的js中会把Math=$data.Math,造成Math被覆盖,建议把window的全局对象重新挂载到$data中

关于打包模块 自定义

有这样一个场景,目前tmodjs的打包规则是 接照amd ,cmd 类似seajs,requirejs的 define形式进行打包的,
如下: https://github.com/aui/artTemplate/blob/master/src/outro.js

// RequireJS && SeaJS
if (typeof define === 'function') {
    define(function() {
        return template;
    });

// NodeJS
} else if (typeof exports !== 'undefined') {
    module.exports = template;
} else {
    this.template = template;
}

})();

这样打包,少了很多的适用性,因为有些加载器上的define规则 不是这个样式,这样就没办法适用了,

如下;

// RequireJS && SeaJS
if (typeof define === 'function') {
    define("想在此处会有一些名称",['template'],function(template) {
        return template;
    });

// NodeJS
} else if (typeof exports !== 'undefined') {
    module.exports = template;
} else {
    this.template = template;
}

})();

不知道 怎么样可以做到这样的需要求,

我看了一下 tmodjs的源码,发现支持 cmd,amd,default,的那段https://github.com/aui/tmodjs/blob/master/src/AOTcompile.js#L82
我自己加了一条规则 重写了一下,但是最后发现,define的地方,还是需要修改。觉得这个地方需要在grunt或者什么地方去配置。将配置的信息加到根据需要编译文件名字来定,
define('static/js/a',['template'], function(){})

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.