vuejs / vitepress

Vite & Vue powered static site generator.
https://vitepress.dev
MIT License
11.48k stars 1.86k forks source link

`client` and `theme` are not `exported` from `exports` field in `package.json` #913

Closed JounQin closed 1 year ago

JounQin commented 1 year ago

Hi! πŸ‘‹

Firstly, thanks for your work on this project! πŸ™‚

Today I used patch-package to patch vitepress@1.0.0-alpha.4 for the project I'm working on.

Here is the diff that solved my problem:

diff --git a/node_modules/vitepress/package.json b/node_modules/vitepress/package.json
index bc579de..68da516 100644
--- a/node_modules/vitepress/package.json
+++ b/node_modules/vitepress/package.json
@@ -12,7 +12,9 @@
       "import": "./dist/node/index.js",
       "require": "./dist/node-cjs/index.cjs"
     },
-    "./dist/client/*": "./dist/client/*"
+    "./dist/client/*": "./dist/client/*",
+    "./client": "./client.d.ts",
+    "./theme": "./theme.d.ts"
   },
   "bin": {
     "vitepress": "bin/vitepress.js"

This issue body was partially generated by patch-package.

brc-dd commented 1 year ago

Can you tell what error(s) were you getting? I don't think types need to be in exports.

JounQin commented 1 year ago

Can you tell what error(s) were you getting? I don't think types need to be in exports.

// docs/.vitepress/theme/index.ts
import type { Theme } from 'vitepress'
import DefaultTheme from 'vitepress/theme'

import * as components from '../components'

import './index.less'

const theme: Theme = {
  ...DefaultTheme,
  enhanceApp({ app }) {
    for (const [name, Component] of Object.entries(components))
      app.component(name, Component)
  },
}

export default theme

We do have "types": "./types/index.d.ts" in exports fields.

When using strict node16 or nodenext TypeScript moduleResolution, vitepress/theme must be defined in exports.

See https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#package-json-exports-imports-and-self-referencing for more details.

JounQin commented 1 year ago

Although I'm not quite sure to understand why import DefaultTheme from 'vitepress/theme' would work (it's a .d.ts right?):

import DefaultTheme from 'vitepress/theme'

console.log('DefaultTheme:', DefaultTheme)
image

It is documented at https://vitepress.vuejs.org/guide/theme-introduction.html#extending-the-default-theme

JounQin commented 1 year ago

OK, I found vitepress/theme is transformed into the following on client:

import DefaultTheme from "/@fs/Users/JounQin/Workspaces/Alauda/vision/node_modules/vitepress/dist/client/theme-default/index.js";
console.log("DefaultTheme:", DefaultTheme);

So vitepress/theme actually points to vitepress/dist/client/theme-default/index.js

JounQin commented 1 year ago

OK, finally, this is a TypeScript usage related issue. @brc-dd

brc-dd commented 1 year ago

Yeah but your fix is still throwing this error in my case:

Module 'vitepress/theme' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.

Without that fix, I was getting:

Cannot find module 'vitepress/theme' or its corresponding type declarations.

JounQin commented 1 year ago

Yeah but your fix is still throwing this error in my case:

Module 'vitepress/theme' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.

Without that fix, I was getting:

Cannot find module 'vitepress/theme' or its corresponding type declarations.

What command can I run to reproduce on this project?

JounQin commented 1 year ago

And did you try my new fix?

image
brc-dd commented 1 year ago

https://github.com/brc-dd/vp-issue

Yeah I have those changes:

image

JounQin commented 1 year ago

OK, I'll check it ASAP.

JounQin commented 1 year ago

@brc-dd That's because there is no type: "module" field in package.json, so .ts will be compiled as cjs, and we have no cjs entry for vitepress/theme, you can update package.json with type: 'module', or add a new private package.json under .vitepress with:

{
  "private": true,
  "type": "module"
}

Then, the .vitepress/theme/index.ts will be considered as ESM correctly.

image

Both "Go to Definition" and "Go to Source Definition" will work as expected at the same time.

JounQin commented 1 year ago

@brc-dd See https://github.com/brc-dd/vp-issue/pull/1 for demo.

JounQin commented 1 year ago

Besides, export const VPHomeHero = ComponentOptions in theme.d.ts seems absolutely wrong, actually, it should be export const VPHomeHero: ComponentOptions, should I fix this in the same PR or a separated one?

brc-dd commented 1 year ago

Besides, export const VPHomeHero = ComponentOptions in theme.d.ts seems absolutely wrong, actually, it should be export const VPHomeHero: ComponentOptions, should I fix this in the same PR or a separated one?

This is fixed on vite 3 branch.

JounQin commented 1 year ago

This is fixed on vite 3 branch.

Glad to hear.


@brc-dd

Besides, do you think is there any chance how can I apply to be a member or collaborator or vite/vitepress groups? I'd like to spend more time working on vite/vitepress in the next few days.