vuejs / vitepress

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

Better support for `type: "module"` from user #917

Closed JounQin closed 1 year ago

JounQin commented 1 year ago

Is your feature request related to a problem? Please describe.

The outputs ESM entries are not fully compatible with native ESM actually, take the following as example

https://unpkg.com/browse/vitepress@1.0.0-alpha.4/dist/client/index.js

All relative file paths should be ended with correct .js extension, and /index.js can not be omitted anymore.

That's being said, we should use moduleResolution: "Node16" instead.

And when the user enables type: "module" in their package.json or .vitepress/package.json, all temporary .js files in .vitepress/.temp would be considered as ESM only, and now it would emit error:

vitepress v1.0.0-alpha.4
- building client + server bundles...
@alauda/chart doesn't appear to be written in CJS, but also doesn't appear to be a valid ES module (i.e. it doesn't have "type": "module" or an .mjs extension for the entry point). Please contact the package author to fix.
quill-image-uploader doesn't appear to be written in CJS, but also doesn't appear to be a valid ES module (i.e. it doesn't have "type": "module" or an .mjs extension for the entry point). Please contact the package author to fix.
✓ building client + server bundles...
- rendering pages...
✖ rendering pages...
build error:
 ReferenceError: exports is not defined in ES module scope
This file is being treated as an ES module because it has a '.js' file extension and '/home/jenkins/agent/workspace/frontend/frontend-vision-docs/docs/.vitepress/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
    at file:///home/jenkins/agent/workspace/frontend/frontend-vision-docs/docs/.vitepress/.temp/app.js:2:25
    at ModuleJob.run (node:internal/modules/esm/module_job:195:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:337:24)
    at async renderPage (file:///home/jenkins/agent/workspace/frontend/frontend-vision-docs/node_modules/vitepress/dist/node/serve-05342c3d.js:39534:25)
    at async build (file:///home/jenkins/agent/workspace/frontend/frontend-vision-docs/node_modules/vitepress/dist/node/serve-05342c3d.js:39853:9)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
script returned exit code 1

Describe the solution you'd like

Enable moduleResolution: "Node16" and add a package.json into .vitepress/.temp with type: "commonjs" for now, and migrate all outputs files as pure ESM later.

Describe alternatives you've considered

We can use .cjs files extensions for files outputs in .vitepress/.temp

Additional context

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

Validations

brc-dd commented 1 year ago

Can you try with the chore/vite-3 branch? Most of the ESM related issues are fixed there.

JounQin commented 1 year ago

Can you try with the chore/vite-3 branch? Most of the ESM related issues are fixed there.

I don't think so?

https://github.com/vuejs/vitepress/blob/chore/vite-3/src/node/index.ts

For example, no .js extensions are added.

brc-dd commented 1 year ago

That file is processed by Rollup which adds the extensions. In dist/client, there aren't any extensions, because we don't need them there. Those files are used by VIte which understands that stuff in ESM contexts too. Try testing it out locally (pnpm i && pnpm docs-build && pnpm pack, pnpm add -D path/to/vitepress.tgz), it should work with type: module in your package.json.

keqing77 commented 1 year ago

Can you try with the chore/vite-3 branch? Most of the ESM related issues are fixed there.

I don't think so?

https://github.com/vuejs/vitepress/blob/chore/vite-3/src/node/index.ts

For example, no .js extensions are added.

I also encountered this problem when I run yarn docs:build, and don't know how to solute it , Because none of the files in my project have the .js extension , How can I rename.js to .cjs😰, at first I think it is vue-eslint-parser cause , but seem to doesn't work😥

keqing77 commented 1 year ago

I remove the config "type": "module", in package.json and it works , image

JounQin commented 1 year ago

I remove the config "type": "module", in package.json and it works , image

It's not a solution. 😂

brc-dd commented 1 year ago

Actually, I had tried applying moduleResolution: nodenext on client only (node part already has extensions on imports). Got everything to work except for the docsearch package. That package has certain issues with that mode.

JounQin commented 1 year ago

@brc-dd

moduleResolution: nodenext is not the thing, type: "module" in user's package.json is.

brc-dd commented 1 year ago

moduleResolution: nodenext is not the thing, type: "module" in user's package.json is.

I meant in VitePress' tsconfig (to resolve this issue).

JounQin commented 1 year ago

moduleResolution: nodenext is not the thing, type: "module" in user's package.json is.

I meant in VitePress' tsconfig (to resolve this issue).

Oh, right, thanks for fixing this issue.

brc-dd commented 1 year ago

Oh, right, thanks for fixing this issue.

I tried but I'm still not able to fix this because of some issue with @docsearch/js. Probably has something to do with its exports or the (broken) types they are generating. In main, we are patching its types. In chore/vite3, I removed those stuff as its typings are somewhat better now, but IG to support this we'd have to again do the ugly stuff.

JounQin commented 1 year ago

Is chore/vite3 the branch you're working on? I'd like to take a look to see whether there is anything I can help.

brc-dd commented 1 year ago

Is chore/vite3 the branch you're working on?

Yeah, chore/vite-3. But that moduleResolution thing is not there as I wasn't able to make it work.

JounQin commented 1 year ago

OK, I'll add it locally and manually.

JounQin commented 1 year ago

@brc-dd See #1136

brc-dd commented 1 year ago

Okay, so now there is another issue. VitePress is unable to resolve custom theme if its in TS (and user has not added moduleResolution: nodenext to their tsconfig.json) :/

JounQin commented 1 year ago

Okay, so now there is another issue. VitePress is unable to resolve custom theme if its in TS (and user has not added moduleResolution: nodenext to their tsconfig.json) :/

I'm not sure why? Can it be tested easily?

brc-dd commented 1 year ago

Can it be tested easily?

git clone https://github.com/vuejs/vitepress -b chore/vite-3
cd vitepress
pnpm i && pnpm build && pnpm pack
cd ..
mkdir foo
cd foo
pnpm add -D ../vitepress/vitepress-1.0.0-alpha.4.tgz vue typescript
mkdir .vitepress
mkdir .vitepress/theme
echo "export { default } from 'vitepress/theme'" >.vitepress/theme/index.ts
echo "# Hello VitePress" > index.md
pnpm vitepress build
brc-dd commented 1 year ago

I'm not sure why?

Probably has something to with our aliases.

JounQin commented 1 year ago

I'm not sure why?

Probably has something to with our aliases.

Thanks, I'll take a look tonight.

Lexpeartha commented 1 year ago

Any progress on the issue? It's currently blocking me from setting up CI/CD pipeline

JounQin commented 1 year ago

It seems I definitely forgot about this issue, I'll spend some time on it tonight.

Sorry, no time again.