
用 DUEL 双端模板引擎构建 TodoMVC从 Maven 构建、客户端 DOM 渲染到 Tomcat 调试运行【免费下载链接】todomvcHelping you select a JavaScript framework - Todo apps for React.js, Angular, Vue and many more项目地址: https://gitcode.com/gh_mirrors/to/todomvc本指南以 TodoMVC 仓库中的 DUEL 示例examples/duel为核心系统讲解 DUELDuel-Sided Templating Engine双端模板引擎的核心思想、工程结构、构建流程与运行方式。读完本文你将掌握DUEL 如何用一份 HTML 模板同时生成客户端 JavaScript 与服务端 Java 视图、如何在纯 JavaScript 中把编译后的视图渲染为 DOM 对象以及如何使用 Maven 完成静态应用构建并用 Tomcat 7 进行可调试运行。DUEL 是什么一个双端模板引擎根据示例文档examples/duel/readme.md的官方定义DUEL 是一个双端模板引擎使用 HTML 作为布局语言、100% 纯 JavaScript 作为绑定语言。同一份视图既可以直接在浏览器中执行客户端模板也可以在服务端执行服务端模板。这一设计带来两个关键特性单份模板、双端复用视图以 HTML 标记markup书写随后被预编译precompiled为 JavaScript客户端模板和 Java服务端模板两套产物避免为浏览器与服务端各写一套视图代码渲染形态灵活客户端模板被编译成纯 JavaScript 函数执行结果既可以渲染为文本标记text markup也可以渲染为 DOM 对象DOM objects。本示例采用后者——toDOM()直接产出 DOM 节点并插入页面。以 TodoMVC 项目而言这意味着新增任务、切换过滤、编辑任务等所有交互都发生在浏览器端服务端视图仅作为调试辅助手段存在详见下文构建一节。工程结构一览DUEL 示例的目录组织如下均相对于仓库根目录examples/duel/ ├── pom.xml # Maven 构建配置DUEL 编译、合并、静态应用插件 ├── staticapp.json # 静态应用生成配置 ├── package.json # npm 脚本拉取 TodoMVC 公共 CSS/JS 到 webapp ├── readme.md # 示例说明文档 └── src/main/webapp/ ├── WEB-INF/web.xml # 部署描述符RoutingServlet 路由配置 ├── css/ │ ├── base.css # TodoMVC 基础样式 │ ├── index.css │ └── styles.merge # CSS 合并清单 └── js/ ├── lib/ │ ├── duel.js # DUEL 客户端运行时 │ └── todos.js # TodoMVC 公共基础脚本 ├── todos/ │ ├── model.js # 数据模型localStorage 存储 │ └── controller.js # 控制器事件处理与视图刷新 └── scripts.merge # JS 合并清单其中www/目录examples/duel/www存放的是 Maven 构建后生成的静态应用产物index.html与带哈希指纹的 CDN 资源都在其中目录下还保留了src/main/webapp/js/todos/下的模型与控制器源码作为理解渲染链路的第一手材料。模板如何被编译duel-maven-pluginDUEL 视图的编译发生在 Maven 构建阶段由 examples/duel/pom.xml 中的duel-maven-plugin负责plugin groupIdorg.duelengine/groupId artifactIdduel-maven-plugin/artifactId version${duel.version}/version !-- 0.9.7 -- executions execution goals goalgenerate/goal /goals configuration clientPrefix${duel.clientPrefix}/clientPrefix serverPrefix${duel.serverPrefix}/serverPrefix inputDir${duel.sourceDir}/inputDir outputClientPath${duel.clientPath}/outputClientPath /configuration /execution /executions /plugin对应的属性定义在pom.xml的properties中是理解编译产物的关键属性默认值本示例含义duel.clientPrefixtodos.views客户端编译产物的命名空间前缀duel.serverPrefixcom.todomvc.duel.views服务端 Java 产物的包名前缀duel.sourceDir${project.basedir}/src/main/resources/views/DUEL 视图源码.duel文件所在目录duel.clientPath/js/客户端 JS 产物输出路径该插件的generate目标会读取src/main/resources/views/下的 DUEL 视图源码生成两类产物客户端 JS 模板输出到outputClientPath即/js/生成后的视图命名空间为todos.views服务端 Java 模板生成到target/generated-sources/duel/目录——这正是示例文档中服务端模板仅用于调试所指的产物位置。此外pom.xml的resources配置中通过exclude**/*.duel/exclude将 DUEL 视图源码从 WAR 的目标输出中排除说明视图源码只是构建期输入不会被打包进最终应用。从 src/main/webapp/js/scripts.merge 这份合并清单可以直观看到编译产物的形状# compiled views /js/todos/views/Stats.js /js/todos/views/Task.js /js/todos/views/Tasks.js /js/todos/views/TodoApp.js也就是说本示例的四个视图统计栏Stats、单条任务Task、任务列表Tasks、整体应用TodoApp在构建期被编译为todos.views命名空间下的四个 JS 模块随后由 merge 插件打包进最终静态资源。客户端渲染在纯 JavaScript 中调用编译视图DUEL 的客户端模板编译产物是一个个 JavaScript 函数调用它们即可得到渲染结果。本示例的渲染入口在 src/main/webapp/js/todos/controller.js 的refreshView()中function refreshView() { // get the data var data todos.model.viewData(curFilter()); // build the view var view todos.views.TodoApp(data).toDOM(); var old find(.todoapp); if (old) { // replace old task list old.parentNode.replaceChild(view, old); } else { // insert at top document.body.insertBefore(view, document.body.firstChild); } find(.new-todo).focus(); }这条调用链清晰体现了双端模板的客户端形态取数todos.model.viewData(curFilter())根据当前 URL hash 过滤all/active/completed得到视图数据渲染todos.views.TodoApp(data).toDOM()调用编译好的客户端模板函数并以toDOM()方式产出 DOM 对象——对应示例文档中本示例为视图生成 DOM 对象的说明挂载通过replaceChild或insertBefore将新 DOM 替换/插入页面属于典型的全量重渲染式交互。视图刷新由穷人版路由驱动addEventListener(hashchange, refreshView, false)监听 URL hash 变化切换过滤条件即触发重渲染。数据层位于 src/main/webapp/js/todos/model.js以localStoragekey 为todos-duel作为持久化存储提供add、edit、toggle、toggleAll、remove、expunge等操作并通过viewData(filter)返回视图所需的{ tasks, stats }数据结构。事件处理器则集中导出为todos.actions覆盖回车新增ENTER_KEY、双击编辑、Esc 取消、勾选完成、清除已完成等 TodoMVC 标准交互。构建静态应用merge 与 staticapps 插件除 DUEL 编译外mvn clean package还会依次执行另外两个 DUEL 生态插件把应用收敛为纯静态站点。merge-maven-plugin资源合并与 CDN 指纹该插件读取 src/main/webapp/js/scripts.merge 与 src/main/webapp/css/styles.merge 两份清单将列表中的 JS/CSS 依次合并并依据内容生成带哈希的文件名CDN 指纹。pom.xml中相关配置merge.cdnMapFile/cdn.properties/merge.cdnMapFile merge.cdnRoot/cdn//merge.cdnRoot merge.cdnFiles.ico .png .jpg .gif .cur .eot .woff .ttf .svg .svgz/merge.cdnFiles即合并产物输出到/cdn/根下cdn.properties记录原路径 → 哈希文件名的映射字体图标等二进制资源同样纳入 CDN 处理。构建后的 examples/duel/www 目录中cdn/3aba0c24...js、cdn/b12c1274...css即为带内容哈希的合并产物。duel-staticapps-maven-plugin生成静态应用duel-staticapps-maven-plugin依据 examples/duel/staticapp.json 生成最终静态站点{ targetDir: www/, sourceDir: target/todomvc/, serverPrefix : com.todomvc.duel.views, cdnMap: cdn, cdnLinksMap: cdnLinks, cdnHost: ./, isDevMode: false, views: { index.html: { view: HomePage, data: {}, extras: {} } }, files: [robots.txt, favicon.ico] }关键配置项说明targetDir/sourceDir输出目录与输入 WAR 目录views.index.html.view指定首页由名为HomePage的服务端视图渲染此时data为空对象即服务端不注入业务数据渲染结果只做页面骨架这正是服务端模板仅用于调试的体现cdnHost: ./CDN 资源使用相对路径引用便于静态托管isDevMode: false关闭开发模式产出最终优化产物。生成后的 examples/duel/www/index.html 即为最终静态页面引用带哈希的 CSS/JS 文件页面主体由浏览器端编译视图渲染印证了客户端模板负责全部交互渲染的架构。运行与调试Tomcat 7前置条件示例文档明确要求Apache Maven 3作为构建工具本示例使用 Maven 管理构建生命周期与插件示例本身同时是一个 Maven Web 项目pom.xml中packagingwar/packaging依赖duel-runtime、duel-staticapps与slf4j-jdk14三个运行时库。标准构建在包含pom.xml的目录即examples/duel/执行mvn clean packageMaven 将自动下载依赖、清理先前构建产物并依次执行 DUEL 编译、资源合并、静态应用生成三个插件目标最终在www/目录产出静态应用。可调试运行若希望在开发期获得可调试的版本使用 Tomcat 7 作为 Web 服务器mvn tomcat7:run随后在浏览器中访问 http://localhost:8080/ 即可。pom.xml中tomcat7-maven-plugin版本 2.2的配置为应用路径/、端口8080、UTF-8 URI 编码并将target/todomvc/作为 WAR 源码目录加载。该模式跑的是完整 WAR包含 RoutingServlet 路由与静态资源因此也覆盖了服务端模板的调试场景。服务端路由配置src/main/webapp/WEB-INF/web.xml 将根路径/映射到org.duelengine.duel.staticapps.RoutingServlet并传入config-pathstaticapp.json与dev-mode-overridetrue两个初始化参数——前者指明静态应用配置来源后者允许以开发模式覆盖staticapp.json中的isDevMode设置方便调试时即时反映改动。小结DUEL 的一份视图双端执行回顾整个示例DUEL 的工程形态可概括为一条编译流水线编写以 HTML 纯 JavaScript 绑定语言书写.duel视图编译duel-maven-plugin同时产出客户端 JS 模板todos.views.*与服务端 Java 模板com.todomvc.duel.views落入target/generated-sources/duel/仅用于调试合并merge-maven-plugin按scripts.merge/styles.merge清单生成带哈希指纹的 CDN 资源生成duel-staticapps-maven-plugin依据staticapp.json渲染首页并输出纯静态www/运行浏览器中客户端模板以toDOM()直接渲染 DOM配合hashchange路由与 localStorage 模型完成全部 TodoMVC 交互开发期可借助mvn tomcat7:run在localhost:8080上做可调试运行。对于想深入研究的读者可从以下仓库路径继续探索构建配置见 examples/duel/pom.xml静态应用配置见 examples/duel/staticapp.json渲染入口与数据模型见 controller.js 与 model.js最终产物见 examples/duel/www/index.html。该示例由 Stephen McKamey 基于 DUEL 引擎移植与仓库中其他框架示例React、Angular、Vue 等共同构成 TodoMVC 的框架对比矩阵。【免费下载链接】todomvcHelping you select a JavaScript framework - Todo apps for React.js, Angular, Vue and many more项目地址: https://gitcode.com/gh_mirrors/to/todomvc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考