Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@trusktr
Copy link
Member

@trusktr trusktr commented Mar 28, 2024

and adjust package.json so that types are picked up in consumer projects

Summary

The code base is still plain JS as before (the build did not change) but this now allows outputting declaration files so that consumers that can start to import Docsify via ES Modules with type definitions. This also type checks our own code (more details below), allowing us to improve our code base over time in a new way.

Related issue, if any:

What kind of change does this PR introduce?

Feature (dev experience)
Build-related changes (adds a build step that outputs declaration files, but otherwise does not change the build in any other way)

For any code change,

  • Related documentation has been updated, if needed
  • Related tests have been added or updated, if needed

Does this PR introduce a breaking change?

No

Tested in the following browsers:

  • Chrome
  • Firefox
  • Safari
  • Edge

Additional info

Several changes:

  • Improved types within Docsify source code
    • Improves many type definitions inside Docsify source code for our own sake, but many things are still inferred as type any and can be fixed later.
    • The noImplicitAny option is set to false in tsconfig.json to disable ~600 type errors that will otherwise happen.
  • Type support for consumers
    • This outputs types declaration files (files ending with .d.ts) alongside files in src/. We do not output types to dist/ because that conflicts with the folder structure there. The dist/ folder is only for the global build, and we may optionally place bundled ESM builds there later, but otherwise ESM imports are directly from src/ and the sibling output .d.ts files automatically provide type awareness for consuming TypeScript projects.
    • The src/ folder is now added to the files array in package.json.
    • The added tsconfig.json sets up TypeScript rules.
    • The new build:types scripts causes .d.ts and .d.ts.map files to be emitted next to .js files in src/. This step does not do anything with the .js files, those are handled in the pre-existing build separately.
      • The .d.ts files provide declarations for consumption, and the .d.ts.map files allow features like Go To Definition on Docsify APIs to take someone directly to the source definition in their IDEs.
    • There is a new test in test/consume-types which is a sample project that imports Docsify to bootstrap a Docsify site (see those files for more details).
      • We're not e2e testing the result of this sample project, but maybe we should. I verified the example manually.
      • This sample project does not have a build, it is vanilla ESM that runs in browser, witha few hacks for importing prismjs (which is in CommonJS format) and common-tags (which has bespoke import specifiers pointing to folders instead of JS files).
      • We can, and maybe should, make other sample projects later than use some common build tools to build Docsify into an app bundle, to verify imports are working well in JS ecosystem tooling.
    • The new test:consume-types script goes into test/consume-types directory, installs Docsify and Docsify's dependencies into its local node_modules, and runs type checking with TypeScript to verify the types are imported as expected via ESM.
      • This script is added to our CI.
  • new Docsify(config) API
    • Global APIs are against the grain of ESM code where globals are generally avoided, and working with global types with TypeScript in consumer projects would be a lot less ideal. So for people importing Docsify, they can now pass options directly to the Docsify constructor, while getting type checking and intellisense on all the available options:
      import {Docsify} from 'docsify'
      
      new Docsify({
        el: '#app',
        name: true,
        // ...etc...
      })
    • This is not the new Custom Element API we're planning, but is a middle ground so we can release something non-breaking in 5.0, which is already in release candidate.
      • We might be able to release a Custom Element API in 5.0 non-breaking, but if anything we can release that in 6.0.

@vercel
Copy link

vercel bot commented Mar 28, 2024

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
docsify-preview Ready Ready Preview Comment Nov 17, 2025 7:56am

@sy-records sy-records changed the title output type definitions chore: output type definitions Mar 28, 2024
@sy-records
Copy link
Member

Do these need to be fixed?

image

@trusktr
Copy link
Member Author

trusktr commented Mar 30, 2024

Not necessary to fix, the code works as-is. Looks like GitHub doing type checking. We can fix type errors as we go along.

Later we can make type definitions for the end users for the options, and for plugins, with nice docs when they hover in their editor.

sy-records
sy-records previously approved these changes Mar 31, 2024
@jhildenbiddle
Copy link
Member

jhildenbiddle commented Mar 31, 2024

Do these need to be fixed?

Yes. We should not merge code that fails our tests and automated checks, and we should not merge code assuming someone else will fix the issues later.

Not necessary to fix, the code works as-is.

When we merge code because it "works as-is" despite the fact that it produces errors, fails tests, or fails our automated checks, ever other maintainer is forced to deal with these issues while working locally and while reviewing subsequent PRs.

Copy link
Member

@jhildenbiddle jhildenbiddle left a comment

Choose a reason for hiding this comment

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

As I understand it, this PR is intended to support users who are consuming Docsify as an ESM module, correct?

If so, I don't think we should be distributing TypeScript definitions until end users are able to actually benefit from them. Since Docsify currently can not be consumed as an ESM module, there is no real-world benefit to generating a d.ts file. That may change in the future, but until then these changes only add complexity to the project and stand to confuse users who may wonder why we offer a d.ts file when there is no way to use it.

My concern here is with merging code to support future work that we don't have commitments for or documentation to support. I've implemented similar configurations in my own projects (e.g. mergician) so I am not opposed to the approach used in the PR. I simply prefer to see these changes incorporated as part of a larger "Docsify as ESM module" effort since the benefits of the changes in the PR are only realized when the larger effort is complete.

@trusktr trusktr marked this pull request as draft March 31, 2024 21:46
… package for people to start importing `Docsify` and passing in non-global configs
@Koooooo-7
Copy link
Member

IMO,for current propose to replace $docsify seems not necessary (module-lize).
WDYT?

@trusktr

This comment was marked as outdated.

@trusktr trusktr requested a review from jhildenbiddle April 2, 2024 07:13
@trusktr

This comment was marked as resolved.

Copy link
Member

@jhildenbiddle jhildenbiddle left a comment

Choose a reason for hiding this comment

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

I think this is a good example of why these types of changes should be introduced as either a new issue (better for triage/tracking) or discussion (better for higher-level discussions that produce issue(s) to track/triage) instead of a PR. What started off as a PR about generating TypeScript types has evolved into a discussion involving ESM modules, deprecating globals, and componentization. These are all good things to discuss, but the comments section of this PR is not the right place IMHO.

@trusktr -- There's some good stuff in here, so please don't take the above comment negatively. I am onboard with the core concepts of what is being proposed here, but I'd like us to align and execute efficiently since we have limited resources available. For example:

  • We cannot deprecate Docsify globals because we have agreed to keep v5 compatible with v4 with the exception of SSR and legacy browser support. Deprecating globals would therefore have to be targeted for a future release.
  • We could offer Docsify as an ESM export for v5 in addition to our current IIFE version, but if we do this we also have to consider if/how we export plugins and themes.
  • I like the idea of providing better IntelliSense for docsify configurations, but the implementation I would use is different than the one in this PR.

Can we create / move to separate issues so can align and triage?

  1. ESM export => New issue
    TypeScript / IntelliSense support can be part of this discussion.
  2. Docsify encapsulation => #2135
    I've updated this thread with high-level POC. Deprecation of globals can be part of this discussion.

Thanks!

@Koooooo-7
Copy link
Member

Hi Joe @trusktr , no offense.
I understand and respect that you did everything good for necessary changes like always (notification,warning and compatibility).

Based on current @jhildenbiddle mentioned here, I think I may have some misunderstood on the scope.

Is it a planning or something? If it were a planning, thats fine and we could have more discussions on it, I apologize that I declined it directly.
If it were a things you propose to do it now. Sorry that I don't see the clear context/roadmap more on the changes in the PR, so I don't we could get more benefit on the changes now, and it gets more breaking stuff, so I "voted" the -1 here for the changes.

If I do miss some details plz let me know.

@trusktr

This comment was marked as off-topic.

@trusktr
Copy link
Member Author

trusktr commented Nov 17, 2025

I've updated this PR with the latest from develop, and added an example of consuming ESM in a sample project in test/consume-types/ (it runs as part of the tests in CI to ensure types check out).

The basic idea is:

import {Docsify} from 'docsify'

// With type checking and intellisense, we can see the
// available Docsify options in our IDE.
new Docsify({
  el: '#app',
  // ...etc...
})

Now, this is not a custom element yet, but it's a middle ground: using globals is bad and not suitable for a good ESM TypeScript experience, so this PR makes it possible to consume the Docsify in an ESM project until we convert to a custom element (I'm imagining that'll may be v6) with type awareness and intellisense.

@trusktr
Copy link
Member Author

trusktr commented Nov 17, 2025

Aaaand, I broke something. But we're almost there. Must be a tiny change somewhere.

…s with noImplicitAny disabled which we'll fix later
… a test that ensures types are properly exported and consumable in TS ESM projects.
@trusktr trusktr marked this pull request as ready for review November 17, 2025 07:25
@trusktr trusktr requested review from a team and removed request for Koooooo-7 and sy-records November 17, 2025 07:47
@trusktr
Copy link
Member Author

trusktr commented Nov 17, 2025

When we merge code because it "works as-is" despite the fact that it produces errors, fails tests, or fails our automated checks, ever other maintainer is forced to deal with these issues while working locally and while reviewing subsequent PRs.

Yeah, of course. That wasn't the intent. The PR was in Draft mode, and lots of type issues.

Types have been updated (I updated the description with details).

All tests are green, including a new test to ensure types flow into consumer projects using the same project in test/consume-types.

The PR is now marked as ready.

@trusktr
Copy link
Member Author

trusktr commented Nov 17, 2025

  • We cannot deprecate Docsify globals because we have agreed to keep v5 compatible with v4 with the exception of SSR and legacy browser support. Deprecating globals would therefore have to be targeted for a future release.

Removed deprecation messages from global API. Makes sense, as ESM mode works but is not great yet (see the new test:consume-types).

  • We could offer Docsify as an ESM export for v5 in addition to our current IIFE version, but if we do this we also have to consider if/how we export plugins and themes.

The PR is doing this now in a way that doesn't conflict with global stuff.

  • I like the idea of providing better IntelliSense for docsify configurations, but the implementation I would use is different than the one in this PR.

What's the implementation?

@trusktr trusktr requested review from jhildenbiddle and sy-records and removed request for jhildenbiddle November 17, 2025 08:06
@trusktr
Copy link
Member Author

trusktr commented Nov 17, 2025

The only feature change of this PR is the ability to pass config directly to new Docsify(config). It's a way to use ESM without $docsify.

So the question is, do we want this?

These changes are non-breaking.

If we keep new Docsify(config), then later the Docsify class can just be a custom element with the same API when called with new, and it can then also be called via HTML as <docsify-app ...config...> as a non-breaking change for people who may have already adopted the new Docsify(config) format once we come out with the custom element.

Based on this, I propose we move forward because introducing the custom element API later can be non-breaking. This is a nice small stepping stone, if we agree.

I want to move forward more quickly, so if this doesn't get approved, we need a viable alternative to be presented so we're not waiting.

@trusktr
Copy link
Member Author

trusktr commented Nov 17, 2025

I think I may have some misunderstood on the scope.

@Koooooo-7 I updated the PR description.

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

Successfully merging this pull request may close these issues.

5 participants