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