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

refactor(theme-common): split package into public/internal API entrypoints #7660

Merged
merged 14 commits into from Jun 24, 2022

Conversation

slorber
Copy link
Collaborator

@slorber slorber commented Jun 22, 2022

Breaking change

  • Many @docusaurus/theme-common APIs have been moved to @docusaurus/theme-common/internal: if your swizzled components stop working, try updating the imports
  • APIs have not been renamed/refactored, so just changing the import might work
  • You might need to split the import in 2 parts (public/internal)

Pre-flight checklist

  • I have read the Contributing Guidelines on pull requests.
  • If this is a code change: I have written unit tests and/or added dogfooding pages to fully verify the new behavior.
  • If this is a new API or substantial change: the PR has an accompanying issue (closes #0000) and the maintainers have approved on my working plan.

Motivation

We want to make it more explicit which @docusaurus/theme-common APIs are public, and which are internal.

We'll maintain semver retrocompatibility only on public APIs.

Work in progress, details to be discussed.

IMHO there is 3 kind of APIs:

  • @docusaurus/theme-common public APIs with guaranteed retrocompatibility
    • documented: recommended APIs to use
    • undocumented: we ensure retro compatibility but don't encourage direct usage (on purpose)
  • @docusaurus/theme-common/internal private APIs on which we can safely do undocumented breaking changes

Test Plan

Preview keeps working

Test links

Deploy preview: https://deploy-preview-_____--docusaurus-2.netlify.app/

Related issues/PRs

v2.0 launch plan: #6113

@slorber slorber added the pr: breaking change Existing sites may not build successfully in the new version. Description contains more details. label Jun 22, 2022
@facebook-github-bot facebook-github-bot added the CLA Signed Signed Facebook CLA label Jun 22, 2022
@slorber slorber marked this pull request as draft June 22, 2022 17:09
@netlify
Copy link

netlify bot commented Jun 22, 2022

[V2]

Name Link
🔨 Latest commit bb151c0
🔍 Latest deploy log https://app.netlify.com/sites/docusaurus-2/deploys/62b57eb90b44d00008b0154c
😎 Deploy Preview https://deploy-preview-7660--docusaurus-2.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@github-actions
Copy link

github-actions bot commented Jun 22, 2022

⚡️ Lighthouse report for the deploy preview of this PR

URL Performance Accessibility Best Practices SEO PWA Report
/ 🟢 93 🟢 100 🟢 100 🟢 100 🟢 90 Report
/docs/installation 🟠 86 🟢 100 🟢 100 🟢 100 🟢 90 Report

@github-actions
Copy link

github-actions bot commented Jun 22, 2022

Size Change: -4 B (0%)

Total Size: 802 kB

ℹ️ View Unchanged
Filename Size Change
website/.docusaurus/globalData.json 52.6 kB 0 B
website/build/assets/css/styles.********.css 107 kB 0 B
website/build/assets/js/main.********.js 604 kB -4 B (0%)
website/build/index.html 38.9 kB 0 B

compressed-size-action

Copy link
Collaborator

@Josh-Cena Josh-Cena left a comment

Choose a reason for hiding this comment

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

My idea is we don't have to be too conservative about marking APIs as public. General utilities should definitely be public. I feel like we should have more public APIs than internal ones. I marked those that I have the strongest opinions about, but we need to think about every one of them, probably make a ranking.

Some other thoughts:

  1. We definitely can select certain "interesting" utilities to document while only keeping others retro-compatible (i.e. safe for eject) without documentation
  2. "Public" can mean three things:
    • External theme authors are encouraged to use these
    • Site creators are encouraged to use these in their custom pages
    • Safe for swizzle eject

packages/docusaurus-theme-common/src/index.ts Outdated Show resolved Hide resolved
packages/docusaurus-theme-common/src/index.ts Outdated Show resolved Hide resolved
packages/docusaurus-theme-common/src/internal.ts Outdated Show resolved Hide resolved
Comment on lines +84 to +88
export {
useFilteredAndTreeifiedTOC,
useTreeifiedTOC,
type TOCTreeNode,
} from './utils/tocUtils';
Copy link
Collaborator

Choose a reason for hiding this comment

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

At least useTreeifiedTOC is very useful

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

useTreeifiedTOC is not used in any theme component, only useFilteredAndTreeifiedTOC is, which does feel like a weird name that we may want to change currently. Similarly, not sure i's useful to publicly commit to retro-compatibility on apis that even our own theme does not use. In the end we want the TOC components to be safe to swizzle, and in this case it doesn't help.

I would be ok to expose a unique useTOCTree(array, options) or something later, but this requires some refactoring.

I want to keep this PR clean from refactors: focusing only on splitting private/internal that we are ready to expose right now, as is.

What I mean is that we can do extra refactors in subsequent PRs, and it's not a big deal if this one API is not public immediately.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I once planned to document useTreeifiedTOC in #6729, because it's no longer possible to pick arbitrary TOC subtrees so users need to implement this themselves. But I agree the API is not perfect yet and can benefit from some more refactors.

packages/docusaurus-theme-common/src/internal.ts Outdated Show resolved Hide resolved
packages/docusaurus-theme-common/src/index.ts Show resolved Hide resolved
packages/docusaurus-theme-common/src/index.ts Outdated Show resolved Hide resolved
packages/docusaurus-theme-common/src/internal.ts Outdated Show resolved Hide resolved
packages/docusaurus-theme-common/src/internal.ts Outdated Show resolved Hide resolved
@Josh-Cena Josh-Cena changed the title refactor(theme): split @docusaurus/theme-common into public/internal apis refactor(theme): split @docusaurus/theme-common into public/internal APIs Jun 22, 2022
@Josh-Cena Josh-Cena changed the title refactor(theme): split @docusaurus/theme-common into public/internal APIs refactor(theme-common): split into public/internal APIs Jun 23, 2022
@slorber
Copy link
Collaborator Author

slorber commented Jun 23, 2022

My idea is we don't have to be too conservative about marking APIs as public. General utilities should definitely be public. I feel like we should have more public APIs than internal ones.

Agree on that.
I just do not want to mark everything as public right now in this very PR so that we can at least move on and not delay merge with too many discussions.
But we can continue to move more internal APIs to public in subsequent PRs for sure 👍

Some other thoughts:

  1. We definitely can select certain "interesting" utilities to document while only keeping others retro-compatible (i.e. safe for eject) without documentation

  2. "Public" can mean three things:

    • External theme authors are encouraged to use these
    • Site creators are encouraged to use these in their custom pages
    • Safe for swizzle eject

Looks similar to what I had in mind, except I grouped the first 2 cases as "documented APIs" (~= encouraged usage)


Note this PR somehow split APIs to document from APIs to not document. We may not 100% agree on this split yet, but it's not a big deal as those are not documented yet 🤪 We'll refine that later on a case-by-case basis, for now I just wanted to have an initial set of public APIs extracted

@slorber slorber marked this pull request as ready for review June 23, 2022 20:00
Comment on lines +1 to +32
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import fs from 'fs-extra';

// See comment in src/internal.ts
// This script should be run by CI tests to remove:
// export * from './index'

const filePath = 'lib/internal.js';
const lineToRemove = "export * from './index';\n";

if (!(await fs.pathExists(filePath))) {
throw new Error(`internal entrypoint file not found at ${filePath}`);
}

const fileContent = await fs.readFile(filePath, 'utf8');

const fileContentUpdated = fileContent.replaceAll(lineToRemove, '');

// Ensure the script correctly removes the re-export
if (fileContent === fileContentUpdated) {
throw new Error(
'Unexpected: internal re-export has not been replaced.\nMake sure this script works, and is only run once.',
);
}

await fs.writeFile(filePath, fileContentUpdated);
Copy link
Collaborator Author

@slorber slorber Jun 23, 2022

Choose a reason for hiding this comment

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

this idea is a bit convoluted but it looks to work fine 🤪

The error message is not very visible though 😓

CleanShot 2022-06-23 at 22 00 05@2x

Copy link
Collaborator

Choose a reason for hiding this comment

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

Lol, this looks like pure hack... Since we are to automate the marking of ejection safety by analyzing dependency on /internal APIs, we can simply reuse the same analyzer. I'll investigate that later.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes 😅 maybe we'll remove this in the future once we have more public APIs

But this is not exactly the same problem: If a component is unsafe, it should still preferably import from the public endpoint instead of the internal re-export.

@slorber
Copy link
Collaborator Author

slorber commented Jun 23, 2022

any concern to merge this?

We can move internal -> public and document things in subsequent PRs

Copy link
Collaborator

@Josh-Cena Josh-Cena left a comment

Choose a reason for hiding this comment

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

Almost good—last concern.

type NavbarSecondaryMenuComponent,
} from './contexts/navbarSecondaryMenu/content';
export {useNavbarSecondaryMenu} from './contexts/navbarSecondaryMenu/display';
export {duplicates, uniq} from './utils/jsUtils';

export {useBackToTopButton} from './hooks/useBackToTopButton';
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this really stable? We have a lot of "wiring hooks" like useAnnouncementBar, useNavbarMobileSidebar, etc., and this is the only public one.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Moved to internal for now as I'm not 100% satisfied with the api, but we'll have to figure out how to make all these public on a case-by-case basis to ensure we can safely swizzle the related components.

Copy link
Collaborator

@Josh-Cena Josh-Cena left a comment

Choose a reason for hiding this comment

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

LGTM—I think this is a good starting point and there's plenty to document already.

@slorber slorber changed the title refactor(theme-common): split into public/internal APIs refactor(theme-common): split package into public/internal API entrypoints Jun 24, 2022
@slorber slorber merged commit 9473508 into main Jun 24, 2022
@slorber slorber deleted the slorber/theme-common-internal-export branch June 24, 2022 09:21
arisac added a commit to arisac/docusaurus-boilerplate that referenced this pull request Jul 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed Signed Facebook CLA pr: breaking change Existing sites may not build successfully in the new version. Description contains more details.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants