nodejs后台babel在线热编译jsx

浏览器加载react/vue组件时,遇到es6转es5,jsx转js...时,一种方法是用webpack离线编译,一种方法是用babel在线热编译(为了效率部署前可以预热)。

我比较喜欢在线热编译,好处是发布时快,不经过build直接源码发布,并可以避免忘记编译步骤导致bug。

为了提供效率,把热编译结果保存为文件缓存起来。先检查是否有编译后缓存文件,有就直接读取,否者编译,再读取。

let fs=require('fs');
let babel = require("@babel/core");
let babel_preset_env=require('@babel/preset-env');

function transform(f,cb){
  let fc=f+'.js';
  fs.access(fc,function(err){
    if (err){
      fs.readFile(f,'utf8',function(err,code){
        if (err){cb(err)}
        else{
          let r=babel.transformSync(code,{presets:[babel_preset_env]});
          code=r.code;
          cb(null,code);
          fs.writeFile(fc,code,function(err){
          });
        }
      });
    }
    else{
      fs.readFile(f,'utf8',function(err,code){
        cb(err,code);
      });
    }
  });
}
transform('a.jsx',function(err,code){console.log(err,code});

但在多并发时,问题来了:多个并发任务可能会同时都检查到缓存不存在,然后开始编译.......很浪费,其实只需要一个任务来编译,其它任务等待编译结束后再读取缓存。

其实有点复杂,涉及到文件锁机制,阿里“通义千问”建议用proper-lockfile,我没用。模拟一下:

/**
 * 测试多进程下,判断一个文件是否存在,不存在才生成内容创建文件
 * 难点:
 * (1)避免多个进程在生成文件内容。
 * (2)一个进程如何等待正在生成文件的进程生成完成再读取。
 * (3)等待的效率,降低cpu占用
 */
let path=require('path');
let fs=require('fs');
let fn=path.join(__dirname,'a.txt');

function rw5(task){
  let fnlock=fn+'.lock';
  //递归获取锁
  function lock(cb){
    fs.open(fnlock,'wx',function(err,fhandle){
      if (err){
        console.log(task,' locked,try again...');
        setTimeout(function(){
          lock(cb);
        },1);
      }
      else{
        fs.close(fhandle,function(err){
          if (err) console.log(err);
          console.log(task,' got lock');
          cb();
        });
      }
    });
  }
  function unlock(){
    fs.unlink(fnlock,function(err){if (err) console.log(err)});
  }
  function read(cb){
    fs.readFile(fn,'utf8',function(err,data){
      //读不到正在写入的内容
      if (err) console.log(err);
      else console.log(task,' readed:',data);
      if (cb) cb();
    });
  }
  function write(cb){
    let content='hello';
    //用setTimeout模拟一个长时间的content计算过程,比如babel转码
    setTimeout(function(){
      fs.writeFile(fn,content,function(err,data){
        console.log(task,' writed:',content);
        if (cb) cb();
      });
    }, 1000);
  }
  fs.access(fn,function(err,data){
    if (err){
      console.log(task,' not exists');
      lock(function(){
        fs.access(fn,function(err,data){
          if (err){
            console.log(task,' not exists');
            write(function(){
              unlock();
            });
          }
          else{
            read(function(){
              unlock();
            });
          }
        });
      });
    }
    else{
      read();
    }
  });
}
rw5(1);
rw5(2);

看到的运行记录,可能如下:

D:\work\Source\yujiang.Foil.Node\test\filerw>node multirw.js
1  not exists
2  not exists
1  got lock
2  locked,try again...
1  not exists
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
2  locked,try again...
1  writed: hello
2  locked,try again...
2  got lock
2  readed: hello

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/608864.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序网格布局

效果图 实现 wxml <!-- 订单内容 --><view class"father"><!-- 订单item --><view class"childs" wx:for"{{List}}" wx:key"{{ index }}"></view></view> wxss .father{display: grid;grid-tem…

如何在CentOS上解决Python版本冲突和路径问题

在使用CentOS等Linux系统时&#xff0c;安装多个Python版本可能会导致版本冲突和路径问题。当你运行python3命令时&#xff0c;系统可能不会调用你期望的Python版本&#xff0c;这可能会导致运行错误或者其他依赖问题。下面是一篇详细的博客&#xff0c;介绍如何解决这种Python…

数据治理的难题:如何化解?

在数字化转型的大潮中&#xff0c;数据治理成了每个企业都绕不开的话题。但是&#xff0c;数据治理这条路并不好走&#xff0c;充满了各种挑战。这些挑战不仅来自于技术&#xff0c;还有组织文化、流程和法律法规等方面。 挑战一&#xff1a;数据孤岛 在企业内部&#xff0c;…

如何远程控制另一部手机:远程控制使用方法

在现今高科技的社会中&#xff0c;远程控制手机的需求在某些情境下变得越来越重要。不论是为了协助远在他乡的家人解决问题&#xff0c;还是为了确保孩子的在线安全&#xff0c;了解如何实现这一功能都是有益的。本文将为您简要介绍几种远程控制手机的方法及其使用要点。 KKVi…

全面解析C++11与C++20线程(含内容)

昨晚跟一些小伙伴做了第一次直播尝试&#xff0c;一起探讨了C11 thread与 C20的jthread&#xff0c;于此同时给大家出了几个问题&#xff0c;在直播之外不会公布答案&#xff0c;所以以后直播还是得跟着走起。 总共有22人参加直播&#xff0c;氛围相当不错&#xff0c;没有录播…

如何解决 NPM依赖下载超时问题 :npm ERR! network timeout at: https://registry.npmjs.org/猫头虎

如何解决 NPM依赖下载超时问题 &#xff1a;npm ERR! network timeout at: https://registry.npmjs.org/猫头虎 博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试…

AWS Cli Windows安装配置

1. 安装 下载地址&#xff1a;AWS 命令行界面(CLI)_管理AWS服务的统一工具-AWS云服务 检验安装&#xff1a; > aws --version aws-cli/2.15.44 Python/3.11.8 Windows/10 exe/AMD64 prompt/off 2. 创建IAM用户 1) 创建组 选择IAM 点击创建组 填写用户组名&#xff0c;…

Linux sudo 指令

sudo命令 概念&#xff1a; sudo是linux下常用的允许普通用户使用超级用户权限的工具&#xff0c;允许系统管理员让普通用户执行一些或者全部的root命令&#xff0c;如halt&#xff0c;reboot&#xff0c;su等。这样不仅减少了root用户的登录和管理时间&#xff0c;同样也提高…

Qt常用基础控件总结

一、按钮部件 按钮部件共同特性 Qt 用于描述按钮部件的类、继承关系、各按钮的名称和样式,如下图: 助记符:使用字符"&“可在为按钮指定文本标签时设置快捷键,在&之后的字符将作为快捷键。比如 “A&BC” 则 Alt+B 将成为该按钮的快捷键,使用”&&qu…

基于FPGA实现的HDMI TO MIPI扩展显示器方案

FPGA方案&#xff0c;HDMI IN接收原始HDMI 信号&#xff0c;输出显示到LCD 屏上 客户应用&#xff1a;扩展显示器 主要特性&#xff1a; 1.支持2K以下任意分辨率显示 2.支持OSD 叠加多个图层 3.支持MIPI/EDP/LVDS/RGB屏 4.支持放大缩小匹配屏分辨率 5.零延时&#xff0c;输…

算法设计课第五周(贪心法实现活动选择问题)

目录 一、【实验目的】 二、【实验内容】 三、实验源代码 一、【实验目的】 &#xff08;1&#xff09;熟悉贪心法的设计思想 &#xff08;2&#xff09;理解贪心法的最优解与正确性证明之间的关系 &#xff08;3&#xff09;比较活动选择的各种“贪心”策略&#xff0c;…

Navicat连接远程数据库时,隔一段时间不操作出现的卡顿问题

使用 Navicat 连接服务器上的数据库时&#xff0c;如果隔一段时间没有使用&#xff0c;再次点击就会出现卡顿的问题。 如&#xff1a;隔一段时间再查询完数据会出现&#xff1a; 2013 - Lost connection to MySQL server at waiting for initial communication packet, syste…

上位机图像处理和嵌入式模块部署(树莓派4b读写json数据)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们说过&#xff0c;ini文件是用来进行配置的&#xff0c;数据库是用来进行数据存储的。那json是用来做什么的呢&#xff0c;json一般是用来做…

C++学习进阶:C++11线程库

目录 前言&#xff1a; 1.线程库的使用 1.1.thread库 1.2.mutex库 1.3.condition_variable库 1.4.atomic库 2.线程安全问题 2.1.智能指针 2.2.STL容器 前言&#xff1a; 操作系统&#xff1a;线程-CSDN博客 我们曾经在这篇博客中提及了“语言”和“pthread库”之间的…

Flutter 引入webview_windows插件,在已经使用$PATH 中的 nuget.exe情况下,windows端构建失败

报错 PS F:\xx\xxxx> flutter run -d windows Flutter assets will be downloaded from https://storage.flutter-io.cn. Make sure you trust this source! Launching lib\main.dart on Windows in debug mode... E:\Some software\Visual Studio\VS 2022\MSBuild\M…

JavaScript 进阶征途:解锁Function奥秘,深掘Object方法精髓

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;JavaScript 精粹 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 &#x1f235;Function方法 与 函数式编程&#x1f49d;1 call &#x1f49d…

Linux|进程控制

进程创建 fork函数初识 在linux中fork函数时非常重要的函数&#xff0c;它从已存在进程中创建一个新进程。新进程为子进程&#xff0c;而原进程为父进程。 返回值&#xff1a;子进程中返回0&#xff0c;父进程返回子进程id&#xff0c;出错返回-1 进程调用fork&#xff0c;当…

ICode国际青少年编程竞赛- Python-2级训练场-数独

ICode国际青少年编程竞赛- Python-2级训练场-数独 1、 Spaceship.step(3)2、 Spaceship.step(3)3、 Spaceship.step(1) Spaceship.turnLeft() Spaceship.step(1)4、 Spaceship.step(3) Spaceship.turnRight() Spaceship.step(1)5、 Spaceship.step(4) for i in range(3):Spaces…

企业级通用业务 Header 处理方案

目录 01: 处理 PC 端基础架构 02: 通用组件&#xff1a;search 搜索框能力分析 03: 通用组件&#xff1a;search 搜索框样式处理 04: 通用组件&#xff1a;Button 按钮能力分析 05: 通用组件&#xff1a;Button 按钮功能实现 06: 通用组件&#xff1a;完善 search 基本…

MySQL学习笔记11——数据备份 范式 ER模型

数据备份 & 范式 & ER模型 一、数据备份1、如何进行数据备份&#xff08;1&#xff09;备份数据库中的表&#xff08;2&#xff09;备份数据库&#xff08;3&#xff09;备份整个数据库服务器 2、如何进行数据恢复3、如何导出和导入表里的数据&#xff08;1&#xff09…
最新文章