 VSCode插件-Node进程交互
VSCode插件-Node进程交互
  # 0.前言
# 1.进程模块说明
Node中的进程:
- 主进程: - process,无需导入可直接通过- process变量访问。
- 子进程: - child_process,异步京城的创建方式如下:- child_process.exec:用于执行- shell命令
- child_process.execFile:同上。
- child_process.fork:增强版- spawn,返回的子进程对象可以和父进程对象进行通信,通过- send和- on方法。- 衍生的 - Node.js子进程独立于父进程,但两者之间建立的 IPC 通信通道除外。 每个进程都有自己的内存,带有自己的 V8 实例
- child_process.spawn:上述- API的底层实现。
 
# 1.Node进程间的三种交互方式
 # 1. 默认pipe
 官方说明是主进程和子进程间建立了一个管道,实际上是构建了默认开启一个事件发布订阅模式。
- 主进程:
const path = require('path')
const { spawn } = require('child_process')
// 等价于执行 node ./child_1.js
let p = spawn('node', ['child_1.js'], {
    cwd: path.join(__dirname, 'childs'),
    stdio: ['pipe', 'pipe', 'pipe']
})
p.stdout.on('data', (data) => {
    console.log('获取到子进程的pid:', data.toString());
})
console.log("主进程pid:",process.pid);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
- 子进程:在子进程的终端输出pid
console.log("主进程pid:",process.pid);
1
ps. 在终端输出有两种方式:
- 使用
console.log- 使用
process.stdout.write()
# 2. 使用公共数据流,默认传递的是父进程
将pipe 改为process.stdin、process.stdout、process.stderr
- 主进程 - const path = require('path') const { spawn } = require('child_process') // 等价于 node ./child_1.js let p = spawn('node', ['child_1.js'], { cwd: path.join(__dirname, 'childs'), stdio: [process.stdin,process.stdout, process.stderr] }) console.log("主进程pid",process.pid);1
 2
 3
 4
 5
 6
 7
 8
 9
 10
- 子进程 - // 注: process 仍是 子进程的 pid(线程) // 但此时 process.stdout 使用的是 公共的流 (本质是父组件的流) process.stdout.write("子进程的pid", process.pid) // 往公共(父组件)的终端输出1
 2
 3
# 3.使用ipc
 此方案感觉像是真正建立了信息交互的桥梁,原因是:在调用.send() 函数时无需再次指定传输的对象。
- 主进程 - const path = require('path') const { spawn } = require('child_process') // 等价于 node ./child_1.js let p = spawn('node', ['child_1.js'], { cwd: path.join(__dirname, 'childs'), stdio: ["ipc", 'pipe', 'pipe'] }) p.on("message", message => { console.log("子进程的pid", message); }) console.log("主进程的pid", process.pid);1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
- 子进程 - // 子进程未指定 send to Who??? process.send(process.pid)1
 2
# 2.其余技巧
# 1. 如何判断是否文件是否存在:
let filePath: string = path.normalize(
  `${projectName}/application.config.json`
);
if (!fs.existsSync(filePath)) {
  vscode.window.showErrorMessage(
    "cmr数据同步失败,找不到application.config.json!"
  );
  return;
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 2.解决 settings 页面资源导入问题
function getWebViewContent2(context: any, templatePath: any) {
  const resourcePath = path.join(context.extensionPath, templatePath);
  const dirPath = path.dirname(resourcePath);
  let html = fs.readFileSync(resourcePath, "utf-8");
  // vscode不支持直接加载本地资源,需要替换成其专有路径格式,这里只是简单的将样式和JS的路径替换
  html = html.replace(
    /(<link.+?href="|<script.+?src="|<img.+?src=")(.+?)"/g,
    (m, $1, $2) => {
      const str =
        $1 +
        vscode.Uri.file(path.resolve(dirPath, $2.substr(1)))
          .with({ scheme: "vscode-resource" })
          .toString() +
        '"';
      return str;
    }
  );
  return html;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 参考资料
- https://zhuanlan.zhihu.com/p/36678971 
- https://www.cnblogs.com/chyingp/p/node-learning-guide-child_process.html 
编辑  (opens new window)
  上次更新: 2023/06/17, 10:06:00
