vuepress / core

Vue-Powered Static Site Generator
https://vuepress.vuejs.org
MIT License
2.17k stars 922 forks source link

[Proposal]: Deprecate vuepress-vite and vuepress-webpack #1446

Closed Mister-Hope closed 6 months ago

Mister-Hope commented 7 months ago

Clear and concise description of the problem

Useless packages

vuepress-vite and vuepress-webpack are just be used as alias of calling bundler vite/webpack. ( I am not seeing any different use case from downstream. If a user want an advanced usage to "programly call vuepress in scripts", they all choose to import @vuepress/cli and handle the process themselves.

So under this situation I think vuepress-vite and vuepress-webpack are a bit useless as users install them only for the vuepress-vite and vuepress-webpack bin.

Version mismatch

Also users often complains version mismatch. Vue solves this by reexporting pacakges at vue, e.g.: vue/reactivity for @vue/reactivity export, vue/compiler-sfc for @vue/compiler-sfc. We can do this too.

Suggested solution

Currently, if we drop support of yarn1, and only support pnpm>7 npm>8, we can use optionalPeers feature.

This solves the problem that users often triggers a version mismatch with vuepress, and is extactly what vue is doing.

We should deprecate vuepress-vite and vuepress-package, and set @vuepress/bundler-vite and @vuepress/bundler-webpack as optional peers. Also, we can reexport core markdown client shared in vuepress:

{
  "name": "vuepress",
  // ...
  "exports": {
    ".": "./dist/index.js",
    "./bin": "./bin/vuepress.js",
    // a reexport of @vuepress/core
    "./core": "./dist/core.js",
    // a reexport of @vuepress/client
    "./client": "./dist/client.js",
    // a reexport of @vuepress/markdown
    "./markdown": "./dist/markdown.js",
    // a reexport of @vuepress/shared
    "./shared": "./dist/shared.js",
    // a reexport of @vuepress/utils
    "./utils": "./dist/utils.js",
    "./package.json": "./package.json"
  },
  "dependencies": {
    "@vuepress/core": "workspace:*",
    "@vuepress/client": "workspace:*",
    "@vuepress/markdown": "workspace:*",
    "@vuepress/shared": "workspace:*",
    "@vuepress/utils": "workspace:*"
  },
  "peerDependencies": {
    "@vuepress/bundler-vite": "workspace:*",
    "@vuepress/bundler-webpack": "workspace:*",
    "vue": "^3.3.4"
  },
  "peerDependenciesMeta": {
    "@vuepress/bundler-vite": {
      "optional": true
    },
    "@vuepress/bundler-webpack": {
      "optional": true
    },
  }
}

We can then provide try catch to perform bundler detecting/requiring and a new bundler flag if users are missing bundler field.

# when both bundlers are installed and no bundler field in config file
vuepress dev src --bundler vite
vueress dev src --bundler webpack

# use vite by default
vuepress dev src

When users only install 1 bundler, we use that bundler for him.

# automatically use the installed bundler
vuepress dev src

When users install no bundler, we throw an error:

vuepress dev src
❌vuepress: No bundler package found, install @vuepress/bundler-vite or @vuepress/bundler-webpack

The re-export helps avoid the version mismatch problem and simple plugin/theme deps:

// client
import { xxx } from 'vuepress/client';
// node
import { xxx } from 'vuepress/core';
import { xxx } from 'vuepress/utils'
// package.json
{
  "name": "vuepress-plugin-xxx",
  "dependencies": {
    "vuepress": "^2.1.1"
  },
  "peerDependencies": {
    // ensures the user installed one is matching the requirement
    // modern package manager also knows that this means the plugin want to require the same pkg as peer
    "vuepress": "^2.1.1"
  }
}
meteorlxy commented 6 months ago

This proposal also requires a create helper