微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

VS Code和JSDoc中protobuf生成JS代码的语义检查

如何解决VS Code和JSDoc中protobuf生成JS代码的语义检查

我正在编写一个 Node.js 应用程序,该应用程序使用 Google Protocol Buffers 与 C# 客户端进行通信。

我正在使用带有 Commonjs 样式导入的官方 Google 的 JavaScript 编译器。我最近使用 eslint 将 linting 添加到我的项目中,特别是认的“google”配置。 VS Code 提供语义检查(设置 ID js/ts.implicitProjectConfig.checkJs),结合 JSDoc,谷歌 lint 风格强制执行,非常适合在我的应用程序中引入一点类型安全。现在的问题是我无法让 VS Code 语义检查与 Protocol Buffers 生成的 JS 代码一起使用。代码运行良好,所以至少 Node 理解协议缓冲区代码

这是一个小示例代码index.js,这给我带来了麻烦:

// Alteratively following works for JSDoc as well: /** @typedef { import('./bar').Bar } Bar */
const {Bar} = require('./bar');

// The typedef imports are not working:
// /** @typedef { import('./foo_pb').fooPackage } fooPackage */
// ^ Warns "Namespace ...foo_pb has no exported member fooPackage"
// /** @typedef { import('./foo_pb').Foo } Foo */
// ^ Warns "Namespace ...foo_pb has no exported member Foo"
const fooPackage = require('./foo_pb');

/**
 * @param {Bar} bar
 */
function useBar(bar) {
  bar.printHi();
}

// VS Code warns "Namespace <abspath>/foo_pb has no exported member 'Foo'."
/**
 * @param {fooPackage.Foo} foo
 */
function useFoo(foo) {
  console.log(foo);
}

useBar(new Bar());
// VS Code warns "Property 'Foo' does not exist on type 'typeof import("<abspath>/foo_pb")'."
useFoo(fooPackage.Foo.FOO_OK);

这是 foo.proto 文件,它生成输出 foo_pb.js

// foo.proto
Syntax = "proto3";

package fooPackage;

enum Foo {
  FOO_UNSPECIFIED = 0;
  FOO_OK = 1;
}

// foo_pb.js
var jspb = require('google-protobuf');
var goog = jspb;
var global = Function('return this')();

goog.exportSymbol('proto.fooPackage.Foo',null,global);
/**
 * @enum {number}
 */
proto.fooPackage.Foo = {
  FOO_UNSPECIFIED: 0,FOO_OK: 1
};

goog.object.extend(exports,proto.fooPackage);

这是在 index.js 中使用的 bar.js,它在语义检查中按我的预期工作:

/** A Bar class */
class Bar {
  /** Prints hi */
  printHi() {
    console.log('Hi');
  }
}

module.exports = {
  Bar,};

这是我的删节版package.json

{
  "main": "index.js","scripts": {
    "build": "protoc --proto_path=./ --js_out=import_style=commonjs,binary:./ foo.proto","lint": "node_modules/.bin/eslint ./"
  },"dependencies": {
    "google-protobuf": "^3.14.0"
  },"devDependencies": {
    "eslint": "^7.18.0","eslint-config-google": "^0.14.0"
  }
}

我不清楚这是否是 VS Code、Google 的协议缓冲区代码或 JSDoc 的问题,以及 TypeScript 和 Closure 如何参与其中。

解决方法

对我来说使用以下 require 语法的合理解决方案:const Foo = require('./foo_pb').Foo;

VS Code 语义检查并没有抱怨它,但它确实有以下缺点:

  • 每个符号必须单独导入,而 const fooPackage = require('./foo_pb'); 将所有符号导入 fooPackage“命名空间”。可以说这实际上是一个好处,因为整个“包括你使用的”原则。
  • VS Code 无法检查这些符号,因此自动完成对它们不起作用
  • Linting 可能会抱怨这些导入的 no-unused-vars,例如,如果它们只是函数参数。对我来说一个简单的解决方案是包装这些导入 /* eslint-disable no-unused-vars */ 块。

仅供参考,这里正在运行 index.js

const {Bar} = require('./bar');

const Foo = require('./foo_pb').Foo;

/**
 * @param {Bar} bar
 */
function useBar(bar) {
  bar.printHi();
}

/**
 * @param {Foo} foo
 */
function useFoo(foo) {
  console.log(foo);
}

useBar(new Bar());
useFoo(Foo.FOO_OK);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?