diff --git a/.eslintrc.cjs b/.eslintrc.cjs
index 961fe199582d87..629aedd122aae4 100644
--- a/.eslintrc.cjs
+++ b/.eslintrc.cjs
@@ -73,6 +73,10 @@ module.exports = defineConfig({
'@typescript-eslint/ban-ts-comment': 'off', // TODO: we should turn this on in a new PR
'@typescript-eslint/ban-types': 'off', // TODO: we should turn this on in a new PR
+ '@typescript-eslint/explicit-module-boundary-types': [
+ 'error',
+ { allowArgumentsExplicitlyTypedAsAny: true }
+ ],
'@typescript-eslint/no-empty-function': [
'error',
{ allow: ['arrowFunctions'] }
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 013794932f334c..248bb3fbedd101 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -48,7 +48,7 @@ jobs:
uses: actions/checkout@v3
- name: Install pnpm
- uses: pnpm/action-setup@v2
+ uses: pnpm/action-setup@v2.2.2
- name: Set node version to ${{ matrix.node_version }}
uses: actions/setup-node@v3
@@ -87,7 +87,7 @@ jobs:
fetch-depth: 0
- name: Install pnpm
- uses: pnpm/action-setup@v2
+ uses: pnpm/action-setup@v2.2.2
- name: Set node version to 16
uses: actions/setup-node@v3
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index cc91df0ed32f7c..5b26ca1a4697ce 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -18,7 +18,7 @@ jobs:
uses: actions/checkout@v3
- name: Install pnpm
- uses: pnpm/action-setup@v2
+ uses: pnpm/action-setup@v2.2.2
- name: Set node version to 16.x
uses: actions/setup-node@v3
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4fdc71fe42f0f0..71a4aa09841ebe 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -214,6 +214,8 @@ Vite aims to be fully usable as a dependency in a TypeScript project (e.g. it sh
To get around this, we inline some of these dependencies' types in `packages/vite/types`. This way we can still expose the typing but bundle the dependency's source code.
+Use `pnpm run check-dist-types` to check bundled types does not rely on types in `devDependencies`. If you are adding `dependencies`, make sure to configure `tsconfig.check.json`.
+
### Think before adding yet another option
We already have many config options, and we should avoid fixing an issue by adding yet another one. Before adding an option, try to think about:
diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts
index 8f0bdb8ef613f1..1a729dc3237553 100644
--- a/docs/.vitepress/config.ts
+++ b/docs/.vitepress/config.ts
@@ -35,7 +35,7 @@ export default defineConfig({
},
carbonAds: {
- carbon: 'CEBIEK3N',
+ code: 'CEBIEK3N',
placement: 'vitejsdev'
},
@@ -53,9 +53,9 @@ export default defineConfig({
},
nav: [
- { text: 'Guide', link: '/guide/' },
- { text: 'Config', link: '/config/' },
- { text: 'Plugins', link: '/plugins/' },
+ { text: 'Guide', link: '/guide/', activeMatch: '/guide/' },
+ { text: 'Config', link: '/config/', activeMatch: '/config/' },
+ { text: 'Plugins', link: '/plugins/', activeMatch: '/plugins/' },
{
text: 'Links',
items: [
diff --git a/docs/.vitepress/theme/components/AsideSponsors.vue b/docs/.vitepress/theme/components/AsideSponsors.vue
new file mode 100644
index 00000000000000..9c90fcca3750a6
--- /dev/null
+++ b/docs/.vitepress/theme/components/AsideSponsors.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
diff --git a/docs/.vitepress/theme/components/HomeSponsors.vue b/docs/.vitepress/theme/components/HomeSponsors.vue
index 5eec6e1d8cd5cb..16ea073b423820 100644
--- a/docs/.vitepress/theme/components/HomeSponsors.vue
+++ b/docs/.vitepress/theme/components/HomeSponsors.vue
@@ -9,6 +9,7 @@ const { data } = useSponsor()
diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts
index ec9259a0ee08a5..3b4d7e38df76ab 100644
--- a/docs/.vitepress/theme/index.ts
+++ b/docs/.vitepress/theme/index.ts
@@ -1,14 +1,15 @@
import { h } from 'vue'
import Theme from 'vitepress/theme'
import './styles/vars.css'
-import './styles/custom.css'
import HomeSponsors from './components/HomeSponsors.vue'
+import AsideSponsors from './components/AsideSponsors.vue'
export default {
...Theme,
Layout() {
return h(Theme.Layout, null, {
- 'home-features-after': () => h(HomeSponsors)
+ 'home-features-after': () => h(HomeSponsors),
+ 'aside-ads-before': () => h(AsideSponsors)
})
}
}
diff --git a/docs/.vitepress/theme/styles/custom.css b/docs/.vitepress/theme/styles/custom.css
deleted file mode 100644
index 69671d732acc5c..00000000000000
--- a/docs/.vitepress/theme/styles/custom.css
+++ /dev/null
@@ -1,15 +0,0 @@
-@media (min-width: 640px) {
- .VPHero .text {
- max-width: 592px;
- }
-
- .VPHero .tagline {
- max-width: 440px;
- }
-}
-
-@media (min-width: 960px) {
- .VPHero .tagline {
- max-width: 480px;
- }
-}
diff --git a/docs/.vitepress/theme/styles/vars.css b/docs/.vitepress/theme/styles/vars.css
index 938bf984656ec3..feacdfcd2dfd4d 100644
--- a/docs/.vitepress/theme/styles/vars.css
+++ b/docs/.vitepress/theme/styles/vars.css
@@ -38,6 +38,25 @@
#bd34fe 30%,
#41d1ff
);
+
+ --vp-home-hero-image-background-image: linear-gradient(
+ -45deg,
+ #bd34fe 50%,
+ #47caff 50%
+ );
+ --vp-home-hero-image-filter: blur(40px);
+}
+
+@media (min-width: 640px) {
+ :root {
+ --vp-home-hero-image-filter: blur(56px);
+ }
+}
+
+@media (min-width: 960px) {
+ :root {
+ --vp-home-hero-image-filter: blur(72px);
+ }
}
/**
diff --git a/docs/guide/env-and-mode.md b/docs/guide/env-and-mode.md
index a0b5400182fe4e..4b37e5549fcd11 100644
--- a/docs/guide/env-and-mode.md
+++ b/docs/guide/env-and-mode.md
@@ -16,7 +16,7 @@ Vite exposes env variables on the special **`import.meta.env`** object. Some bui
During production, these env variables are **statically replaced**. It is therefore necessary to always reference them using the full static string. For example, dynamic key access like `import.meta.env[key]` will not work.
-It will also replace these strings appearing in JavaScript strings and Vue templates. This should be a rare case, but it can be unintended. You may see errors like `Missing Semicolon` or `Unexpected token` in this case, for example when `"process.env.NODE_ENV: "` is transformed to `""development": "`. There are ways to work around this behavior:
+It will also replace these strings appearing in JavaScript strings and Vue templates. This should be a rare case, but it can be unintended. You may see errors like `Missing Semicolon` or `Unexpected token` in this case, for example when `"process.env.``NODE_ENV"` is transformed to `""development": "`. There are ways to work around this behavior:
- For JavaScript strings, you can break the string up with a Unicode zero-width space, e.g. `'import.meta\u200b.env.MODE'`.
diff --git a/docs/guide/index.md b/docs/guide/index.md
index ab45ceb7f85475..d5d20d80094b1e 100644
--- a/docs/guide/index.md
+++ b/docs/guide/index.md
@@ -116,7 +116,7 @@ Running `vite` starts the dev server using the current working directory as root
In a project where Vite is installed, you can use the `vite` binary in your npm scripts, or run it directly with `npx vite`. Here are the default npm scripts in a scaffolded Vite project:
-```json5
+```json
{
"scripts": {
"dev": "vite", // start dev server, aliases: `vite dev`, `vite serve`
diff --git a/docs/index.md b/docs/index.md
index 05a85262022650..40e6df844db31a 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -1,10 +1,16 @@
---
layout: home
+title: Vite
+titleTemplate: Next Generation Frontend Tooling
+
hero:
name: Vite
text: Next Generation Frontend Tooling
tagline: Get ready for a development environment that can finally catch up with you.
+ image:
+ src: /logo-with-shadow.png
+ alt: Vite
actions:
- theme: brand
text: Get Started
diff --git a/docs/public/logo-with-shadow.png b/docs/public/logo-with-shadow.png
new file mode 100644
index 00000000000000..8b23c919ed7b9c
Binary files /dev/null and b/docs/public/logo-with-shadow.png differ
diff --git a/package.json b/package.json
index 6dde8708780745..5811ce3f6f519d 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,7 @@
"scripts": {
"preinstall": "npx only-allow pnpm",
"format": "prettier --write .",
- "lint": "eslint packages/*/{src,types}/** playground/**/__tests__/**/*.ts scripts/**",
+ "lint": "eslint packages/*/{src,types,__tests__}/** playground/**/__tests__/**/*.ts scripts/**",
"typecheck": "tsc -p scripts --noEmit && tsc -p playground --noEmit",
"test": "run-s test-unit test-serve test-build",
"test-serve": "vitest run -c vitest.config.e2e.ts",
@@ -88,7 +88,7 @@
"typescript": "^4.6.4",
"unbuild": "^0.7.4",
"vite": "workspace:*",
- "vitepress": "1.0.0-draft.4",
+ "vitepress": "1.0.0-draft.8",
"vitest": "^0.12.9",
"vue": "^3.2.35"
},
diff --git a/packages/create-vite/__tests__/cli.spec.ts b/packages/create-vite/__tests__/cli.spec.ts
index fbfb606f486885..d9b6bafdefa306 100644
--- a/packages/create-vite/__tests__/cli.spec.ts
+++ b/packages/create-vite/__tests__/cli.spec.ts
@@ -1,9 +1,8 @@
-/* eslint-disable node/no-extraneous-import */
+import { join } from 'path'
import type { ExecaSyncReturnValue, SyncOptions } from 'execa'
import { commandSync } from 'execa'
import { mkdirpSync, readdirSync, remove, writeFileSync } from 'fs-extra'
-import { join } from 'path'
-import { test, expect, beforeAll, afterEach } from 'vitest'
+import { afterEach, beforeAll, expect, test } from 'vitest'
const CLI_PATH = join(__dirname, '..')
diff --git a/packages/plugin-legacy/src/index.ts b/packages/plugin-legacy/src/index.ts
index ed2c4a24820a61..3a9fb253d4658a 100644
--- a/packages/plugin-legacy/src/index.ts
+++ b/packages/plugin-legacy/src/index.ts
@@ -517,7 +517,7 @@ export async function detectPolyfills(
code: string,
targets: any,
list: Set
-) {
+): Promise {
const babel = await loadBabel()
const { ast } = babel.transform(code, {
ast: true,
diff --git a/packages/vite/CHANGELOG.md b/packages/vite/CHANGELOG.md
index 3a7c2d42f24eaa..c8bea7c58ca913 100644
--- a/packages/vite/CHANGELOG.md
+++ b/packages/vite/CHANGELOG.md
@@ -1,3 +1,19 @@
+## 3.0.0-alpha.7 (2022-05-27)
+
+* fix: preserve annotations during build deps optimization (#8358) ([334cd9f](https://github.com/vitejs/vite/commit/334cd9f)), closes [#8358](https://github.com/vitejs/vite/issues/8358)
+* refactor: `ExportData.imports` to `ExportData.hasImports` (#8355) ([168de2d](https://github.com/vitejs/vite/commit/168de2d)), closes [#8355](https://github.com/vitejs/vite/issues/8355)
+
+
+
+## 3.0.0-alpha.6 (2022-05-27)
+
+* fix: missing types for `es-module-lexer` (fixes #8349) (#8352) ([df2cc3d](https://github.com/vitejs/vite/commit/df2cc3d)), closes [#8349](https://github.com/vitejs/vite/issues/8349) [#8352](https://github.com/vitejs/vite/issues/8352)
+* fix(optimizer): transpile before calling `transformGlobImport` (#8343) ([1dbc7cc](https://github.com/vitejs/vite/commit/1dbc7cc)), closes [#8343](https://github.com/vitejs/vite/issues/8343)
+* feat: scan free dev server (#8319) ([3f742b6](https://github.com/vitejs/vite/commit/3f742b6)), closes [#8319](https://github.com/vitejs/vite/issues/8319)
+* chore: remove unused dts from dist (#8346) ([de9f556](https://github.com/vitejs/vite/commit/de9f556)), closes [#8346](https://github.com/vitejs/vite/issues/8346)
+
+
+
## 3.0.0-alpha.5 (2022-05-26)
* feat: non-blocking esbuild optimization at build time (#8280) ([909cf9c](https://github.com/vitejs/vite/commit/909cf9c)), closes [#8280](https://github.com/vitejs/vite/issues/8280)
diff --git a/packages/vite/package.json b/packages/vite/package.json
index 5db998d0c295dd..1d3460d58dd3dd 100644
--- a/packages/vite/package.json
+++ b/packages/vite/package.json
@@ -1,6 +1,6 @@
{
"name": "vite",
- "version": "3.0.0-alpha.5",
+ "version": "3.0.0-alpha.7",
"type": "module",
"license": "MIT",
"author": "Evan You",
@@ -49,10 +49,11 @@
"dev": "rimraf dist && pnpm run build-bundle -w",
"build": "rimraf dist && run-s build-bundle build-types",
"build-bundle": "rollup --config rollup.config.ts --configPlugin typescript",
- "build-types": "run-s build-temp-types patch-types roll-types",
+ "build-types": "run-s build-temp-types patch-types roll-types check-dist-types",
"build-temp-types": "tsc --emitDeclarationOnly --outDir temp/node -p src/node",
"patch-types": "esno scripts/patchTypes.ts",
"roll-types": "api-extractor run && rimraf temp",
+ "check-dist-types": "tsc --project tsconfig.check.json",
"lint": "eslint --ext .ts src/**",
"format": "prettier --write --parser typescript \"src/**/*.ts\"",
"prepublishOnly": "npm run build"
diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts
index b178ba9825d4b2..d80f5a60583abc 100644
--- a/packages/vite/src/node/config.ts
+++ b/packages/vite/src/node/config.ts
@@ -871,7 +871,7 @@ async function loadConfigFromBundledFile(
return config
}
-export function isDepsOptimizerEnabled(config: ResolvedConfig) {
+export function isDepsOptimizerEnabled(config: ResolvedConfig): boolean {
const { command, optimizeDeps } = config
const { disabled } = optimizeDeps
return !(
diff --git a/packages/vite/src/node/optimizer/esbuildDepPlugin.ts b/packages/vite/src/node/optimizer/esbuildDepPlugin.ts
index 4bf5c8b1c2152b..0c32af75219438 100644
--- a/packages/vite/src/node/optimizer/esbuildDepPlugin.ts
+++ b/packages/vite/src/node/optimizer/esbuildDepPlugin.ts
@@ -171,20 +171,15 @@ export function esbuildDepPlugin(
}
let contents = ''
- const data = exportsData[id]
- const [imports, exports] = data
- if (!imports.length && !exports.length) {
+ const { hasImports, exports, hasReExports } = exportsData[id]
+ if (!hasImports && !exports.length) {
// cjs
contents += `export default require("${relativePath}");`
} else {
if (exports.includes('default')) {
contents += `import d from "${relativePath}";export default d;`
}
- if (
- data.hasReExports ||
- exports.length > 1 ||
- exports[0] !== 'default'
- ) {
+ if (hasReExports || exports.length > 1 || exports[0] !== 'default') {
contents += `\nexport * from "${relativePath}"`
}
}
diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts
index 3cece89d1d7676..4f4231354e0a6a 100644
--- a/packages/vite/src/node/optimizer/index.ts
+++ b/packages/vite/src/node/optimizer/index.ts
@@ -31,12 +31,15 @@ const isDebugEnabled = _debug('vite:deps').enabled
const jsExtensionRE = /\.js$/i
const jsMapExtensionRE = /\.js\.map$/i
-export type ExportsData = ReturnType & {
+export type ExportsData = {
+ hasImports: boolean
+ exports: readonly string[]
+ facade: boolean
// es-module-lexer has a facade detection but isn't always accurate for our
// use case when the module has default export
- hasReExports?: true
+ hasReExports?: boolean
// hint if the dep requires loading as jsx
- jsxLoader?: true
+ jsxLoader?: boolean
}
export interface DepsOptimizer {
@@ -62,6 +65,13 @@ export interface DepOptimizationOptions {
* vite project root. This will overwrite default entries inference.
*/
entries?: string | string[]
+ /**
+ * Enable esbuild based scan phase, to get back to the optimized deps discovery
+ * strategy used in Vite v2
+ * @default false
+ * @experimental
+ */
+ devScan?: boolean
/**
* Force optimize listed dependencies (must be resolvable import paths,
* cannot be globs).
@@ -475,7 +485,7 @@ export async function runOptimizeDeps(
splitting: true,
sourcemap: true,
outdir: processingCacheDir,
- ignoreAnnotations: true,
+ ignoreAnnotations: resolvedConfig.command !== 'build',
metafile: true,
define,
plugins: [
@@ -585,19 +595,22 @@ export function newDepOptimizationProcessing(): DepOptimizationProcessing {
// Convert to { id: src }
export function depsFromOptimizedDepInfo(
depsInfo: Record
-) {
+): Record {
return Object.fromEntries(
Object.entries(depsInfo).map((d) => [d[0], d[1].src!])
)
}
-export function getOptimizedDepPath(id: string, config: ResolvedConfig) {
+export function getOptimizedDepPath(
+ id: string,
+ config: ResolvedConfig
+): string {
return normalizePath(
path.resolve(getDepsCacheDir(config), flattenId(id) + '.js')
)
}
-export function getDepsCacheDir(config: ResolvedConfig) {
+export function getDepsCacheDir(config: ResolvedConfig): string {
const dirName = config.command === 'build' ? 'depsBuild' : 'deps'
return normalizePath(path.resolve(config.cacheDir, dirName))
}
@@ -607,11 +620,16 @@ function getProcessingDepsCacheDir(config: ResolvedConfig) {
return normalizePath(path.resolve(config.cacheDir, dirName))
}
-export function isOptimizedDepFile(id: string, config: ResolvedConfig) {
+export function isOptimizedDepFile(
+ id: string,
+ config: ResolvedConfig
+): boolean {
return id.startsWith(getDepsCacheDir(config))
}
-export function createIsOptimizedDepUrl(config: ResolvedConfig) {
+export function createIsOptimizedDepUrl(
+ config: ResolvedConfig
+): (url: string) => boolean {
const { root } = config
const depsCacheDir = getDepsCacheDir(config)
@@ -740,7 +758,6 @@ export async function extractExportsData(
config: ResolvedConfig
): Promise {
await init
- let exportsData: ExportsData
const esbuildOptions = config.optimizeDeps?.esbuildOptions ?? {}
if (config.optimizeDeps.extensions?.some((ext) => filePath.endsWith(ext))) {
@@ -753,34 +770,48 @@ export async function extractExportsData(
write: false,
format: 'esm'
})
- exportsData = parse(result.outputFiles[0].text) as ExportsData
- } else {
- const entryContent = fs.readFileSync(filePath, 'utf-8')
- try {
- exportsData = parse(entryContent) as ExportsData
- } catch {
- const loader = esbuildOptions.loader?.[path.extname(filePath)] || 'jsx'
- debug(
- `Unable to parse: ${filePath}.\n Trying again with a ${loader} transform.`
- )
- const transformed = await transformWithEsbuild(entryContent, filePath, {
- loader
- })
- // Ensure that optimization won't fail by defaulting '.js' to the JSX parser.
- // This is useful for packages such as Gatsby.
- esbuildOptions.loader = {
- '.js': 'jsx',
- ...esbuildOptions.loader
- }
- exportsData = parse(transformed.code) as ExportsData
- exportsData.jsxLoader = true
+ const [imports, exports, facade] = parse(result.outputFiles[0].text)
+ return {
+ hasImports: imports.length > 0,
+ exports,
+ facade
}
- for (const { ss, se } of exportsData[0]) {
- const exp = entryContent.slice(ss, se)
- if (/export\s+\*\s+from/.test(exp)) {
- exportsData.hasReExports = true
- }
+ }
+
+ let parseResult: ReturnType
+ let usedJsxLoader = false
+
+ const entryContent = fs.readFileSync(filePath, 'utf-8')
+ try {
+ parseResult = parse(entryContent)
+ } catch {
+ const loader = esbuildOptions.loader?.[path.extname(filePath)] || 'jsx'
+ debug(
+ `Unable to parse: ${filePath}.\n Trying again with a ${loader} transform.`
+ )
+ const transformed = await transformWithEsbuild(entryContent, filePath, {
+ loader
+ })
+ // Ensure that optimization won't fail by defaulting '.js' to the JSX parser.
+ // This is useful for packages such as Gatsby.
+ esbuildOptions.loader = {
+ '.js': 'jsx',
+ ...esbuildOptions.loader
}
+ parseResult = parse(transformed.code)
+ usedJsxLoader = true
+ }
+
+ const [imports, exports, facade] = parseResult
+ const exportsData: ExportsData = {
+ hasImports: imports.length > 0,
+ exports,
+ facade,
+ hasReExports: imports.some(({ ss, se }) => {
+ const exp = entryContent.slice(ss, se)
+ return /export\s+\*\s+from/.test(exp)
+ }),
+ jsxLoader: usedJsxLoader
}
return exportsData
}
@@ -802,9 +833,9 @@ function needsInterop(
) {
return true
}
- const [imports, exports] = exportsData
+ const { hasImports, exports } = exportsData
// entry has no ESM syntax - likely CJS or UMD
- if (!exports.length && !imports.length) {
+ if (!exports.length && !hasImports) {
return true
}
diff --git a/packages/vite/src/node/optimizer/optimizer.ts b/packages/vite/src/node/optimizer/optimizer.ts
index ed950264684663..d1846903d95269 100644
--- a/packages/vite/src/node/optimizer/optimizer.ts
+++ b/packages/vite/src/node/optimizer/optimizer.ts
@@ -34,7 +34,9 @@ const debounceMs = 100
const depsOptimizerMap = new WeakMap()
-export function getDepsOptimizer(config: ResolvedConfig) {
+export function getDepsOptimizer(
+ config: ResolvedConfig
+): DepsOptimizer | undefined {
// Workers compilation shares the DepsOptimizer from the main build
return depsOptimizerMap.get(config.mainConfig || config)
}
@@ -46,6 +48,8 @@ export async function initDepsOptimizer(
const { logger } = config
const isBuild = config.command === 'build'
+ const scan = config.command !== 'build' && config.optimizeDeps.devScan
+
const sessionTimestamp = Date.now().toString()
const cachedMetadata = loadCachedDepOptimizationMetadata(config)
@@ -100,7 +104,7 @@ export async function initDepsOptimizer(
// If there wasn't a cache or it is outdated, we need to prepare a first run
let firstRunCalled = !!cachedMetadata
if (!cachedMetadata) {
- if (isBuild) {
+ if (!scan) {
// Initialize discovered deps with manually added optimizeDeps.include info
const discovered = await initialProjectDependencies(
config,
@@ -460,9 +464,14 @@ export async function initDepsOptimizer(
exportsData: extractExportsData(resolved, config)
})
- // Debounced rerun, let other missing dependencies be discovered before
- // the running next optimizeDeps
- if (!isBuild) {
+ // Until the first optimize run is called, avoid triggering processing
+ // We'll wait until the user codebase is eagerly processed by Vite so
+ // we can get a list of every missing dependency before giving to the
+ // browser a dependency that may be outdated, thus avoiding full page reloads
+
+ if (scan || firstRunCalled) {
+ // Debounced rerun, let other missing dependencies be discovered before
+ // the running next optimizeDeps
debouncedProcessing()
}
diff --git a/packages/vite/src/node/optimizer/scan.ts b/packages/vite/src/node/optimizer/scan.ts
index 6f609991ecc7fb..63d2d265e10e27 100644
--- a/packages/vite/src/node/optimizer/scan.ts
+++ b/packages/vite/src/node/optimizer/scan.ts
@@ -3,7 +3,7 @@ import path from 'path'
import { performance } from 'perf_hooks'
import glob from 'fast-glob'
import type { Loader, OnLoadResult, Plugin } from 'esbuild'
-import { build } from 'esbuild'
+import { build, transform } from 'esbuild'
import colors from 'picocolors'
import type { ResolvedConfig } from '..'
import {
@@ -299,17 +299,26 @@ function esbuildScanPlugin(
const key = `${path}?id=${scriptId++}`
if (contents.includes('import.meta.glob')) {
+ let transpiledContents
+ // transpile because `transformGlobImport` only expects js
+ if (loader !== 'js') {
+ transpiledContents = (await transform(contents, { loader }))
+ .code
+ } else {
+ transpiledContents = contents
+ }
+
scripts[key] = {
- loader: 'js',
+ loader: 'js', // since it is transpiled
contents:
(
await transformGlobImport(
- contents,
+ transpiledContents,
path,
config.root,
resolve
)
- )?.s.toString() || contents
+ )?.s.toString() || transpiledContents
}
} else {
scripts[key] = {
diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts
index 45ff0525b1042d..a8112d48658091 100644
--- a/packages/vite/src/node/plugins/css.ts
+++ b/packages/vite/src/node/plugins/css.ts
@@ -1197,7 +1197,7 @@ async function minifyCSS(css: string, config: ResolvedConfig) {
}
}
-export async function hoistAtRules(css: string) {
+export async function hoistAtRules(css: string): Promise {
const s = new MagicString(css)
const cleanCss = emptyCssComments(css)
let match: RegExpExecArray | null
diff --git a/packages/vite/src/node/plugins/importAnalysis.ts b/packages/vite/src/node/plugins/importAnalysis.ts
index 93da02147ae854..5d2fce4ad13e02 100644
--- a/packages/vite/src/node/plugins/importAnalysis.ts
+++ b/packages/vite/src/node/plugins/importAnalysis.ts
@@ -52,7 +52,10 @@ import {
optimizedDepNeedsInterop
} from '../optimizer'
import { checkPublicFile } from './asset'
-import { ERR_OUTDATED_OPTIMIZED_DEP } from './optimizedDeps'
+import {
+ ERR_OUTDATED_OPTIMIZED_DEP,
+ delayDepsOptimizerUntil
+} from './optimizedDeps'
import { isCSSRequest, isDirectCSSRequest } from './css'
const isDebug = !!process.env.DEBUG
@@ -61,7 +64,7 @@ const debug = createDebugger('vite:import-analysis')
const clientDir = normalizePath(CLIENT_DIR)
const skipRE = /\.(map|json)$/
-export const canSkipImportAnalysis = (id: string) =>
+export const canSkipImportAnalysis = (id: string): boolean =>
skipRE.test(id) || isDirectCSSRequest(id)
const optimizedDepChunkRE = /\/chunk-[A-Z0-9]{8}\.js/
@@ -186,7 +189,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
let s: MagicString | undefined
const str = () => s || (s = new MagicString(source))
const importedUrls = new Set()
- const staticImportedUrls = new Set()
+ const staticImportedUrls = new Set<{ url: string; id: string }>()
const acceptedUrls = new Set<{
url: string
start: number
@@ -466,7 +469,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
importedUrls.add(urlWithoutBase)
if (!isDynamicImport) {
// for pre-transforming
- staticImportedUrls.add(urlWithoutBase)
+ staticImportedUrls.add({ url: urlWithoutBase, id: resolvedId })
}
} else if (!importer.startsWith(clientDir) && !ssr) {
// check @vite-ignore which suppresses dynamic import warning
@@ -605,13 +608,14 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
)
// pre-transform known direct imports
+ // TODO: we should also crawl dynamic imports
if (config.server.preTransformRequests && staticImportedUrls.size) {
- staticImportedUrls.forEach((url) => {
+ staticImportedUrls.forEach(({ url, id }) => {
url = unwrapId(removeImportQuery(url)).replace(
NULL_BYTE_PLACEHOLDER,
'\0'
)
- transformRequest(url, server, { ssr }).catch((e) => {
+ const request = transformRequest(url, server, { ssr }).catch((e) => {
if (e?.code === ERR_OUTDATED_OPTIMIZED_DEP) {
// This are expected errors
return
@@ -619,6 +623,9 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
// Unexpected error, log the issue but avoid an unhandled exception
config.logger.error(e.message)
})
+ if (!config.optimizeDeps.devScan) {
+ delayDepsOptimizerUntil(config, id, () => request)
+ }
})
}
diff --git a/packages/vite/src/node/plugins/importMetaGlob.ts b/packages/vite/src/node/plugins/importMetaGlob.ts
index b624d7e609bcb1..4a6c97e09150eb 100644
--- a/packages/vite/src/node/plugins/importMetaGlob.ts
+++ b/packages/vite/src/node/plugins/importMetaGlob.ts
@@ -33,7 +33,10 @@ export interface ParsedImportGlob {
end: number
}
-export function getAffectedGlobModules(file: string, server: ViteDevServer) {
+export function getAffectedGlobModules(
+ file: string,
+ server: ViteDevServer
+): ModuleNode[] {
const modules: ModuleNode[] = []
for (const [id, allGlobs] of server._importGlobMap!) {
if (allGlobs.some((glob) => isMatch(file, glob)))
@@ -501,7 +504,7 @@ export function getCommonBase(globsResolved: string[]): null | string {
return commonAncestor
}
-export function isVirtualModule(id: string) {
+export function isVirtualModule(id: string): boolean {
// https://vitejs.dev/guide/api-plugin.html#virtual-modules-convention
return id.startsWith('virtual:') || id.startsWith('\0') || !id.includes('/')
}
diff --git a/packages/vite/src/node/plugins/optimizedDeps.ts b/packages/vite/src/node/plugins/optimizedDeps.ts
index db206ef7e319e1..49bcc69bf6f25e 100644
--- a/packages/vite/src/node/plugins/optimizedDeps.ts
+++ b/packages/vite/src/node/plugins/optimizedDeps.ts
@@ -16,7 +16,7 @@ const debug = createDebugger('vite:optimize-deps')
const runOptimizerIfIdleAfterMs = 100
interface RunProcessingInfo {
- ids: { id: string; done: () => Promise }[]
+ ids: { id: string; done: () => Promise }[]
seenIds: Set
workersSources: Set
waitingOn: string | undefined
@@ -43,7 +43,10 @@ function getRunProcessingInfo(config: ResolvedConfig): RunProcessingInfo {
)
}
-export function registerWorkersSource(config: ResolvedConfig, id: string) {
+export function registerWorkersSource(
+ config: ResolvedConfig,
+ id: string
+): void {
const info = getRunProcessingInfo(config)
info.workersSources.add(id)
if (info.waitingOn === id) {
@@ -51,11 +54,11 @@ export function registerWorkersSource(config: ResolvedConfig, id: string) {
}
}
-function delayDepsOptimizerUntil(
+export function delayDepsOptimizerUntil(
config: ResolvedConfig,
id: string,
- done: () => Promise
-) {
+ done: () => Promise
+): void {
const info = getRunProcessingInfo(config)
if (
!getDepsOptimizer(config)?.isOptimizedDepFile(id) &&
@@ -98,6 +101,22 @@ export function optimizedDepsPlugin(config: ResolvedConfig): Plugin {
return {
name: 'vite:optimized-deps',
+ buildStart() {
+ if (!config.isWorker) {
+ initRunProcessingInfo(config)
+ }
+ },
+
+ async resolveId(id) {
+ if (getDepsOptimizer(config)?.isOptimizedDepFile(id)) {
+ return id
+ }
+ },
+
+ // this.load({ id }) isn't implemented in PluginContainer
+ // The logic to register an id to wait until it is processed
+ // is in importAnalysis, see call to delayDepsOptimizerUntil
+
async load(id) {
const depsOptimizer = getDepsOptimizer(config)
if (depsOptimizer?.isOptimizedDepFile(id)) {
diff --git a/packages/vite/src/node/plugins/splitVendorChunk.ts b/packages/vite/src/node/plugins/splitVendorChunk.ts
index 1ce53eaeb5a259..bc319b01586dab 100644
--- a/packages/vite/src/node/plugins/splitVendorChunk.ts
+++ b/packages/vite/src/node/plugins/splitVendorChunk.ts
@@ -27,7 +27,7 @@ export class SplitVendorChunkCache {
constructor() {
this.cache = new Map()
}
- reset() {
+ reset(): void {
this.cache = new Map()
}
}
diff --git a/packages/vite/src/node/server/hmr.ts b/packages/vite/src/node/server/hmr.ts
index 23ed627a79f3e6..5a0616dbb643e7 100644
--- a/packages/vite/src/node/server/hmr.ts
+++ b/packages/vite/src/node/server/hmr.ts
@@ -34,14 +34,14 @@ export interface HmrContext {
server: ViteDevServer
}
-export function getShortName(file: string, root: string) {
+export function getShortName(file: string, root: string): string {
return file.startsWith(root + '/') ? path.posix.relative(root, file) : file
}
export async function handleHMRUpdate(
file: string,
server: ViteDevServer
-): Promise {
+): Promise {
const { ws, config, moduleGraph } = server
const shortFile = getShortName(file, config.root)
const fileName = path.basename(file)
@@ -130,7 +130,7 @@ export function updateModules(
modules: ModuleNode[],
timestamp: number,
{ config, ws }: ViteDevServer
-) {
+): void {
const updates: Update[] = []
const invalidatedModules = new Set()
let needFullReload = false
@@ -425,7 +425,7 @@ export function lexAcceptedHmrDeps(
function error(pos: number) {
const err = new Error(
- `import.meta.accept() can only accept string literals or an ` +
+ `import.meta.hot.accept() can only accept string literals or an ` +
`Array of string literals.`
) as RollupError
err.pos = pos
diff --git a/packages/vite/src/node/server/sourcemap.ts b/packages/vite/src/node/server/sourcemap.ts
index 97ee26668d741c..d38c992f7155a2 100644
--- a/packages/vite/src/node/server/sourcemap.ts
+++ b/packages/vite/src/node/server/sourcemap.ts
@@ -59,7 +59,7 @@ export async function injectSourcesContent(
}
}
-export function genSourceMapUrl(map: SourceMap | string | undefined) {
+export function genSourceMapUrl(map: SourceMap | string | undefined): string {
if (typeof map !== 'string') {
map = JSON.stringify(map)
}
@@ -70,7 +70,7 @@ export function getCodeWithSourcemap(
type: 'js' | 'css',
code: string,
map: SourceMap | null
-) {
+): string {
if (isDebug) {
code += `\n/*${JSON.stringify(map, null, 2).replace(/\*\//g, '*\\/')}*/\n`
}
diff --git a/packages/vite/src/node/ssr/ssrExternal.ts b/packages/vite/src/node/ssr/ssrExternal.ts
index c6be41bd990e01..512ec038a21244 100644
--- a/packages/vite/src/node/ssr/ssrExternal.ts
+++ b/packages/vite/src/node/ssr/ssrExternal.ts
@@ -20,7 +20,7 @@ const debug = createDebugger('vite:ssr-external')
/**
* Converts "parent > child" syntax to just "child"
*/
-export function stripNesting(packages: string[]) {
+export function stripNesting(packages: string[]): string[] {
return packages.map((s) => {
const arr = s.split('>')
return arr[arr.length - 1].trim()
diff --git a/packages/vite/src/node/ssr/ssrManifestPlugin.ts b/packages/vite/src/node/ssr/ssrManifestPlugin.ts
index 993fae1632ed5d..8bb9a8bcff75dc 100644
--- a/packages/vite/src/node/ssr/ssrManifestPlugin.ts
+++ b/packages/vite/src/node/ssr/ssrManifestPlugin.ts
@@ -59,7 +59,7 @@ export function ssrManifestPlugin(config: ResolvedConfig): Plugin {
const chunk = bundle[filename] as OutputChunk | undefined
if (chunk) {
chunk.viteMetadata.importedCss.forEach((file) => {
- deps.push(`/${file}`)
+ deps.push(join(config.base, file))
})
chunk.imports.forEach(addDeps)
}
diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts
index 258551b838f271..db331894bb78fb 100644
--- a/packages/vite/src/node/utils.ts
+++ b/packages/vite/src/node/utils.ts
@@ -234,10 +234,10 @@ export const isJSRequest = (url: string): boolean => {
const knownTsRE = /\.(ts|mts|cts|tsx)$/
const knownTsOutputRE = /\.(js|mjs|cjs|jsx)$/
-export const isTsRequest = (url: string) => knownTsRE.test(url)
-export const isPossibleTsOutput = (url: string) =>
+export const isTsRequest = (url: string): boolean => knownTsRE.test(url)
+export const isPossibleTsOutput = (url: string): boolean =>
knownTsOutputRE.test(cleanUrl(url))
-export function getPotentialTsSrcPaths(filePath: string) {
+export function getPotentialTsSrcPaths(filePath: string): string[] {
const [name, type, query = ''] = filePath.split(/(\.(?:[cm]?js|jsx))(\?.*)?$/)
const paths = [name + type.replace('js', 'ts') + query]
if (!type.endsWith('x')) {
@@ -781,7 +781,7 @@ export function parseRequest(id: string): Record | null {
return Object.fromEntries(new URLSearchParams(search))
}
-export const blankReplacer = (match: string) => ' '.repeat(match.length)
+export const blankReplacer = (match: string): string => ' '.repeat(match.length)
export function getHash(text: Buffer | string): string {
return createHash('sha256').update(text).digest('hex').substring(0, 8)
@@ -856,7 +856,7 @@ function gracefulRemoveDir(
})
}
-export function emptyCssComments(raw: string) {
+export function emptyCssComments(raw: string): string {
return raw.replace(multilineCommentsRE, (s) => ' '.repeat(s.length))
}
diff --git a/packages/vite/tsconfig.check.json b/packages/vite/tsconfig.check.json
new file mode 100644
index 00000000000000..cd8f8d6eeb3f2c
--- /dev/null
+++ b/packages/vite/tsconfig.check.json
@@ -0,0 +1,20 @@
+{
+ "compilerOptions": {
+ "noEmit": true,
+ "moduleResolution": "classic",
+ // Only add entries to `paths` when you are adding/updating dependencies (not devDependencies)
+ // See CONTRIBUTING.md "Ensure type support" for more details
+ "paths": {
+ // direct
+ "rollup": ["./node_modules/rollup/dist/rollup.d.ts"],
+ // direct
+ "esbuild": ["./node_modules/esbuild/lib/main.d.ts"],
+ // direct
+ "postcss": ["./node_modules/postcss/lib/postcss.d.ts"],
+ // indirect: postcss depends on it
+ "source-map-js": ["./node_modules/source-map-js/source-map.d.ts"]
+ },
+ "typeRoots": []
+ },
+ "include": ["dist/**/*.d.ts"]
+}
diff --git a/playground/legacy/__tests__/ssr/serve.ts b/playground/legacy/__tests__/ssr/serve.ts
index fc0fba377160ac..339b95e690b83a 100644
--- a/playground/legacy/__tests__/ssr/serve.ts
+++ b/playground/legacy/__tests__/ssr/serve.ts
@@ -5,7 +5,7 @@ import { ports, rootDir } from '~utils'
export const port = ports['legacy/ssr']
-export async function serve() {
+export async function serve(): Promise<{ close(): Promise }> {
const { build } = await import('vite')
await build({
root: rootDir,
diff --git a/playground/optimize-deps/index.astro b/playground/optimize-deps/index.astro
index 95790f5bf3a0d5..4425a8b0f6b1ee 100644
--- a/playground/optimize-deps/index.astro
+++ b/playground/optimize-deps/index.astro
@@ -1,4 +1,6 @@
diff --git a/playground/ssr-vue/__tests__/serve.ts b/playground/ssr-vue/__tests__/serve.ts
index 471929634483e8..2e80107022b625 100644
--- a/playground/ssr-vue/__tests__/serve.ts
+++ b/playground/ssr-vue/__tests__/serve.ts
@@ -7,12 +7,13 @@ import { hmrPorts, isBuild, ports, rootDir } from '~utils'
export const port = ports['ssr-vue']
-export async function serve() {
+export async function serve(): Promise {
if (isBuild) {
// build first
const { build } = await import('vite')
// client build
await build({
+ base: '/test/',
root: rootDir,
logLevel: 'silent', // exceptions are logged by Vitest
build: {
@@ -24,6 +25,7 @@ export async function serve() {
})
// server build
await build({
+ base: '/test/',
root: rootDir,
logLevel: 'silent',
build: {
diff --git a/playground/ssr-vue/__tests__/ssr-vue.spec.ts b/playground/ssr-vue/__tests__/ssr-vue.spec.ts
index fced36889da442..a70586a5427df5 100644
--- a/playground/ssr-vue/__tests__/ssr-vue.spec.ts
+++ b/playground/ssr-vue/__tests__/ssr-vue.spec.ts
@@ -10,20 +10,20 @@ import {
untilUpdated
} from '~utils'
-const url = `http://localhost:${port}`
+const url = `http://localhost:${port}/test/`
test('vuex can be import succeed by named import', async () => {
// wait networkidle for dynamic optimize vuex
- await page.goto(url + '/store', { waitUntil: 'networkidle' })
+ await page.goto(url + 'store', { waitUntil: 'networkidle' })
expect(await page.textContent('h1')).toMatch('bar')
// raw http request
- const storeHtml = await (await fetch(url + '/store')).text()
+ const storeHtml = await (await fetch(url + 'store')).text()
expect(storeHtml).toMatch('bar')
})
test('/about', async () => {
- await page.goto(url + '/about')
+ await page.goto(url + 'about')
expect(await page.textContent('h1')).toMatch('About')
// should not have hydration mismatch
browserLogs.forEach((msg) => {
@@ -31,27 +31,27 @@ test('/about', async () => {
})
// fetch sub route
- const aboutHtml = await (await fetch(url + '/about')).text()
+ const aboutHtml = await (await fetch(url + 'about')).text()
expect(aboutHtml).toMatch('About')
if (isBuild) {
// assert correct preload directive generation for async chunks and CSS
expect(aboutHtml).not.toMatch(
- /link rel="modulepreload".*?href="\/assets\/Home\.\w{8}\.js"/
+ /link rel="modulepreload".*?href="\/test\/assets\/Home\.\w{8}\.js"/
)
expect(aboutHtml).not.toMatch(
- /link rel="stylesheet".*?href="\/assets\/Home\.\w{8}\.css"/
+ /link rel="stylesheet".*?href="\/test\/assets\/Home\.\w{8}\.css"/
)
expect(aboutHtml).toMatch(
- /link rel="modulepreload".*?href="\/assets\/About\.\w{8}\.js"/
+ /link rel="modulepreload".*?href="\/test\/assets\/About\.\w{8}\.js"/
)
expect(aboutHtml).toMatch(
- /link rel="stylesheet".*?href="\/assets\/About\.\w{8}\.css"/
+ /link rel="stylesheet".*?href="\/test\/assets\/About\.\w{8}\.css"/
)
}
})
test('/external', async () => {
- await page.goto(url + '/external')
+ await page.goto(url + 'external')
expect(await page.textContent('div')).toMatch(
'Example external component content'
)
@@ -61,18 +61,18 @@ test('/external', async () => {
})
// fetch sub route
- const externalHtml = await (await fetch(url + '/external')).text()
+ const externalHtml = await (await fetch(url + 'external')).text()
expect(externalHtml).toMatch('Example external component content')
if (isBuild) {
// assert correct preload directive generation for async chunks and CSS
expect(externalHtml).not.toMatch(
- /link rel="modulepreload".*?href="\/assets\/Home\.\w{8}\.js"/
+ /link rel="modulepreload".*?href="\/test\/assets\/Home\.\w{8}\.js"/
)
expect(externalHtml).not.toMatch(
- /link rel="stylesheet".*?href="\/assets\/Home\.\w{8}\.css"/
+ /link rel="stylesheet".*?href="\/test\/assets\/Home\.\w{8}\.css"/
)
expect(externalHtml).toMatch(
- /link rel="modulepreload".*?href="\/assets\/External\.\w{8}\.js"/
+ /link rel="modulepreload".*?href="\/test\/assets\/External\.\w{8}\.js"/
)
}
})
@@ -90,23 +90,23 @@ test('/', async () => {
if (isBuild) {
// assert correct preload directive generation for async chunks and CSS
expect(html).toMatch(
- /link rel="modulepreload".*?href="\/assets\/Home\.\w{8}\.js"/
+ /link rel="modulepreload".*?href="\/test\/assets\/Home\.\w{8}\.js"/
)
expect(html).toMatch(
- /link rel="stylesheet".*?href="\/assets\/Home\.\w{8}\.css"/
+ /link rel="stylesheet".*?href="\/test\/assets\/Home\.\w{8}\.css"/
)
// JSX component preload registration
expect(html).toMatch(
- /link rel="modulepreload".*?href="\/assets\/Foo\.\w{8}\.js"/
+ /link rel="modulepreload".*?href="\/test\/assets\/Foo\.\w{8}\.js"/
)
expect(html).toMatch(
- /link rel="stylesheet".*?href="\/assets\/Foo\.\w{8}\.css"/
+ /link rel="stylesheet".*?href="\/test\/assets\/Foo\.\w{8}\.css"/
)
expect(html).not.toMatch(
- /link rel="modulepreload".*?href="\/assets\/About\.\w{8}\.js"/
+ /link rel="modulepreload".*?href="\/test\/assets\/About\.\w{8}\.js"/
)
expect(html).not.toMatch(
- /link rel="stylesheet".*?href="\/assets\/About\.\w{8}\.css"/
+ /link rel="stylesheet".*?href="\/test\/assets\/About\.\w{8}\.css"/
)
}
})
@@ -132,7 +132,7 @@ test('asset', async () => {
})
const img = await page.$('img')
expect(await img.getAttribute('src')).toMatch(
- isBuild ? /\/assets\/logo\.\w{8}\.png/ : '/src/assets/logo.png'
+ isBuild ? /\/test\/assets\/logo\.\w{8}\.png/ : '/src/assets/logo.png'
)
})
@@ -166,13 +166,13 @@ test('hmr', async () => {
test('client navigation', async () => {
await page.goto(url)
- await untilUpdated(() => page.textContent('a[href="/about"]'), 'About')
- await page.click('a[href="/about"]')
+ await untilUpdated(() => page.textContent('a[href="/test/about"]'), 'About')
+ await page.click('a[href="/test/about"]')
await untilUpdated(() => page.textContent('h1'), 'About')
editFile('src/pages/About.vue', (code) => code.replace('About', 'changed'))
await untilUpdated(() => page.textContent('h1'), 'changed')
- await page.click('a[href="/"]')
- await untilUpdated(() => page.textContent('a[href="/"]'), 'Home')
+ await page.click('a[href="/test/"]')
+ await untilUpdated(() => page.textContent('a[href="/test/"]'), 'Home')
})
test('import.meta.url', async () => {
@@ -183,7 +183,8 @@ test('import.meta.url', async () => {
test.runIf(isBuild)('dynamic css file should be preloaded', async () => {
await page.goto(url)
const homeHtml = await (await fetch(url)).text()
- const re = /link rel="modulepreload".*?href="\/assets\/(Home\.\w{8}\.js)"/
+ const re =
+ /link rel="modulepreload".*?href="\/test\/assets\/(Home\.\w{8}\.js)"/
const filename = re.exec(homeHtml)[1]
const manifest = (
await import(
diff --git a/playground/ssr-vue/server.js b/playground/ssr-vue/server.js
index fb0fd58554b276..5e4e6718bff7bf 100644
--- a/playground/ssr-vue/server.js
+++ b/playground/ssr-vue/server.js
@@ -33,6 +33,7 @@ export async function createServer(
vite = await (
await import('vite')
).createServer({
+ base: '/test/',
root,
logLevel: isTest ? 'error' : 'info',
server: {
@@ -53,6 +54,7 @@ export async function createServer(
} else {
app.use((await import('compression')).default())
app.use(
+ '/test/',
(await import('serve-static')).default(resolve('dist/client'), {
index: false
})
@@ -61,7 +63,7 @@ export async function createServer(
app.use('*', async (req, res) => {
try {
- const url = req.originalUrl
+ const url = req.originalUrl.replace('/test/', '/')
let template, render
if (!isProd) {
@@ -94,8 +96,8 @@ export async function createServer(
if (!isTest) {
createServer().then(({ app }) =>
- app.listen(5173, () => {
- console.log('http://localhost:5173')
+ app.listen(6173, () => {
+ console.log('http://localhost:6173')
})
)
}
diff --git a/playground/ssr-vue/src/router.js b/playground/ssr-vue/src/router.js
index 2c4f23f7b07e62..814098102d7899 100644
--- a/playground/ssr-vue/src/router.js
+++ b/playground/ssr-vue/src/router.js
@@ -20,7 +20,9 @@ export function createRouter() {
return _createRouter({
// use appropriate history implementation for server/client
// import.meta.env.SSR is injected by Vite.
- history: import.meta.env.SSR ? createMemoryHistory() : createWebHistory(),
+ history: import.meta.env.SSR
+ ? createMemoryHistory('/test/')
+ : createWebHistory('/test/'),
routes
})
}
diff --git a/playground/ssr-vue/vite.config.js b/playground/ssr-vue/vite.config.js
index e9fc4c1e309e0f..d57a11972d449e 100644
--- a/playground/ssr-vue/vite.config.js
+++ b/playground/ssr-vue/vite.config.js
@@ -7,6 +7,7 @@ const nestedVirtualFile = '@nested-virtual-file'
const nestedVirtualId = '\0' + nestedVirtualFile
export default defineConfig({
+ base: '/test/',
plugins: [
vuePlugin(),
vueJsx(),
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b3a949e094db47..4495b294a0b344 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -64,7 +64,7 @@ importers:
typescript: ^4.6.4
unbuild: ^0.7.4
vite: workspace:*
- vitepress: 1.0.0-draft.4
+ vitepress: 1.0.0-draft.8
vitest: ^0.12.9
vue: ^3.2.35
devDependencies:
@@ -122,7 +122,7 @@ importers:
typescript: 4.6.4
unbuild: 0.7.4
vite: link:packages/vite
- vitepress: 1.0.0-draft.4
+ vitepress: 1.0.0-draft.8
vitest: 0.12.9
vue: 3.2.36
@@ -1626,12 +1626,14 @@ packages:
/@cspotcode/source-map-consumer/0.8.0:
resolution: {integrity: sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==}
engines: {node: '>= 12'}
+ dev: true
/@cspotcode/source-map-support/0.7.0:
resolution: {integrity: sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==}
engines: {node: '>=12'}
dependencies:
'@cspotcode/source-map-consumer': 0.8.0
+ dev: true
/@docsearch/css/3.0.0:
resolution: {integrity: sha512-1kkV7tkAsiuEd0shunYRByKJe3xQDG2q7wYg24SOw1nV9/2lwEd4WrUYRJC/ukGTl2/kHeFxsaUvtiOy0y6fFA==}
@@ -2121,15 +2123,19 @@ packages:
/@tsconfig/node10/1.0.8:
resolution: {integrity: sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==}
+ dev: true
/@tsconfig/node12/1.0.9:
resolution: {integrity: sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==}
+ dev: true
/@tsconfig/node14/1.0.1:
resolution: {integrity: sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==}
+ dev: true
/@tsconfig/node16/1.0.2:
resolution: {integrity: sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==}
+ dev: true
/@types/argparse/1.0.38:
resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==}
@@ -2711,6 +2717,7 @@ packages:
/acorn-walk/8.2.0:
resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
engines: {node: '>=0.4.0'}
+ dev: true
/acorn/7.4.1:
resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
@@ -2721,6 +2728,7 @@ packages:
resolution: {integrity: sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==}
engines: {node: '>=0.4.0'}
hasBin: true
+ dev: true
/add-stream/1.0.0:
resolution: {integrity: sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=}
@@ -2825,6 +2833,7 @@ packages:
/arg/4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
+ dev: true
/arg/5.0.1:
resolution: {integrity: sha512-e0hDa9H2Z9AwFkk2qDlwhoMYE4eToKarchkQHovNdLTCYMHZHeRjI71crOh+dio4K6u1IcwubQqo79Ga4CyAQA==}
@@ -3613,6 +3622,7 @@ packages:
/create-require/1.1.1:
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
+ dev: true
/cross-env/7.0.3:
resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==}
@@ -3858,6 +3868,7 @@ packages:
/diff/4.0.2:
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
engines: {node: '>=0.3.1'}
+ dev: true
/dir-glob/3.0.1:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
@@ -5890,6 +5901,7 @@ packages:
/make-error/1.3.6:
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
+ dev: true
/map-obj/1.0.1:
resolution: {integrity: sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=}
@@ -6853,11 +6865,6 @@ packages:
engines: {node: '>= 0.8'}
dev: false
- /prismjs/1.28.0:
- resolution: {integrity: sha512-8aaXdYvl1F7iC7Xm1spqSaY/OJBpYW3v+KJ+F17iYxvdc8sfjW194COK5wVhMZX45tGteiBQgdvD/nhxcRwylw==}
- engines: {node: '>=6'}
- dev: true
-
/process-nextick-args/2.0.1:
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
dev: true
@@ -7541,6 +7548,14 @@ packages:
resolution: {integrity: sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==}
dev: true
+ /shiki/0.10.1:
+ resolution: {integrity: sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==}
+ dependencies:
+ jsonc-parser: 3.0.0
+ vscode-oniguruma: 1.6.2
+ vscode-textmate: 5.2.0
+ dev: true
+
/side-channel/1.0.4:
resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
dependencies:
@@ -8182,6 +8197,7 @@ packages:
make-error: 1.3.6
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
+ dev: true
/tsconfck/2.0.0:
resolution: {integrity: sha512-GVDTXF4MdNBBxKfUfjs/wkb7LHd8Ho8WLavESCddTFQFG9AUZOZEm6kODBGmQopQ9OG+EHpkT6dBaIIGhYVt+Q==}
@@ -8423,6 +8439,7 @@ packages:
/v8-compile-cache-lib/3.0.1:
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
+ dev: true
/v8-compile-cache/2.3.0:
resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==}
@@ -8449,9 +8466,9 @@ packages:
engines: {node: '>= 0.8'}
dev: true
- /vitepress/1.0.0-draft.4:
- resolution: {integrity: sha512-ViWGXaNFdILpCtC0iOiyNT8zsNYoWZTwZIK7rCrPJWyDD2sIeYuI9uK87pPGJo2XN+OuP7u68Ui86CJRuTtqpw==}
- engines: {node: '>=14.0.0'}
+ /vitepress/1.0.0-draft.8:
+ resolution: {integrity: sha512-r1cphHgtJ/KFwtph3cyusGWjRyX0NHvwfBboKnG5mRJpOP/JyvX5q5+NIiRYElPgdFXU7Roxkl8BcJbxWht56Q==}
+ engines: {node: '>=14.6.0'}
hasBin: true
dependencies:
'@docsearch/css': 3.0.0
@@ -8459,7 +8476,7 @@ packages:
'@vitejs/plugin-vue': link:packages/plugin-vue
'@vueuse/core': 8.5.0_vue@3.2.33
body-scroll-lock: 4.0.0-beta.0
- prismjs: 1.28.0
+ shiki: 0.10.1
vite: link:packages/vite
vue: 3.2.33
transitivePeerDependencies:
@@ -8506,6 +8523,14 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
+ /vscode-oniguruma/1.6.2:
+ resolution: {integrity: sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==}
+ dev: true
+
+ /vscode-textmate/5.2.0:
+ resolution: {integrity: sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==}
+ dev: true
+
/vue-demi/0.12.5_vue@3.2.33:
resolution: {integrity: sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==}
engines: {node: '>=12'}
@@ -8742,6 +8767,7 @@ packages:
/yn/3.1.1:
resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
engines: {node: '>=6'}
+ dev: true
/youch/2.2.2:
resolution: {integrity: sha512-/FaCeG3GkuJwaMR34GHVg0l8jCbafZLHiFowSjqLlqhC6OMyf2tPJBu8UirF7/NI9X/R5ai4QfEKUCOxMAGxZQ==}
diff --git a/scripts/releaseUtils.ts b/scripts/releaseUtils.ts
index 272ab799fbc732..ea6987e1fe5c27 100644
--- a/scripts/releaseUtils.ts
+++ b/scripts/releaseUtils.ts
@@ -4,7 +4,7 @@
import { existsSync, readdirSync, writeFileSync } from 'fs'
import path from 'path'
import colors from 'picocolors'
-import type { Options as ExecaOptions } from 'execa'
+import type { Options as ExecaOptions, ExecaReturnValue } from 'execa'
import execa from 'execa'
import type { ReleaseType } from 'semver'
import semver from 'semver'
@@ -39,7 +39,18 @@ export const versionIncrements: ReleaseType[] = [
// 'prerelease'
]
-export function getPackageInfo(pkgName: string) {
+interface Pkg {
+ name: string
+ version: string
+ private?: boolean
+}
+export function getPackageInfo(pkgName: string): {
+ pkg: Pkg
+ pkgName: string
+ pkgDir: string
+ pkgPath: string
+ currentVersion: string
+} {
const pkgDir = path.resolve(__dirname, '../packages/' + pkgName)
if (!existsSync(pkgDir)) {
@@ -47,11 +58,7 @@ export function getPackageInfo(pkgName: string) {
}
const pkgPath = path.resolve(pkgDir, 'package.json')
- const pkg: {
- name: string
- version: string
- private?: boolean
- } = require(pkgPath)
+ const pkg: Pkg = require(pkgPath)
const currentVersion = pkg.version
if (pkg.private) {
@@ -71,7 +78,7 @@ export async function run(
bin: string,
args: string[],
opts: ExecaOptions = {}
-) {
+): Promise> {
return execa(bin, args, { stdio: 'inherit', ...opts })
}
@@ -79,7 +86,7 @@ export async function dryRun(
bin: string,
args: string[],
opts?: ExecaOptions
-) {
+): Promise {
return console.log(
colors.blue(`[dryrun] ${bin} ${args.join(' ')}`),
opts || ''
@@ -88,11 +95,15 @@ export async function dryRun(
export const runIfNotDry = isDryRun ? dryRun : run
-export function step(msg: string) {
+export function step(msg: string): void {
return console.log(colors.cyan(msg))
}
-export function getVersionChoices(currentVersion: string) {
+interface VersionChoice {
+ title: string
+ value: string
+}
+export function getVersionChoices(currentVersion: string): VersionChoice[] {
const currentBeta = currentVersion.includes('beta')
const currentAlpha = currentVersion.includes('alpha')
const isStable = !currentBeta && !currentAlpha
@@ -101,7 +112,7 @@ export function getVersionChoices(currentVersion: string) {
return semver.inc(currentVersion, i, tag)!
}
- let versionChoices = [
+ let versionChoices: VersionChoice[] = [
{
title: 'next',
value: inc(isStable ? 'patch' : 'prerelease')
@@ -175,7 +186,7 @@ export async function publishPackage(
})
}
-export async function getLatestTag(pkgName: string) {
+export async function getLatestTag(pkgName: string): Promise {
const tags = (await run('git', ['tag'], { stdio: 'pipe' })).stdout
.split(/\n/)
.filter(Boolean)
@@ -186,7 +197,7 @@ export async function getLatestTag(pkgName: string) {
.reverse()[0]
}
-export async function logRecentCommits(pkgName: string) {
+export async function logRecentCommits(pkgName: string): Promise {
const tag = await getLatestTag(pkgName)
if (!tag) return
const sha = await run('git', ['rev-list', '-n', '1', tag], {
@@ -214,7 +225,7 @@ export async function logRecentCommits(pkgName: string) {
console.log()
}
-export async function updateTemplateVersions() {
+export async function updateTemplateVersions(): Promise {
const viteVersion = (await fs.readJSON('../packages/vite/package.json'))
.version
if (/beta|alpha|rc/.test(viteVersion)) return