当前位置: 首页 > news >正文

单仁做的网站网站管理建设需进一步加强

单仁做的网站,网站管理建设需进一步加强,嵌入式软件开发平台有哪些,选课网站开发目录 开始 插件编写 功能一 功能二 功能三 合并功能 运行代码 总结 这篇文章主要讲如何根据注释#xff0c;通过babel插件自动地#xff0c;给相应函数插入埋点代码#xff0c;在实现埋点逻辑和业务逻辑分离的基础上#xff0c;配置更加灵活 这篇文章想要达到的效…目录 开始 插件编写 功能一 功能二 功能三 合并功能 运行代码 总结 这篇文章主要讲如何根据注释通过babel插件自动地给相应函数插入埋点代码在实现埋点逻辑和业务逻辑分离的基础上配置更加灵活 这篇文章想要达到的效果 源代码 //##箭头函数 //_tracker const test1  ()  {};const test1_2  ()  {};转译之后 import _tracker from tracker; //##箭头函数 //_tracker const test1  ()  {_tracker(); };const test1_2  ()  {};代码中有两个函数其中一个//_tracker的注释另一个没有。转译之后只给有注释的函数添加埋点函数。 要达到这个效果就需要读取函数上面的注释如果注释中有//_tracker我们就给函数添加埋点。这样做避免了僵硬的给每个函数都添加埋点的情况让埋点更加灵活。 下面让我们来看看怎么做 开始 准备babel入口文件index.js const { transformFileSync }  require(babel/core); const path  require(path); const tracker  require(./babel-plugin-tracker-comment.js);const pathFile  path.resolve(__dirname, ./sourceCode.js);//transform ast and generate code const { code }  transformFileSync(pathFile, {plugins: [[tracker, { trackerPath: tracker, commentsTrack: _tracker }]], });console.log(code); 这里我们使用transformFileSyncAPI转译源代码并将转译之后的代码打印出来。过程中将手写的插件作为参数传入plugins: [[tracker, { trackerPath: tracker, commentsTrack: _tracker}]]。除此之外还有插件的参数 trackerPath表示埋点函数的路径插件在插入埋点函数之前会检查是否已经引入了该函数如果没有引入就需要额外引入。 commentsTrack标识埋点如果函数前的注释有这个就说明函数需要埋点。判断的标识是动态传入的这样比较灵活 入口文件准备好了接下来准备下源代码文件sourceCode.js import ./index.css;//##箭头函数 //_tracker const test1  ()  {};const test1_2  ()  {};//函数表达式 //_tracker const test2  function () {};const test2_1  function () {};// 函数声明 //_tracker function test3() {}function test3_1() {}这里准备了三种不同的函数类型并且各个函数类型都有一个加了注释另一个没加作为参照对象 就差插件了下面写插件代码babel-plugin-tracker-comment.js 插件编写 功能一 功能实现过程中涉及到了读取函数的注释并且判断注释中是否有//_tracker const leadingComments  path.get(leadingComments); const paramCommentPath  hasTrackerComments(leadingComments, options.commentsTrack);//函数实现 const hasTrackerComments  (leadingComments, comments)  {if (!leadingComments) {return null;}if (Array.isArray(leadingComments)) {const res  leadingComments.filter((item)  {return item.node.value.includes(comments);});return res[0] || null;}return null; };具体函数实现接收函数前的注释注释可能会有多个所以需要一一判断。还接受埋点的标识。如果找到了含有注释标识的注释就将这行注释返回。否则一律返回null表示这个函数不需要埋点 那什么是多个注释 这个很好理解我们看下AST explorer[2]就知道了 a函数前面有4个注释三个行注释一个块注释。 其对应的AST解析是这样的 AST对象中用leadingComments表示前面的注释用trailingComments表示后面的注释。leadingComments中确实有4个注释并且三个行注释一个块注释和代码对应上了。 函数要做的就是将其中含有//_tracker的comment path对象找出来 功能二 判断函数确实需要埋点之后就要开始插入埋点函数了。但在这之前还需要做一件事就是检查埋点函数是否引入如果没有引入就需要额外引入了 const { addDefault }  require(babel/helper-module-imports);if (paramCommentPath) {//add Importconst programPath  path.hub.file.path;const importId  checkImport(programPath, options.trackerPath);state.importTackerId  importId; }//函数实现 const checkImport  (programPath, trackPath)  {let importTrackerId  ;programPath.traverse({ImportDeclaration(path) {const sourceValue  path.get(source).node.value;if (sourceValue  trackPath) {const specifiers  path.get(specifiers.0);importTrackerId  specifiers.get(local).toString();path.stop();}},});if (!importTrackerId) {importTrackerId  addDefault(programPath, trackPath, {nameHint: programPath.scope.generateUid(tracker),}).name;}return importTrackerId; };拿到import语句需要program节点。checkImport函数的实现就是在当前文件中找出埋点函数的引入。寻找的过程中用到了引入插件时传入的参数trackerPath。还用到了traverseAPI用来遍历import语句。 如果找到了引入就获取引入的变量。这个变量在之后埋点的时候需要。即如果引入的变量命名了tracker2那么埋点的时候埋点函数就是tracker2了 如果没有引入就插入引入。 addDefault就是引入path的函数并且会返回插入引用的变量。 功能三 确定好了函数需要埋点并且确定了埋点函数引入的变量接下来就插入函数了。 if (paramCommentPath) {//add Importconst programPath  path.hub.file.path;const importId  checkImport(programPath, options.trackerPath);state.importTackerId  importId;insertTracker(path, state); } const insertTracker  (path, state)  {const bodyPath  path.get(body);if (bodyPath.isBlockStatement()) {const ast  template.statement(${state.importTackerId}();)();bodyPath.node.body.unshift(ast);} else {const ast  template.statement({${state.importTackerId}();return BODY;})({ BODY: bodyPath.node });bodyPath.replaceWith(ast);} };在生成埋点函数的时候就用到了之前获取到的埋点函数的变量importTackerId。还有在实际插入的时候要区分函数体是一个Block还是直接返回的值--() 合并功能 三个功能都写好了接下来将三个功能合起来就是我们的插件代码了 const { declare }  require(babel/helper-plugin-utils); const { addDefault }  require(babel/helper-module-imports); const { template }  require(babel/core);//get comments path from leadingComments const hasTrackerComments  (leadingComments, comments)  {if (!leadingComments) {return false;}if (Array.isArray(leadingComments)) {const res  leadingComments.filter((item)  {return item.node.value.includes(comments);});return res[0] || null;}return null; };//insert path const insertTracker  (path, param, state)  {const bodyPath  path.get(body);if (bodyPath.isBlockStatement()) {const ast  template.statement(${state.importTackerId}(${param});)();bodyPath.node.body.unshift(ast);} else {const ast  template.statement({${state.importTackerId}(${param});return BODY;})({ BODY: bodyPath.node });bodyPath.replaceWith(ast);} };//check if tacker func was imported const checkImport  (programPath, trackPath)  {let importTrackerId  ;programPath.traverse({ImportDeclaration(path) {const sourceValue  path.get(source).node.value;if (sourceValue  trackPath) {const specifiers  path.get(specifiers.0);importTrackerId  specifiers.get(local).toString();path.stop();}},});if (!importTrackerId) {importTrackerId  addDefault(programPath, trackPath, {nameHint: programPath.scope.generateUid(tracker),}).name;}return importTrackerId; };module.exports  declare((api, options)  {console.log(babel-plugin-tracker-comment);return {visitor: {ArrowFunctionExpression|FunctionDeclaration|FunctionExpression: {enter(path, state) {let nodeComments  path;if (path.isExpression()) {nodeComments  path.parentPath.parentPath;}// 获取leadingCommentsconst leadingComments  nodeComments.get(leadingComments);const paramCommentPath  hasTrackerComments(leadingComments,options.commentsTrack);//查看作用域中是否有——trackerParam// 如果有注释就插入函数if (paramCommentPath) {//add Importconst programPath  path.hub.file.path;const importId  checkImport(programPath, options.trackerPath);state.importTackerId  importId;insertTracker(path, state);}},},},}; });在获取注释的时候代码中并不是直接获取到path的leadingComments这是为什么 比如这串代码 //_tracker const test1  ()  {};我们在函数中遍历得到的path是(){}ast的path这个path的leadingComments其实是null而想要获取//_tracker我们真正需要拿到的path是注释下面的变量声明语句。所以在代码中有判断是否为表达式如果是那就需要先parentPath得到赋值表达式的path然后在parentPath才能拿到变量声明语句 运行代码 node index.js得到输出 总结 这篇文章写了如何根据函数上方的注释选择性的给函数埋点。过程详尽例子通俗易懂真是不可多得的一篇好文章啊 有任何问题欢迎金友们留言评论哦 相关文章 通过工具babel给函数都添加埋点[4] 通过工具babel给埋点函数传递参数[5]
http://www.huolong8.cn/news/206793/

相关文章:

  • 长沙全程网络营销哪家便宜seo排名优化软件有用
  • 广州网站推广建设电子商务网站建设参考书
  • 制作网站的成本规划宜春做网站 黑酷seo
  • 网站设计手机型企业网站管理系统的运维服务
  • 西安做网站公司有哪些?襄阳建设网站首页
  • 中国建设教育协会是个什么网站手工艺品网站建设
  • 宁波网站建设zj95苏州建设工程质量监督站网站
  • 江苏响应式网站建设哪里有舟山市住房和城乡建设局网站
  • 宜昌网站排名优化新开传奇网站超变
  • 花乡科技园区网站建设济南网络公司建站
  • 大连有什么好玩的地方保定seo推广公司
  • 长治网站建设案例开发网站公司排行榜
  • 外贸企业网站模版沈阳工程信息交易网
  • 广州开发网站技术主机 安装wordpress
  • 创建一个网站需要什么条件高端车品牌排行榜
  • 给网站做cdn网站google搜索优化
  • 模板网站首页设计小程序源码是什么意思
  • 水果网站建设aso搜索优化
  • 佛山做网站公司哪家好网站设计需要用到什么技术
  • 济南做网站的建设部网站查资质6
  • 北京网站搭建开发工业和信息化部考试中心
  • 网站建设技术架构美化wordpress
  • 网站推广的常用途径有哪些浙江和海建设集团网站首页
  • 做第三方库网站南通网站建设贵吗
  • 网站建设和管理情况怎么提高百度搜索排名
  • html5响应式设计公司网站模板整站html源码下载淘宝免费推广的方式有哪些
  • 烟台网站主关键词网站开发运营
  • 网站架构 规划全球十大软件公司排名
  • 个人网站制作步骤注册劳务公司流程和费用
  • 陵水县建设局网站高权重网站做js代码跳转