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

Block Editor: Add BlockContext component to type-checking #22353

Merged
merged 2 commits into from
May 18, 2020

Conversation

aduth
Copy link
Member

@aduth aduth commented May 14, 2020

Closes #21666

This pull request seeks to opt in the BlockContext component (introduced in #21467) to be type-checked. It was previously planned for #21467 but removed due to blocking incompatibilities of #21767. These incompatibilities have since been resolved in #21781, so the type-checking can once again be enabled.

Testing Instructions:

Ensure type checking passes:

npm run build:package-types

@aduth aduth added Good First Review A PR that's suitable for someone looking to contribute for the first time by reviewing code [Package] Block editor /packages/block-editor labels May 14, 2020
@aduth
Copy link
Member Author

aduth commented May 14, 2020

The build caught an error, which I wasn't seeing locally when running npm run build:package-types.

Eventually I could reproduce it by first forcibly removing existing build-types folders and .tsbuildinfo files:

rm -r packages/**/build-types packages/**/*.tsbuildinfo
packages/block-editor/src/components/block-context/index.js:4:52 - error TS7016: Could not find a declaration file for module '@wordpress/element'. '/Users/andrew/Documents/Code/gutenberg/packages/element/build/index.js' implicitly has an 'any' type.
  Try `npm install @types/wordpress__element` if it exists or add a new declaration (.d.ts) file containing `declare module '@wordpress/element';`

4 import { createContext, useContext, useMemo } from '@wordpress/element';
                                                     ~~~~~~~~~~~~~~~~~~~~

It seems there may have been some caching that was preventing the error from being logged.

It's clear enough what the solution is (including the dependencies in references), but definitely lose a bit of trust in npm run build:package-types to be reliable. At least it's caught in continuous integration.

cc @sirreal

@github-actions
Copy link

Size Change: +10 B (0%)

Total Size: 833 kB

Filename Size Change
build/components/index.js 182 kB +10 B (0%)
ℹ️ View Unchanged
Filename Size Change
build/a11y/index.js 1.02 kB 0 B
build/annotations/index.js 3.62 kB 0 B
build/api-fetch/index.js 3.39 kB 0 B
build/autop/index.js 2.83 kB 0 B
build/blob/index.js 620 B 0 B
build/block-directory/index.js 6.59 kB 0 B
build/block-directory/style-rtl.css 764 B 0 B
build/block-directory/style.css 764 B 0 B
build/block-editor/index.js 104 kB 0 B
build/block-editor/style-rtl.css 10.8 kB 0 B
build/block-editor/style.css 10.8 kB 0 B
build/block-library/editor-rtl.css 7.25 kB 0 B
build/block-library/editor.css 7.25 kB 0 B
build/block-library/index.js 118 kB 0 B
build/block-library/style-rtl.css 7.48 kB 0 B
build/block-library/style.css 7.49 kB 0 B
build/block-library/theme-rtl.css 683 B 0 B
build/block-library/theme.css 685 B 0 B
build/block-serialization-default-parser/index.js 1.88 kB 0 B
build/block-serialization-spec-parser/index.js 3.1 kB 0 B
build/blocks/index.js 48.1 kB 0 B
build/components/style-rtl.css 17.1 kB 0 B
build/components/style.css 17 kB 0 B
build/compose/index.js 6.68 kB 0 B
build/core-data/index.js 11.4 kB 0 B
build/data-controls/index.js 1.29 kB 0 B
build/data/index.js 8.43 kB 0 B
build/date/index.js 5.47 kB 0 B
build/deprecated/index.js 772 B 0 B
build/dom-ready/index.js 568 B 0 B
build/dom/index.js 3.1 kB 0 B
build/edit-navigation/index.js 5.6 kB 0 B
build/edit-navigation/style-rtl.css 618 B 0 B
build/edit-navigation/style.css 617 B 0 B
build/edit-post/index.js 28.2 kB 0 B
build/edit-post/style-rtl.css 12.2 kB 0 B
build/edit-post/style.css 12.2 kB 0 B
build/edit-site/index.js 12 kB 0 B
build/edit-site/style-rtl.css 5.22 kB 0 B
build/edit-site/style.css 5.22 kB 0 B
build/edit-widgets/index.js 8.47 kB 0 B
build/edit-widgets/style-rtl.css 4.69 kB 0 B
build/edit-widgets/style.css 4.69 kB 0 B
build/editor/editor-styles-rtl.css 425 B 0 B
build/editor/editor-styles.css 428 B 0 B
build/editor/index.js 44.3 kB 0 B
build/editor/style-rtl.css 5.07 kB 0 B
build/editor/style.css 5.08 kB 0 B
build/element/index.js 4.65 kB 0 B
build/escape-html/index.js 733 B 0 B
build/format-library/index.js 7.63 kB 0 B
build/format-library/style-rtl.css 502 B 0 B
build/format-library/style.css 502 B 0 B
build/hooks/index.js 2.13 kB 0 B
build/html-entities/index.js 622 B 0 B
build/i18n/index.js 3.56 kB 0 B
build/is-shallow-equal/index.js 712 B 0 B
build/keyboard-shortcuts/index.js 2.51 kB 0 B
build/keycodes/index.js 1.94 kB 0 B
build/list-reusable-blocks/index.js 3.13 kB 0 B
build/list-reusable-blocks/style-rtl.css 226 B 0 B
build/list-reusable-blocks/style.css 226 B 0 B
build/media-utils/index.js 5.29 kB 0 B
build/notices/index.js 1.79 kB 0 B
build/nux/index.js 3.4 kB 0 B
build/nux/style-rtl.css 616 B 0 B
build/nux/style.css 613 B 0 B
build/plugins/index.js 2.56 kB 0 B
build/primitives/index.js 1.5 kB 0 B
build/priority-queue/index.js 789 B 0 B
build/redux-routine/index.js 2.85 kB 0 B
build/rich-text/index.js 14.8 kB 0 B
build/server-side-render/index.js 2.68 kB 0 B
build/shortcode/index.js 1.7 kB 0 B
build/token-list/index.js 1.28 kB 0 B
build/url/index.js 4.02 kB 0 B
build/viewport/index.js 1.84 kB 0 B
build/warning/index.js 1.14 kB 0 B
build/wordcount/index.js 1.18 kB 0 B

compressed-size-action

@sirreal
Copy link
Member

sirreal commented May 14, 2020

The build caught an error, which I wasn't seeing locally when running npm run build:package-types.

The error was that the reference omitted? This results in the missing declarations when building a dependent module?

Eventually I could reproduce it by first forcibly removing existing build-types folders and .tsbuildinfo files:

rm -r packages/**/build-types packages/**/*.tsbuildinfo

Aside: This is effective. It should be roughly analogous to npm run clean:package-types (which runs tsc --build --clean).

It seems there may have been some caching that was preventing the error from being logged.

It's clear enough what the solution is (including the dependencies in references), but definitely lose a bit of trust in npm run build:package-types to be reliable. At least it's caught in continuous integration.

The references are the only way tsc knows how projects interdepend. It sounds like you had a types built locally which tsc was able to find and use. There's nothing like auto-discovery via lerna or package.json for TypeScript references as far as I know.

This has popped up a few times. We could probably lint for this by verifying that references aligns with @wordpress/* file dependencies in packages' package.json. I'm undecided how much value that would add.

@@ -4,10 +4,14 @@
"rootDir": "src",
"declarationDir": "build-types"
},
"references": [
{ "path": "../element" }
],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This actually depends on a bunch of things:

"@wordpress/a11y": "file:../a11y",
"@wordpress/blob": "file:../blob",
"@wordpress/blocks": "file:../blocks",
"@wordpress/components": "file:../components",
"@wordpress/compose": "file:../compose",
"@wordpress/data": "file:../data",
"@wordpress/deprecated": "file:../deprecated",
"@wordpress/dom": "file:../dom",
"@wordpress/element": "file:../element",
"@wordpress/hooks": "file:../hooks",
"@wordpress/html-entities": "file:../html-entities",
"@wordpress/i18n": "file:../i18n",
"@wordpress/icons": "file:../icons",
"@wordpress/is-shallow-equal": "file:../is-shallow-equal",
"@wordpress/keyboard-shortcuts": "file:../keyboard-shortcuts",
"@wordpress/keycodes": "file:../keycodes",
"@wordpress/priority-queue": "file:../priority-queue",
"@wordpress/rich-text": "file:../rich-text",
"@wordpress/shortcode": "file:../shortcode",
"@wordpress/token-list": "file:../token-list",
"@wordpress/url": "file:../url",
"@wordpress/viewport": "file:../viewport",
"@wordpress/wordcount": "file:../wordcount",

We should add the packages that are typed already at least.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This actually depends on a bunch of things:

That package as a whole does, sure. Currently we only type-check two files, for which this references set is accurate. I guess it can save us some future work if we just go ahead and add all of the dependencies now?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is interesting to consider…

I've been thinking of the TypeScript project as corresponding to the JavaScript project, but in this case it really doesn't. It's a small subset of the block-editor package. As such, it has a subset of the dependencies.

I don't feel strongly about this one way or the other.

@aduth
Copy link
Member Author

aduth commented May 14, 2020

@sirreal There may be a misunderstanding. My concern isn't that there is an error. My concern was that there was no error for me locally, but then the error appeared in continuous integration. And only after the series of steps above was I finally able to reproduce the error locally.

tl;dr: I got a false negative when testing locally.

@sirreal
Copy link
Member

sirreal commented May 14, 2020

I don't think there's a misunderstanding, but we may have different perspectives and not share the same concerns 🙂

Here's how I'm looking at this:

  • A project was misconfigured, missing a reference. This project is a bit interesting because it doesn't (and cannot) list all of it's package's dependencies: Block Editor: Add BlockContext component to type-checking #22353 (comment) (an observation, not pointing fingers)
  • TypeScript doesn't build (if missing) or rebuild (if stale) the dependencies when building.
  • Locally, TypeScript checks the types by using the declaration files it finds.
  • Pre-existing (and potentially stale) declarations were used for typechecking.
  • CI encounters the issue because the dependency was not built before the dependent. This is because CI is not caching the declaration files at all.

It seems that this all stems from a misconfiguration that we can attempt to prevent in the future or to accept as a risk not worth mitigating because the difficulty or maintenance of the mitigation outweighs the severity.

Even on CI, it's possible that through other dependencies or simple race conditions, the dependencies would happen to be built by the time the declarations were required.

Note that there's a tradeoff here. We could clean and rebuild types every run, but I've anecdotally observed that rebuilding from scratch can take upwards of forty seconds whereas reusing valid incremental builds is virtually instantaneous.

If we decide to mitigate, how could we prevent issues like this?

  • Somehow enforce that every package-level tsconfig.json declare all the monorepo file dependencies as references. With this package in particular, we'd need some logic like "if it depends on another package that has a tsconfig, it should be listed in the references" because not all the dependencies of this package are TypeScript projects right now. Requires implementing and maintaining a script to handle this.
  • Clean the TypeScript build more frequently. Here we move the tradeoff from speed to accuracy.
  • We could clean and build each project in isolation:
    npm run clean:package-types
    npm run build:package-types -- packages/block-editor/
    
    I'd expect this to be very good at detecting this issue, but quite slow. Something like this could run as a scheduled job on CI.

I don't foresee this type of problem being very severe, but I may be wrong. This is mostly intuition. I'd expect problems of this sort either surface rather quickly or be harmless for the most part.

@aduth
Copy link
Member Author

aduth commented May 18, 2020

🤷 I just want a type-checking command that I can trust.

@aduth aduth merged commit 85bd059 into master May 18, 2020
@aduth aduth deleted the update/21666-block-context-types branch May 18, 2020 19:28
@github-actions github-actions bot added this to the Gutenberg 8.2 milestone May 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Good First Review A PR that's suitable for someone looking to contribute for the first time by reviewing code [Package] Block editor /packages/block-editor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Block Editor: BlockContext: Opt-in BlockContext component to type checking
3 participants