Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Many typescript issues while type checking #2642

Closed
blephy opened this issue Oct 3, 2020 · 2 comments
Closed

Many typescript issues while type checking #2642

blephy opened this issue Oct 3, 2020 · 2 comments

Comments

@blephy
Copy link

blephy commented Oct 3, 2020

I'm adding workbox in my ReactJs application.

When i'm running Husky post-commit hooks with tsc -p tsconfig.json --noEmit, a lot of errors from workbox packages comes. If i run tsc -p tsconfig.json --noEmit --skipLibCheck, as you know, errors disappear

> tsc -p tsconfig.json --noEmit

node_modules/@types/workbox-build/_types.d.ts(1,10): error TS2305: Module '"../../workbox-routing"' has no exported member 'RouteHandlerCallback'.
node_modules/@types/workbox-build/_types.d.ts(1,32): error TS2305: Module '"../../workbox-routing"' has no exported member 'RouteMatchCallback'.
node_modules/@types/workbox-core/types/WorkboxPlugin.d.ts(39,13): error TS2304: Cannot find name 'ExtendableEvent'.
node_modules/@types/workbox-core/types/WorkboxPlugin.d.ts(51,13): error TS2304: Cannot find name 'ExtendableEvent'.
node_modules/@types/workbox-core/types/WorkboxPlugin.d.ts(62,13): error TS2304: Cannot find name 'ExtendableEvent'.
node_modules/@types/workbox-precaching/PrecacheController.d.ts(19,17): error TS2304: Cannot find name 'FetchEvent'.
node_modules/@types/workbox-routing/Router.d.ts(31,17): error TS2304: Cannot find name 'FetchEvent'.
node_modules/@types/workbox-routing/types/RouteHandler.d.ts(11,13): error TS2304: Cannot find name 'FetchEvent'.
node_modules/@types/workbox-routing/types/RouteMatchCallback.d.ts(5,13): error TS2304: Cannot find name 'ExtendableEvent'.
node_modules/@types/workbox-strategies/CacheFirst.d.ts(3,5): error TS2305: Module '"../../workbox-routing"' has no exported member 'RouteHandlerCallback'.
node_modules/@types/workbox-strategies/CacheFirst.d.ts(4,5): error TS2305: Module '"../../workbox-routing"' has no exported member 'RouteHandlerObject'.
node_modules/@types/workbox-strategies/CacheOnly.d.ts(3,5): error TS2305: Module '"../../workbox-routing"' has no exported member 'RouteHandlerCallback'.
node_modules/@types/workbox-strategies/CacheOnly.d.ts(4,5): error TS2305: Module '"../../workbox-routing"' has no exported member 'RouteHandlerObject'.
node_modules/@types/workbox-strategies/NetworkFirst.d.ts(3,5): error TS2305: Module '"../../workbox-routing"' has no exported member 'RouteHandlerCallback'.
node_modules/@types/workbox-strategies/NetworkFirst.d.ts(4,5): error TS2305: Module '"../../workbox-routing"' has no exported member 'RouteHandlerObject'.
node_modules/@types/workbox-strategies/NetworkOnly.d.ts(3,5): error TS2305: Module '"../../workbox-routing"' has no exported member 'RouteHandlerCallback'.
node_modules/@types/workbox-strategies/NetworkOnly.d.ts(4,5): error TS2305: Module '"../../workbox-routing"' has no exported member 'RouteHandlerObject'.
node_modules/@types/workbox-strategies/StaleWhileRevalidate.d.ts(3,5): error TS2305: Module '"../../workbox-routing"' has no exported member 'RouteHandlerCallback'.
node_modules/@types/workbox-strategies/StaleWhileRevalidate.d.ts(4,5): error TS2305: Module '"../../workbox-routing"' has no exported member 'RouteHandlerObject'.
node_modules/@types/workbox-strategies/types/MakeRequestCallback.d.ts(7,13): error TS2304: Cannot find name 'ExtendableEvent'.
node_modules/workbox-core/_private/fetchWrapper.d.ts(5,13): error TS2304: Cannot find name 'ExtendableEvent'.
node_modules/workbox-core/_private/resultingClientExists.d.ts(12,84): error TS2304: Cannot find name 'Client'.
node_modules/workbox-core/types.d.ts(8,13): error TS2304: Cannot find name 'ExtendableEvent'.
node_modules/workbox-core/types.d.ts(30,13): error TS2304: Cannot find name 'ExtendableEvent'.
node_modules/workbox-core/types.d.ts(81,13): error TS2304: Cannot find name 'ExtendableEvent'.
node_modules/workbox-core/types.d.ts(91,13): error TS2304: Cannot find name 'ExtendableEvent'.
node_modules/workbox-core/types.d.ts(100,13): error TS2304: Cannot find name 'ExtendableEvent'.
node_modules/workbox-precaching/PrecacheController.d.ts(42,17): error TS2304: Cannot find name 'ExtendableEvent'.
node_modules/workbox-precaching/PrecacheController.d.ts(81,17): error TS2304: Cannot find name 'ExtendableEvent'.
node_modules/workbox-routing/Router.d.ts(79,17): error TS2304: Cannot find name 'ExtendableEvent'.
node_modules/workbox-routing/Router.d.ts(97,17): error TS2304: Cannot find name 'ExtendableEvent'.
node_modules/workbox-strategies/CacheFirst.d.ts(60,47): error TS2304: Cannot find name 'ExtendableEvent'.
node_modules/workbox-strategies/NetworkFirst.d.ts(85,17): error TS2304: Cannot find name 'ExtendableEvent'.
node_modules/workbox-strategies/StaleWhileRevalidate.d.ts(68,17): error TS2304: Cannot find name 'ExtendableEvent'.
husky > pre-commit hook failed (add --no-verify to bypass)

Here is my tsconfig.json :

{
  "ts-node": {
    "compilerOptions": {
      "module": "commonjs"
    }
  },
  "compilerOptions": {
    "baseUrl": "./",
    "sourceMap": true,
    "module": "esnext",
    "target": "es2017",
    "moduleResolution": "node",
    "jsx": "react",
    "checkJs": false,
    "allowJs": false,
    "importHelpers": true,
    "noImplicitAny": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "resolveJsonModule": true,
    "allowSyntheticDefaultImports": true,
    "typeRoots": ["./node_modules/@types", "./src/@types", "./config/@types"],
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "exclude": [
    "build",
    "stats",
    "reports",
    "coverage",
    "server",
    ".vscode",
    ".github",
    "**/node_modules/**",
    "config/test/**"
  ]
}

Here is my service-worker entry point :

/* eslint-disable no-underscore-dangle */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-call */
import { CacheableResponsePlugin } from 'workbox-cacheable-response'
import { setCacheNameDetails } from 'workbox-core'
import { ExpirationPlugin } from 'workbox-expiration'
import { cleanupOutdatedCaches, createHandlerBoundToURL, precacheAndRoute } from 'workbox-precaching'
import { NavigationRoute, registerRoute } from 'workbox-routing'
import { CacheFirst, StaleWhileRevalidate } from 'workbox-strategies'

// eslint-disable-next-line @typescript-eslint/no-explicit-any
declare const self: any

setCacheNameDetails({
  prefix: 'reactpwa-app',
  suffix: 'v0.0.1',
  precache: 'pre-cache',
  runtime: 'runtime-cache',
  googleAnalytics: 'ga-cache'
})

/**
 * Precaching
 */
cleanupOutdatedCaches()
precacheAndRoute(self.__WB_MANIFEST || [])

/**
 * Fallback to index.html on all url
 */
const defaultRouteHandler = createHandlerBoundToURL('/index.html')
const defaultNavigationRoute = new NavigationRoute(defaultRouteHandler, {
  // allowlist: [],
  // denylist: [],
})

registerRoute(defaultNavigationRoute)

/**
 * Specific routes strategies
 */
/**
const DAY_IN_SECONDS = 24 * 60 * 60
const MONTH_IN_SECONDS = DAY_IN_SECONDS * 30

registerRoute(
  new RegExp('.*.js'),
  new StaleWhileRevalidate({
    cacheName: 'js-cache',
    plugins: [
      new CacheableResponsePlugin({
        statuses: [0, 200]
      }),
      new ExpirationPlugin({
        maxAgeSeconds: MONTH_IN_SECONDS
      })
    ]
  })
)
registerRoute(
  new RegExp('.*.css'),
  new StaleWhileRevalidate({
    cacheName: 'css-cache',
    plugins: [
      new CacheableResponsePlugin({
        statuses: [0, 200]
      }),
      new ExpirationPlugin({
        maxAgeSeconds: MONTH_IN_SECONDS
      })
    ]
  })
)
registerRoute(
  new RegExp('.*.(png|gif|jpg|jpeg|svg|ico)'),
  new CacheFirst({
    cacheName: 'img-cache',
    plugins: [
      new CacheableResponsePlugin({
        statuses: [0, 200]
      }),
      new ExpirationPlugin({
        maxEntries: 250,
        maxAgeSeconds: 30 * MONTH_IN_SECONDS,
        purgeOnQuotaError: true
      })
    ]
  })
)

self.addEventListener('message', (event: { data: string }) => {
  if (!event.data) {
    return
  }

  switch (event.data) {
    case 'skipWaiting':
      self.skipWaiting()
      break
    case 'clientsClaim':
      self.clients.claim()
      break
    default:
      break
  }
})

Here is my second entry point for my app, which import workbox-window:

import React from 'react'
import { render } from 'react-dom'

import App from '@/app'

import routes from './app.routes'

const DOM_NODE: HTMLElement = document.querySelector('.appWrapper')

render(<App routes={routes} />, DOM_NODE)

async function registerSw(): Promise<void> {
  if ('serviceWorker' in navigator) {
    const { Workbox } = await import(/* webpackChunkName: 'workbox-window', webpackPreload: true */ 'workbox-window')

    const wb = new Workbox('/service-worker.js')

    wb.register()
  }
}

registerSw()

PS : Additionally, i'm falling into @typescript-eslint/no-unsafe-member-access and eslint-disable @typescript-eslint/no-unsafe-call in the service-worker.ts too ... Even if i added @types/

Here is my eslint config :

{
  "parser": "@typescript-eslint/parser",
  "plugins": ["@typescript-eslint", "react", "simple-import-sort", "prettier"],
  "parserOptions": {
    "project": "./tsconfig.json",
    "ecmaVersion": 2021,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true,
      "modules": true
    }
  },
  "env": {
    "es6": true,
    "browser": true,
    "node": true,
    "jest": true
  },
  "extends": [
    "eslint:recommended",
    "airbnb-typescript",
    "airbnb/hooks",
    "plugin:@typescript-eslint/recommended",
    "plugin:@typescript-eslint/recommended-requiring-type-checking",
    "plugin:react/recommended",
    "prettier/@typescript-eslint",
    "prettier/react",
    "prettier"
  ],
  "settings": {
    "react": {
      "createClass": "createReactClass",
      "pragma": "React",
      "version": "detect"
    },
    "propWrapperFunctions": ["forbidExtraProps"]
  },
  "rules": {
    "prettier/prettier": "error",
    "max-len": [
      2,
      {
        "code": 120,
        "tabWidth": 2,
        "ignoreUrls": true,
        "ignoreComments": true,
        "ignoreStrings": true,
        "ignoreTemplateLiterals": true,
        "ignoreRegExpLiterals": true
      }
    ],
    "padding-line-between-statements": [
      "error",
      {
        "blankLine": "always",
        "prev": ["const", "let"],
        "next": "*"
      },
      {
        "blankLine": "any",
        "prev": ["const", "let"],
        "next": ["const", "let"]
      }
    ],
    "no-console": 1,
    "semi": ["error", "never"],
    "comma-dangle": ["error", "never"],
    "import/no-extraneous-dependencies": [
      "error",
      {
        "devDependencies": true
      }
    ],
    "simple-import-sort/sort": "error",
    "sort-imports": "off",
    "import/first": "error",
    "import/newline-after-import": "error",
    "import/no-duplicates": "error",
    "react/static-property-placement": ["warn", "static public field"],
    "react/jsx-uses-react": "error",
    "react/jsx-props-no-spreading": "off",
    "@typescript-eslint/no-floating-promises": "off"
  },
  "globals": {
    "window": true,
    "document": true,
    "localStorage": true,
    "FormData": true,
    "FileReader": true,
    "Blob": true,
    "navigator": true,
    "workbox": true
  }
}

My dependencies :

    "typescript": "^4.0.3",
    "@types/workbox-build": "^5.0.0",
    "@types/workbox-cacheable-response": "^4.3.0",
    "@types/workbox-expiration": "^4.3.0",
    "@types/workbox-precaching": "^4.3.0",
    "@types/workbox-strategies": "^4.3.0",
    "@types/workbox-window": "^4.3.3",
    "@typescript-eslint/eslint-plugin": "^4.3.0",
    "@typescript-eslint/parser": "^4.3.0",
    "eslint": "^7.10.0",
    "eslint-config-airbnb-typescript": "^11.0.0",
    "eslint-config-prettier": "^6.12.0",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-jsx-a11y": "^6.3.1",
    "eslint-plugin-prettier": "^3.1.4",
    "eslint-plugin-react": "^7.21.2",
    "eslint-plugin-react-hooks": "^4.1.2",
    "eslint-plugin-simple-import-sort": "^5.0.3",
    "eslint-webpack-plugin": "^2.1.0",
    "workbox-cacheable-response": "^5.1.4",
    "workbox-core": "^5.1.4",
    "workbox-expiration": "^5.1.4",
    "workbox-precaching": "^5.1.4",
    "workbox-routing": "^5.1.4",
    "workbox-strategies": "^5.1.4",
    "workbox-window": "^5.1.4"
    "workbox-build": "^5.1.4"

😕

@jeffposnick
Copy link
Contributor

There are some known linting issues with the latest TypeScript and eslint releases, tracked in #2602

Regarding some of the other issues, I would avoid using the Definitely Typed definitions for the Workbox v5 runtime modules, which are native TypeScript code and can be used directly.

The errors about missing ExtendableEvent and a few other symbols are likely because you're explicitly setting

declare const self: any

in your service worker file, but self needs to be ServiceWorkerGlobalScope in order to find those symbols. There's also some guidance from the TypeScript team about including appropriate libraries in your TypeScript configuration when you're compiling a service worker:

{
  "compilerOptions": {
    "lib": [
      "webworker"
    ]
  }
}

Hopefully that combination of answers gets things working for you!

@blephy
Copy link
Author

blephy commented Oct 6, 2020

Thanks a lot, i will apply your recommendations and wait for workbox type def update

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants