Visual Studio 即使定义了变量,代码也会显示红色波浪线

Visual Studio Code shows red swiggly lines even when variable is defined

我在 visual studio 代码中有红色波浪线,即使定义了变量(错误消息)也是如此。

如果我禁用 eslint,它就会消失,但我认为这不是正确的方法,这将停止检查 ts/js 文件的其余部分。 (我安装了 ESLint 扩展)

我有 Visual Studio 代码:Mac OS Catalina 上的 1.57.1​​(通用)。

我可以右键单击并转到 browser 定义。

beforeAll(async () => {
await browser.url('https://example.com/');

})

如果我去定义它看起来像下面这样

代码片段在 .js 文件中,这是 visual studio 代码

的右下角

我该如何解决这个问题? 我也尝试在此处提到的解决方案之一中删除此 .vs 文件夹,但没有成功:Visual Studio compiles fine, but it still shows red lines

还在我的代码中安装了这些库:

npm i
npm install @wdio/cli (https://webdriver.io/docs/gettingstarted/)
npx wdio config

我可以编译我的项目,但是如何在不禁用 ESLint 的情况下去除这些红线?

感谢您的帮助!

beforeAll(async () => {
    await browser.url('https://example.com/');
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.2.3/jquery.min.js">
</script>

注意:我不确定如何创建此代码的 mvp。 但是 beforeAll 是从节点模块定义的。我在下面包含了相关文件。 node_modules/@types/jest/index.d.ts declare var beforeAll: jest.Lifecycle;

我的 package.json 文件看起来像这样

{
  "name": "test-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/user-event": "^12.1.10",
    "@types/jest": "^26.0.15",
    "@types/node": "^12.0.0",
    "@types/react": "^16.14.2",
    "@types/react-dom": "^16.9.8",
    "axios": "^0.21.1",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.1",
    "web-vitals": "^0.2.4"
  },
  "jest": {
    "preset": "jest-playwright-preset"
  },
  "globals": {
    "browserName": "BrowserType",
    "browser": "Browser",
    "context": "BrowserContext",
    "page": "page"
  },
  "devDependencies": {
    "@testing-library/react": "^11.2.3",
    "@wdio/cli": "^7.7.4",
    "@wdio/jasmine-framework": "^7.7.3",
    "@wdio/local-runner": "^7.7.4",
    "@wdio/mocha-framework": "^7.7.4",
    "@wdio/spec-reporter": "^7.7.3",
    "chromedriver": "^91.0.1",
    "jest": "^26.6.0",
    "jest-junit": "^12.0.0",
    "jest-playwright-preset": "^1.6.1",
    "playwright": "^1.12.3",
    "ts-jest": "^26.5.4",
    "ts-node": "^10.0.0",
    "typescript": "^4.2.4",
    "wdio-chromedriver-service": "^7.1.1",
    "webdriverio": "^7.5.7"
  },
  "proxy": "https://localhost:5001",
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  }
}

这是使用 Jest 和 Web Driver UI 浏览器自动化

这是上面截图中的node_modules/jest-playwright-preset/types/global.d.ts文件

import {
  Browser,
  BrowserContext,
  Page,
  BrowserContextOptions,
  LaunchOptions,
  ConnectOptions,
  ConnectOverCDPOptions,
  BrowserType as PlaywrightBrowserType,
  ViewportSize,
  ChromiumBrowser,
  FirefoxBrowser,
  WebKitBrowser,
  devices,
} from 'playwright-core'
import { Config as JestConfig } from '@jest/types'
import { Test } from 'jest-runner'
import { JestProcessManagerOptions } from 'jest-process-manager'

// TODO Find out flex ways to reuse constants
declare const IMPORT_KIND_PLAYWRIGHT = 'playwright'

declare const CHROMIUM = 'chromium'
declare const FIREFOX = 'firefox'
declare const WEBKIT = 'webkit'

declare const LAUNCH = 'LAUNCH'
declare const PERSISTENT = 'PERSISTENT'
declare const SERVER = 'SERVER'

declare module 'jest-playwright-preset' {
  const globalSetup: (config: JestConfig.GlobalConfig) => void
  const globalTeardown: (config: JestConfig.GlobalConfig) => void
  const getPlaywrightEnv: (env?: string) => void
}

export type BrowserType = typeof CHROMIUM | typeof FIREFOX | typeof WEBKIT

export type SkipOption = {
  browsers: BrowserType[]
  devices?: string[] | RegExp
}

export interface TestPlaywrightConfigOptions extends JestPlaywrightConfig {
  browser?: BrowserType
  device?: ConfigDeviceType
}

export type GenericBrowser = PlaywrightBrowserType<
  WebKitBrowser | ChromiumBrowser | FirefoxBrowser
>

type Nullable<T> = T | null

interface JestPlaywright {
  /**
   * Reset global.page
   *
   * ```ts
   * it('should reset page', async () => {
   *   await jestPlaywright.resetPage()
   * })
   * ```
   */
  resetPage: () => Promise<void>
  /**
   * Reset global.context
   *
   * ```ts
   * it('should reset context', async () => {
   *   await jestPlaywright.resetContext()
   * })
   * ```
   */
  resetContext: (newOptions?: BrowserContextOptions) => Promise<void>
  /**
   * Reset global.browser, global.context, and global.page
   *
   * ```ts
   * it('should reset page', async () => {
   *   await jestPlaywright.resetBrowser()
   * })
   * ```
   */
  resetBrowser: (newOptions?: BrowserContextOptions) => Promise<void>
  /**
   * Saves the coverage to the disk which will only work if `collectCoverage`
   * in `jest-playwright.config.js` file is set to true. The merged coverage file
   * is then available in `.nyc_output/coverage.json`. Mostly its needed in the
   * `afterEach` handler like that:
   *
   * ```ts
   * afterEach(async () => {
   *   await jestPlaywright.saveCoverage(page)
   * })
   * ```
   */
  saveCoverage: (page: Page) => Promise<void>
  configSeparateEnv: (
    config: Partial<TestPlaywrightConfigOptions>,
    isDebug?: boolean,
  ) => Promise<ConfigParams>
}

interface JestParams<T> {
  (options: T, name: string, fn?: jest.ProvidesCallback, timeout?: number): void
}

type ProvidesCallback = (cb: ConfigParams) => void

interface JestParamsWithConfigParams<T> {
  (
    options: Partial<T>,
    name: string,
    fn?: ProvidesCallback,
    timeout?: number,
  ): void
}

interface JestPlaywrightTestDebug
  extends JestParamsWithConfigParams<JestPlaywrightConfig> {
  (name: string, fn?: ProvidesCallback, timeout?: number): void
  skip:
    | JestParamsWithConfigParams<JestPlaywrightConfig>
    | JestPlaywrightTestDebug
  only:
    | JestParamsWithConfigParams<JestPlaywrightConfig>
    | JestPlaywrightTestDebug
}

interface JestPlaywrightTestConfig
  extends JestParamsWithConfigParams<JestPlaywrightConfig> {
  skip:
    | JestParamsWithConfigParams<JestPlaywrightConfig>
    | JestPlaywrightTestConfig
  only:
    | JestParamsWithConfigParams<JestPlaywrightConfig>
    | JestPlaywrightTestConfig
}

declare global {
  const browserName: BrowserType
  const deviceName: Nullable<string>
  const page: Page
  const browser: Browser
  const context: BrowserContext
  const jestPlaywright: JestPlaywright
  namespace jest {
    interface It {
      jestPlaywrightSkip: JestParams<SkipOption>
      jestPlaywrightDebug: JestPlaywrightTestDebug
      jestPlaywrightConfig: JestPlaywrightTestConfig
    }
    interface Describe {
      jestPlaywrightSkip: JestParams<SkipOption>
    }
  }
}

type DeviceDescriptor = {
  viewport: Nullable<ViewportSize>
  userAgent: string
  deviceScaleFactor: number
  isMobile: boolean
  hasTouch: boolean
  defaultBrowserType: BrowserType
}

export type CustomDeviceType = Partial<DeviceDescriptor> & {
  name: string
}

export type ConfigDeviceType = CustomDeviceType | string

export type DeviceType = Nullable<ConfigDeviceType>

export type WsEndpointType = Nullable<string>

export type SelectorType = {
  script: string | Function | { path?: string; content?: string }
  name: string
}

export type PlaywrightRequireType = BrowserType | typeof IMPORT_KIND_PLAYWRIGHT

export interface Playwright {
  name: PlaywrightRequireType
  instance: GenericBrowser | Record<BrowserType, GenericBrowser>
  devices: typeof devices
}

type LaunchType = typeof LAUNCH | typeof SERVER | typeof PERSISTENT

type Options<T> = T & Partial<Record<BrowserType, T>>

export type ServerOptions = JestProcessManagerOptions & {
  teardown?: string
}

export interface JestPlaywrightConfig {
  haveSkippedTests?: boolean
  skipInitialization?: boolean
  debugOptions?: JestPlaywrightConfig
  launchType?: LaunchType
  launchOptions?: Options<LaunchOptions>
  connectOptions?: Options<ConnectOptions | ConnectOverCDPOptions>
  contextOptions?: Options<BrowserContextOptions>
  userDataDir?: string
  exitOnPageError?: boolean
  displayName?: string
  browsers: (BrowserType | (JestPlaywrightConfig & { name: BrowserType }))[]
  devices?: ConfigDeviceType[] | RegExp
  useDefaultBrowserType?: boolean
  serverOptions?: ServerOptions | ServerOptions[]
  selectors?: SelectorType[]
  collectCoverage?: boolean
}

export type JestPlaywrightProjectConfig = Test['context']['config'] & {
  browserName: BrowserType
  wsEndpoint: WsEndpointType
  device: DeviceType
}

export type JestPlaywrightContext = Omit<Test['context'], 'config'> & {
  config: JestPlaywrightProjectConfig
}

export type JestPlaywrightTest = Omit<Test, 'context'> & {
  context: JestPlaywrightContext
}

export interface BrowserTest {
  test: JestPlaywrightTest
  config: JestPlaywrightConfig
  browser: BrowserType
  wsEndpoint: WsEndpointType
  device: DeviceType
}

export type ConfigParams = {
  browserName: BrowserType
  deviceName: Nullable<string>
  browser: Nullable<Browser | BrowserContext>
  context: BrowserContext
  page: Page
}

Eslint 不了解全局变量。要解决这个问题,您有两个选择:

  • 告诉eslint定义了哪些变量
  • 禁用检查未定义变量的 eslint 规则

要告诉 eslint 定义了哪些全局变量,请将它们添加到您的 eslint 配置文件中

{
    "globals": {
        "var1": true,
    }
}

文档:https://eslint.org/docs/2.13.1/user-guide/configuring#specifying-globals

为了简化这一点,eslint 提供了所谓的 'environments',其中包括所有全局变量,例如此处描述的框架:https://eslint.org/docs/2.13.1/user-guide/configuring#specifying-environments