3. 将集成dom挂载的Velocity页面的Vue模板文件index.html传递给Vue。
现在,到了这个地步,我们就需要超越理论层面,考虑如何去实现上面的三个步骤。后续步骤取决于先前步骤的工件,因此我们按顺序实现它们。
现在考虑第二个问题。速度渲染引擎需要哪些功能?
根据第一步的描述,引擎需要在前端本地编译并运行速度模板页面并支持渲染模拟数据。
总结起来有两点:1.渲染速度2.Mock数据支持。
目前,本地渲染速度的主要方式是在本地运行一组Java 服务。然而现在的需求开发伙伴对Java了解不多,有些配置项对我们来说比较复杂。嗯,这条路不适合我们。换个角度思考,Java 可以运行服务,但是JS 不能吗?答案是显而易见的。是的,nodejs。我们对Java不是很熟悉,但是对nodejs却很熟悉。
经过一番研究,我发现nodejs有一个类似于Java Velocity的模板引擎,可以运行Velocity模板并支持mock数据。接下来,尝试将引擎集成到您的项目中。
连接到引擎时可以尝试以下两种方法:
方法一:在Vue运行入口文件index.js之前启动Node服务,并使用Node服务引擎提供的compile和run方法加载velocity模板页面供后续使用。
方法二:在webpack的loader中编写引擎,用webpack的执行逻辑编译Velocity。
如果你知道本地运行Vue 时每个页面加载的顺序,你就可以看到方法1 的问题。我们来一一实现,看看问题出在哪里。
行业现状:
以下代码是本地调试时临时编写的,仅用于帮助大家理解思路。这没有帮助。核心代码已注释掉。
step1: 转换vue入口文件index.js
//setup启动node服务,编译Velocity,并在指定文件夹生成HTML文件import ‘./setup’; //Entry是原来的vue Index.js入口文件的内容import ‘./entry’;实现安装程序.js
import Axios from ‘axios’; //该方法向本地启动的Node服务发送请求,告诉Node服务需要重新编译模板(()={ new Promise((resolve,accept)={ axios.get (‘initdom’) .then(()={solve(); }) .catch((err)={reject(err); }); });})() ;step3: 实现节点服务
//node服务会在本地手动启动//现在需要全局安装velocityjs包,以便后续命令执行const http=require(‘http’);const fs=require(‘fs’);const { exec }=require ( ‘child_process’);const 主机名=’127.0.0.1′;const 端口=3000;const server=http.createServer((req, res)={ if (req.url===’/initdom’) { res . statusCode=200; res.setHeader(‘Content-Type’, ‘text/plain’); //该命令运行Velocity 模板页面并将HTML 写入执行目录。 /index.vm) ‘, {coding: ‘utf-8’ }, (error, stdout, stderr)={ if (error) { console.error(error ); } if (stderr) { console.error(stderr) } const isExist=fs;existsSync(‘模板文件地址’); if (isExist) { console.log(‘文件存在’); fs.writeFileSync(‘生成HTML 文件地址’); stdout); console.log(‘文件被重写’); //成功生成HTML 文件后,后续逻辑res.end(‘成功’); } else { console.log(‘URL 错误!’); }});server.listen(端口, 主机名, ()={ console.log(`服务器在http://上运行) ${主机名}:$ {端口}/`);});step4:本地启动node服务和vue项目
//启动节点服务。启动node.js //vuenpm run dev。至此,项目启动之后,方法的整个流程就已经实现了,但是上面的问题出在哪里呢?大家知道,日常本地开发中一个非常重要的需求就是热更新。当我尝试更改模拟数据时,生成的HTML 文件中的模拟数据确实发生了更改,但我必须刷新浏览器两次才能将其反映在页面上,但热更新并没有反映已完成的更改。您将无法获得完整的效果。
问题是,由于Vue 加载HTML 文件的速度比生成HTML 文件的速度快,那么是否可以细化生成HTML 文件的逻辑呢?从方法一来看,这显然是不可能的,因为方法一需要你在本地启动节点服务,并请求一个接口来启动服务。这非常简单,所以请考虑另一种方法。
我知道webpack 提供了一种自定义加载器的机制,允许我创建预处理指定文件的加载器。
vue cli 支持通过Webpack 链添加新的加载器。
我们回顾一下方法1遇到的问题,并尝试使用webpack加载器来实现。
方法2具体实现:
下图是整体流程图。
在实现方法2之前,我们先考虑另一个问题。随着项目随着时间的迭代,Velocity模板文件可能会被分割,同时一些外部文件也需要插入到最终的HTML文件中,代码也会随着时间的推移而被分割。未来还会升级。幸运的是,Velocity 提供了#parse 和#include 功能,可以让你使用脚本和API 接口实现Velocity+vue 的单文件组件化模式。
下图显示了该文件的基本结构。
基于这个结构,我们将构建一个前端沙箱环境,并将模拟服务器数据保存到本地JSON文件。接下来,我们将解析Velocity 模板并将其嵌入到Webpack 加载器中,开发一个Velocity-Loader 引擎来解析文件。将mock数据实时注入到模板中,解决了方法1遇到的热更新问题。如下所示。
下面贴出实现方法2相关的代码。
step1: 配置Webpack链
config.module.rule(‘velocity’) //只处理以.vm.test(/.vm$/) 结尾的文件.exclude.add(/node_modules/).end() .use(‘html-loader’) .loader(‘html-loader’) .end() .use(‘velocity-loader’) .loader(path.resolve(__dirname, ‘./v-loader.js’)) .options({basePath: path.join ) (__dirname, ‘src’), });step2: 实现速度加载引擎
这里我们只写一些核心代码。其他代码是其他配置项,与本文关系不大。
module.exports=function (content) { const callback=this.async(); const filePath=path.dirname(filePath); //此处使用模拟文件名用于说明目的,实际配置即可。 const mockPath=path.join(fileDirPath, ‘mock.js’); //检查模拟文件是否存在并监视它是否存在。实现热更新if (fs .existsSync(mockPath)) { watcher(mockPath); delete require.cache[mockPath]; //eslint-disable-next-line global-require Mouth=require(mockPath);编译以解析速度模板content=new Compile(parse(content), {escape : false, }).render(mock, Macros(filePath, {}, Mouck)); //用于下一步将HTML 内容返回到webpack。 processcallback(null, content);}; 至此,velocity模板本地编译执行的问题已经解决,并且还实现了mock数据和热更新,在不增加维护成本的情况下提高了开发效率和开发体验改进了。五
总结
事实上,本地编译运行Velocity的解决方案有很多,但大多数都已经成熟,我们要么直接使用现有的解决方案,要么没有遇到过这样的情况。写这篇文章的目的也是为了帮助自己解决这个问题。描述并总结问题。
参考
[1] Velocity官网:https://velocity.apache.org/
[2] Velocityjs官网: https://github.com/shepherdwind/velocity.js
[3] webpack官网:https://www.webpackjs.com/loaders/
[4]Vue官网:https://cli.vuejs.org/zh/guide/webpack.html
关于作者
雷明生:LBG-FE
来源:微信公众号:58科技
来源:https://mp.weixin.qq.com/s/LqBf6H-6o88tMfl59IRPbw
原创文章,作者:小条,如若转载,请注明出处:https://www.sudun.com/ask/85708.html