VSCode代码编译启动调试

匿名 (未验证) 提交于 2019-12-02 23:59:01

编译运行

  • fork vscode的源代码,并clone到本地, checkout到master分支
  • 执行yarn install安装依赖,具体node环境查看官方文档
  • 执行yarn watch编译代码并且执行实时监控修改进行增量编译
  • 执行./script/code.sh启动electron程序

1. yarn watch分析

利用gulp watch监控目录变化,实时编译最新的代码

gulp watch --max_old_space_size=4095

gulp会自动读取执行目录下的gulpfile.js文件,并执行,下面分析gulpfile.js

gulpfile.js定义了compile-client, watch-client, compile, watch,default五种任务,先看watch,也就是我们上面执行的命令

- default

可以看到,执行watch的时候并没有执行编译步骤,应该是在default中定义了执行watch前需要执行的流程。

// monacoTypecheckTask monaco编辑器编译 // compileClientTask 客户端基础代码编译 // compileExtensionsTask 客户端基础扩展插件代码编译 const compileTask = task.define('compile', task.parallel(monacoTypecheckTask, compileClientTask, compileExtensionsTask)); gulp.task(compileTask); 
  • monacoTypecheckTask (gulpfile.editor.js)
// 利用tsc,以及tsconfig.monaco.json对monaco编辑器进行编译检查 // 主要代码在src/vs/editor下面,另外的依赖可查看tsconfig.monaco.json const args = ['./node_modules/.bin/tsc', '-p', './src/tsconfig.monaco.json', '--noEmit']; 
  • compileClientTask(compilation.ts)
function createCompile(src: string, build: boolean, emitError?: boolean): (token?: util.ICancellationToken) => NodeJS.ReadWriteStream {     //获取typescript编译选项     const opts = _.clone(getTypeScriptCompilerOptions(src));     //是否代码映射     opts.inlineSources = !!build;     opts.noFilesystemLookup = true;     //利用gulp-tsb编译typescript代码     const ts = tsb.create(opts, true, undefined, err => reporter(err.toString()));     ................................... } 

这三步编译后的js代码输出在out文件夹下

- watch

包含了watchClientTaskwatchExtensionTaskwatchClientTask两个Task,分别监控客户端代码和插件代码的文件夹。核心代码在build/lib/compilation.ts下,

  • watchClientTask
    核心逻辑在build/lib/compilations.tswatchTask方法内
// watch核心逻辑, 变化后编译   const watchSrc = watch('src/**', { base: 'src' });    let generator = new MonacoGenerator(true);   generator.execute();     return watchSrc    .pipe(generator.stream)    //incremental增量编译, 暂时不细看    .pipe(util.incremental(compile, src, true))    //输出目录    .pipe(gulp.dest(out)); 
  • watchExtensionsTask
    核心逻辑在gulpfile.extansions.js
// 遍历extensions文件夹,找到有tsconfig.json文件的插件 const compilations = glob.sync('**/tsconfig.json', {  cwd: extensionsPath,  ignore: ['**/out/**', '**/node_modules/**'] });  const getBaseUrl = out => `https://ticino.blob.core.windows.net/sourcemaps/${commit}/${out}`;  //找到需要编译的文件夹后生成对应extensions的compile\watch\build任务 //watch的核心其实也是watcher const tasks = compilations.map(function (tsconfigFile) {  .......        const watchTask = task.define(`watch-extension:${name}`, task.series(cleanTask, () => {       const pipeline = createPipeline(false);       const input = gulp.src(src, srcOpts);       const watchInput = watcher(src, srcOpts);        return watchInput        .pipe(util.incremental(pipeline, input))    .pipe(gulp.dest(out));  }));  .......  } 

自此所有的ts和css的编译完成,并输出到out文件夹,一旦修改了src以及extensions文件夹下的文件,watch会自动重新进行增量编译

2. ./script/code.sh分析

- 找到对应平台的electron可执行文件
if [[ "$OSTYPE" == "darwin"* ]]; then   NAME=`node -p "require('./product.json').nameLong"`   CODE="./.build/electron/$NAME.app/Contents/MacOS/Electron"  else   NAME=`node -p "require('./product.json').applicationName"`   CODE=".build/electron/$NAME"  fi 
- 执行一系列的单元测试
- 启动
# Launch Code 从哪里启动的? 直接根据package.json中指定的 "main": "./out/main" 启动main进程  exec "$CODE" . "$@" 

自此,整个程序就已经完成了编译和启动。

3. 调试

为了方便以后的修改或者看源码,就需要能动态调试整个项目,下面介绍用WebStorm结合Chrome DevTools来动态调试主进程和渲染进程的方法

- 调试渲染进程

每个渲染进程都运行了一个Chromium实例,其自带了完整的Chrome DevTools套件,只需要在焦点窗口处按下 'Cmd + Opt + I’即可打开,也可以通过菜单’Help -> Toggle Developer Tools’打开。
接下来切换到Sources,或者按下’Cmd + P’查找desktop.main.ts,在onWindowResize方法处下断点,如图

然后调整vscode客户端的大小,就会发现跑到了断点处,渲染进程调试成功

- 调试Node进程

Electron的主进程运行在Node环境中,某些耗时操作运行在fork出来的Node进程中,例如搜索,在启动./script/code.sh后,出现类似的如下日志

Debugger listening on ws://127.0.0.1:5876/bd5aa4a9-d80e-4bfa-bb68-5a0e783de665 For help, see: https://nodejs.org/en/docs/inspector

可知node利用 inspector参数开启了5876端口监听debug(注意:如果5876端口被占用会自动开启其他端口,要根据日志输出,设置不同的端口)利用WebStorm的Debug连接上5876端口即可实现Node进程调试,配置如下

Attach成功,则会出现如下日志

Debugger attached.

接下来尝试在vs/services/search/node/searchIpc.ts中的SearchChannel -> listene方法打断点,接下来执行vscode中的搜索功能,则可以看到运行到了断点处

至此整个vscode的编译运行调试完成

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!