From bc7d4ddcd8432fad299c2e667e25574a0fee8ada Mon Sep 17 00:00:00 2001
From: Kenneth Ng <145921389+DubNubz@users.noreply.github.com>
Date: Mon, 9 Dec 2024 21:08:59 -0500
Subject: [PATCH 01/19] docs: bring back the UwU logo (#18924)
---
.../landing/1. hero-section/HeroDiagram.vue | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/docs/.vitepress/theme/components/landing/1. hero-section/HeroDiagram.vue b/docs/.vitepress/theme/components/landing/1. hero-section/HeroDiagram.vue
index 10bd32fa4d0fb9..f76e7092220094 100644
--- a/docs/.vitepress/theme/components/landing/1. hero-section/HeroDiagram.vue
+++ b/docs/.vitepress/theme/components/landing/1. hero-section/HeroDiagram.vue
@@ -437,6 +437,12 @@ const isChromiumBrowser = ref(false)
onMounted(() => {
isChromiumBrowser.value = 'chrome' in window
})
+
+// Check for uwu query
+const isUwu = ref(false)
+onMounted(() => {
+ isUwu.value = location.search.includes('?uwu')
+})
@@ -463,7 +469,12 @@ onMounted(() => {
>
-
+
@@ -638,6 +649,10 @@ onMounted(() => {
z-index: 3;
}
+ .uwu.vite-chip__logo {
+ width: 134px;
+ }
+
&.active {
box-shadow: 0 30px 35px -10px rgba(0, 0, 0, 0.6);
transform: translate3d(0, 0, 0) scale(1);
From b53479e886d5b8c1f45f7c87f8a32bbd86545040 Mon Sep 17 00:00:00 2001
From: Mohammad Bagher Abiyat
Date: Tue, 10 Dec 2024 05:50:45 +0330
Subject: [PATCH 02/19] ci: buildless ecosystem ci (#18525)
Co-authored-by: sapphi-red <49056869+sapphi-red@users.noreply.github.com>
Co-authored-by: Dominik G.
---
.github/workflows/ecosystem-ci-trigger.yml | 180 ++++++++++++++++++---
1 file changed, 157 insertions(+), 23 deletions(-)
diff --git a/.github/workflows/ecosystem-ci-trigger.yml b/.github/workflows/ecosystem-ci-trigger.yml
index c2c50da948b0be..9e48e2c69755e7 100644
--- a/.github/workflows/ecosystem-ci-trigger.yml
+++ b/.github/workflows/ecosystem-ci-trigger.yml
@@ -9,7 +9,51 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'vitejs/vite' && github.event.issue.pull_request && startsWith(github.event.comment.body, '/ecosystem-ci run')
steps:
- - uses: actions/github-script@v7
+ - name: Get PR Data
+ uses: actions/github-script@v7
+ id: get-pr-data
+ with:
+ script: |
+ console.log(`Get PR info: ${context.repo.owner}/${context.repo.repo}#${context.issue.number}`)
+ const { data: pr } = await github.rest.pulls.get({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ pull_number: context.issue.number
+ })
+ core.setOutput('head_sha', pr.head.sha)
+ return {
+ num: context.issue.number,
+ branchName: pr.head.ref,
+ commit: pr.head.sha,
+ repo: pr.head.repo.full_name
+ }
+
+ - name: Check Package Existence
+ uses: actions/github-script@v7
+ id: check-package
+ with:
+ script: |
+ const prData = ${{ steps.get-pr-data.outputs.result }}
+ const url = `https://pkg.pr.new/vite@${prData.commit}`
+ const response = await fetch(url)
+ console.log(`Package check URL: ${url}, Status: ${response.status}`)
+
+ // Add 'rocket' reaction to the issue comment
+ if (response.status === 404) {
+ const reaction = await github.rest.reactions.createForIssueComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: context.payload.comment.id,
+ content: 'rocket',
+ })
+ return { exists: false, reaction: reaction.id }
+ }
+
+ return { exists: true, reaction: null }
+
+ - name: Check User Permissions
+ uses: actions/github-script@v7
+ id: check-permissions
with:
script: |
const user = context.payload.sender.login
@@ -27,8 +71,8 @@ jobs:
console.warn(e)
}
- if (hasTriagePermission) {
- console.log('Allowed')
+ if (allowed) {
+ console.log('User is allowed. Adding +1 reaction.')
await github.rest.reactions.createForIssueComment({
owner: context.repo.owner,
repo: context.repo.repo,
@@ -36,44 +80,134 @@ jobs:
content: '+1',
})
} else {
- console.log('Not allowed')
+ console.log('User is not allowed. Adding -1 reaction.')
await github.rest.reactions.createForIssueComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: context.payload.comment.id,
content: '-1',
})
- throw new Error('not allowed')
+ throw new Error('User does not have the necessary permissions.')
}
- - uses: actions/github-script@v7
- id: get-pr-data
+
+ - name: Generate Token
+ id: generate-token
+ uses: tibdex/github-app-token@v2
with:
+ app_id: ${{ secrets.ECOSYSTEM_CI_GITHUB_APP_ID }}
+ installation_retrieval_payload: "${{ github.repository_owner }}/vite-ecosystem-ci"
+ private_key: ${{ secrets.ECOSYSTEM_CI_GITHUB_APP_PRIVATE_KEY }}
+
+ - name: Trigger Preview Release (if Package Not Found)
+ if: steps.check-package.outputs.exists == false
+ uses: actions/github-script@v7
+ id: trigger-preview-release
+ with:
+ github-token: ${{ steps.generate-token.outputs.token }}
script: |
- console.log(`Get PR info: ${context.repo.owner}/${context.repo.repo}#${context.issue.number}`)
- const { data: pr } = await github.rest.pulls.get({
+ const prData = ${{ steps.get-pr-data.outputs.result }}
+ console.log('Package not found, triggering preview release...')
+
+ // Add label "trigger: preview" to the PR
+ await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
- pull_number: context.issue.number
+ issue_number: prData.num,
+ labels: ['trigger: preview']
})
- return {
- num: context.issue.number,
- branchName: pr.head.ref,
- repo: pr.head.repo.full_name,
- commit: pr.head.sha
+ console.log('Added "trigger: preview" label.')
+
+ - name: Wait for Preview Release Completion (if Package Not Found)
+ if: steps.check-package.outputs.exists == false
+ uses: actions/github-script@v7
+ id: wait-preview-release
+ with:
+ script: |
+ const prData = ${{ steps.get-pr-data.outputs.result }}
+ const reaction = ${{ steps.check-package.outputs.reaction }}
+ const workflowFileName = 'preview-release.yml'
+ const workflow = await github.rest.actions.getWorkflow({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ workflow_id: workflowFileName,
+ })
+ const workflowId = workflow.data.id
+ console.log(`Waiting for workflow ID ${workflowId} to complete...`)
+
+ const maxRetries = 60 // Wait up to 10 minutes
+ const delay = 10000 // 10 seconds
+ let completed = false
+
+ for (let i = 0; i < maxRetries; i++) {
+ const runsData = await github.rest.actions.listWorkflowRuns({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ workflow_id: workflowId,
+ head_sha: prData.commit,
+ per_page: 100,
+ page: 1,
+ })
+
+ const runs = runsData.data.workflow_runs
+
+ if (runs.length > 0) {
+ const latestRun = runs[0]
+ console.log(`Latest run status: ${latestRun.status}, conclusion: ${latestRun.conclusion}`)
+ if (latestRun.status === 'completed') {
+ if (latestRun.conclusion === 'success') {
+ console.log('Preview release workflow completed successfully.')
+ completed = true
+ break
+ } else {
+ throw new Error('Preview Release workflow failed.')
+ }
+ }
+ }
+
+ console.log(`Retrying... (${i + 1}/${maxRetries})`)
+ await new Promise(resolve => setTimeout(resolve, delay))
}
- - id: generate-token
- uses: tibdex/github-app-token@v2
+
+ if (!completed) {
+ throw new Error('Preview Release workflow did not complete in time.')
+ }
+
+ // Remove the 'rocket' reaction
+ if (reaction) {
+ await github.rest.reactions.deleteForIssueComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: context.payload.comment.id,
+ reaction_id: reaction,
+ })
+ console.log('Removed "rocket" reaction.')
+ }
+
+ - name: Checkout
+ uses: actions/checkout@v4
with:
- app_id: ${{ secrets.ECOSYSTEM_CI_GITHUB_APP_ID }}
- installation_retrieval_payload: "${{ github.repository_owner }}/vite-ecosystem-ci"
- private_key: ${{ secrets.ECOSYSTEM_CI_GITHUB_APP_PRIVATE_KEY }}
- - uses: actions/github-script@v7
+ fetch-depth: 0
+
+ # This step can be removed on May 26 2025
+ - name: Check Commit Hash Ambiguity
+ id: check_ambiguity
+ run: |
+ HEAD_SHA=${{ steps.get-pr-data.outputs.head_sha }}
+ COMMIT_SHORT=${HEAD_SHA:0:7}
+
+ if git show "$COMMIT_SHORT"; then
+ echo "COLLISION=false" >> $GITHUB_ENV
+ else
+ echo "COLLISION=true" >> $GITHUB_ENV
+ fi
+
+ - name: Trigger Downstream Workflow
+ uses: actions/github-script@v7
id: trigger
env:
COMMENT: ${{ github.event.comment.body }}
with:
github-token: ${{ steps.generate-token.outputs.token }}
- result-encoding: string
script: |
const comment = process.env.COMMENT.trim()
const prData = ${{ steps.get-pr-data.outputs.result }}
@@ -89,7 +223,7 @@ jobs:
prNumber: '' + prData.num,
branchName: prData.branchName,
repo: prData.repo,
- commit: prData.commit,
+ commit: process.env.COLLISION === 'false' ? prData.commit : '',
suite: suite === '' ? '-' : suite
}
})
From a95a8f0e2acef230c0ed1a3f72e2e62f57b3d829 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BF=A0=20/=20green?=
Date: Tue, 10 Dec 2024 11:32:38 +0900
Subject: [PATCH 03/19] ci: fix ecosystem-ci-trigger user permission check
(#18926)
---
.github/workflows/ecosystem-ci-trigger.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/ecosystem-ci-trigger.yml b/.github/workflows/ecosystem-ci-trigger.yml
index 9e48e2c69755e7..7a403168ba4bca 100644
--- a/.github/workflows/ecosystem-ci-trigger.yml
+++ b/.github/workflows/ecosystem-ci-trigger.yml
@@ -71,7 +71,7 @@ jobs:
console.warn(e)
}
- if (allowed) {
+ if (hasTriagePermission) {
console.log('User is allowed. Adding +1 reaction.')
await github.rest.reactions.createForIssueComment({
owner: context.repo.owner,
From 87826f5e8d76e68d0bf27cafb1e842791d24984a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BF=A0=20/=20green?=
Date: Tue, 10 Dec 2024 11:46:22 +0900
Subject: [PATCH 04/19] ci: fix ecosystem ci trigger (#18927)
---
.github/workflows/ecosystem-ci-trigger.yml | 86 +++++++++++-----------
1 file changed, 43 insertions(+), 43 deletions(-)
diff --git a/.github/workflows/ecosystem-ci-trigger.yml b/.github/workflows/ecosystem-ci-trigger.yml
index 7a403168ba4bca..ad0f1b6b72b587 100644
--- a/.github/workflows/ecosystem-ci-trigger.yml
+++ b/.github/workflows/ecosystem-ci-trigger.yml
@@ -9,6 +9,45 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'vitejs/vite' && github.event.issue.pull_request && startsWith(github.event.comment.body, '/ecosystem-ci run')
steps:
+ - name: Check User Permissions
+ uses: actions/github-script@v7
+ id: check-permissions
+ with:
+ script: |
+ const user = context.payload.sender.login
+ console.log(`Validate user: ${user}`)
+
+ let hasTriagePermission = false
+ try {
+ const { data } = await github.rest.repos.getCollaboratorPermissionLevel({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ username: user,
+ });
+ hasTriagePermission = data.user.permissions.triage
+ } catch (e) {
+ console.warn(e)
+ }
+
+ if (hasTriagePermission) {
+ console.log('User is allowed. Adding +1 reaction.')
+ await github.rest.reactions.createForIssueComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: context.payload.comment.id,
+ content: '+1',
+ })
+ } else {
+ console.log('User is not allowed. Adding -1 reaction.')
+ await github.rest.reactions.createForIssueComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: context.payload.comment.id,
+ content: '-1',
+ })
+ throw new Error('User does not have the necessary permissions.')
+ }
+
- name: Get PR Data
uses: actions/github-script@v7
id: get-pr-data
@@ -51,45 +90,6 @@ jobs:
return { exists: true, reaction: null }
- - name: Check User Permissions
- uses: actions/github-script@v7
- id: check-permissions
- with:
- script: |
- const user = context.payload.sender.login
- console.log(`Validate user: ${user}`)
-
- let hasTriagePermission = false
- try {
- const { data } = await github.rest.repos.getCollaboratorPermissionLevel({
- owner: context.repo.owner,
- repo: context.repo.repo,
- username: user,
- });
- hasTriagePermission = data.user.permissions.triage
- } catch (e) {
- console.warn(e)
- }
-
- if (hasTriagePermission) {
- console.log('User is allowed. Adding +1 reaction.')
- await github.rest.reactions.createForIssueComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: context.payload.comment.id,
- content: '+1',
- })
- } else {
- console.log('User is not allowed. Adding -1 reaction.')
- await github.rest.reactions.createForIssueComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: context.payload.comment.id,
- content: '-1',
- })
- throw new Error('User does not have the necessary permissions.')
- }
-
- name: Generate Token
id: generate-token
uses: tibdex/github-app-token@v2
@@ -99,7 +99,7 @@ jobs:
private_key: ${{ secrets.ECOSYSTEM_CI_GITHUB_APP_PRIVATE_KEY }}
- name: Trigger Preview Release (if Package Not Found)
- if: steps.check-package.outputs.exists == false
+ if: fromJSON(steps.check-package.outputs.result).exists == false
uses: actions/github-script@v7
id: trigger-preview-release
with:
@@ -118,13 +118,13 @@ jobs:
console.log('Added "trigger: preview" label.')
- name: Wait for Preview Release Completion (if Package Not Found)
- if: steps.check-package.outputs.exists == false
+ if: fromJSON(steps.check-package.outputs.result).exists == false
uses: actions/github-script@v7
id: wait-preview-release
with:
script: |
const prData = ${{ steps.get-pr-data.outputs.result }}
- const reaction = ${{ steps.check-package.outputs.reaction }}
+ const reaction = ${{ fromJSON(steps.check-package.outputs.result).reaction }}
const workflowFileName = 'preview-release.yml'
const workflow = await github.rest.actions.getWorkflow({
owner: context.repo.owner,
@@ -192,7 +192,7 @@ jobs:
- name: Check Commit Hash Ambiguity
id: check_ambiguity
run: |
- HEAD_SHA=${{ steps.get-pr-data.outputs.head_sha }}
+ HEAD_SHA=${{ fromJSON(steps.get-pr-data.outputs.result).head_sha }}
COMMIT_SHORT=${HEAD_SHA:0:7}
if git show "$COMMIT_SHORT"; then
From 8ccd34d685db6c11ea5325e11f54c67ed2c3d42c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BF=A0=20/=20green?=
Date: Tue, 10 Dec 2024 11:51:26 +0900
Subject: [PATCH 05/19] ci: fix ecosystem-ci-trigger head_sha (#18928)
---
.github/workflows/ecosystem-ci-trigger.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/ecosystem-ci-trigger.yml b/.github/workflows/ecosystem-ci-trigger.yml
index ad0f1b6b72b587..77fc7476b9099d 100644
--- a/.github/workflows/ecosystem-ci-trigger.yml
+++ b/.github/workflows/ecosystem-ci-trigger.yml
@@ -192,7 +192,7 @@ jobs:
- name: Check Commit Hash Ambiguity
id: check_ambiguity
run: |
- HEAD_SHA=${{ fromJSON(steps.get-pr-data.outputs.result).head_sha }}
+ HEAD_SHA=${{ steps.get-pr-data.outputs.head_sha }}
COMMIT_SHORT=${HEAD_SHA:0:7}
if git show "$COMMIT_SHORT"; then
From 0e3eec2072602a5dbbfcffd3e03688da08da3969 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BF=A0=20/=20green?=
Date: Tue, 10 Dec 2024 12:16:46 +0900
Subject: [PATCH 06/19] ci: fix ecosystem-ci-trigger reaction id (#18929)
---
.github/workflows/ecosystem-ci-trigger.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/ecosystem-ci-trigger.yml b/.github/workflows/ecosystem-ci-trigger.yml
index 77fc7476b9099d..653048b9fea91f 100644
--- a/.github/workflows/ecosystem-ci-trigger.yml
+++ b/.github/workflows/ecosystem-ci-trigger.yml
@@ -79,7 +79,7 @@ jobs:
// Add 'rocket' reaction to the issue comment
if (response.status === 404) {
- const reaction = await github.rest.reactions.createForIssueComment({
+ const { data: reaction } = await github.rest.reactions.createForIssueComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: context.payload.comment.id,
From 67fa5adb752cd71f046b821be4045acf1581186c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BF=A0=20/=20green?=
Date: Tue, 10 Dec 2024 12:36:03 +0900
Subject: [PATCH 07/19] ci: fix ecosystem-ci-trigger ignore skipped (#18930)
---
.github/workflows/ecosystem-ci-trigger.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/workflows/ecosystem-ci-trigger.yml b/.github/workflows/ecosystem-ci-trigger.yml
index 653048b9fea91f..dc658fb27a6ee4 100644
--- a/.github/workflows/ecosystem-ci-trigger.yml
+++ b/.github/workflows/ecosystem-ci-trigger.yml
@@ -158,6 +158,8 @@ jobs:
console.log('Preview release workflow completed successfully.')
completed = true
break
+ } else if (latestRun.conclusion === 'skipped') {
+ continue
} else {
throw new Error('Preview Release workflow failed.')
}
From 924b352c3484683051f744501b191fd4f6e63501 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BF=A0=20/=20green?=
Date: Tue, 10 Dec 2024 12:39:17 +0900
Subject: [PATCH 08/19] ci: fix ecosystem-ci-trigger ignore skipped (#18931)
---
.github/workflows/ecosystem-ci-trigger.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/ecosystem-ci-trigger.yml b/.github/workflows/ecosystem-ci-trigger.yml
index dc658fb27a6ee4..8320207d2058e3 100644
--- a/.github/workflows/ecosystem-ci-trigger.yml
+++ b/.github/workflows/ecosystem-ci-trigger.yml
@@ -159,7 +159,7 @@ jobs:
completed = true
break
} else if (latestRun.conclusion === 'skipped') {
- continue
+ // noop
} else {
throw new Error('Preview Release workflow failed.')
}
From 472732057cb2273908e1fca8aa7dc18a7e1f7c74 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BF=A0=20/=20green?=
Date: Tue, 10 Dec 2024 16:18:51 +0900
Subject: [PATCH 09/19] fix: `this.resolve` skipSelf should not skip for
different `id` or `import` (#18903)
---
packages/vite/src/node/index.ts | 2 +-
.../server/__tests__/pluginContainer.spec.ts | 47 +++++++++++++++++++
.../vite/src/node/server/pluginContainer.ts | 40 ++++++++++++----
3 files changed, 80 insertions(+), 9 deletions(-)
diff --git a/packages/vite/src/node/index.ts b/packages/vite/src/node/index.ts
index 69f47f3164c148..ae52db468474f1 100644
--- a/packages/vite/src/node/index.ts
+++ b/packages/vite/src/node/index.ts
@@ -145,7 +145,7 @@ export type {
WebSocketClient,
WebSocketCustomListener,
} from './server/ws'
-export type { PluginContainer } from './server/pluginContainer'
+export type { SkipInformation, PluginContainer } from './server/pluginContainer'
export type {
EnvironmentModuleGraph,
EnvironmentModuleNode,
diff --git a/packages/vite/src/node/server/__tests__/pluginContainer.spec.ts b/packages/vite/src/node/server/__tests__/pluginContainer.spec.ts
index a6491bc962a2c4..f0934219797556 100644
--- a/packages/vite/src/node/server/__tests__/pluginContainer.spec.ts
+++ b/packages/vite/src/node/server/__tests__/pluginContainer.spec.ts
@@ -213,6 +213,53 @@ describe('plugin container', () => {
expect(result.code).equals('3')
})
})
+
+ describe('resolveId', () => {
+ describe('skipSelf', () => {
+ it('should skip the plugin itself when skipSelf is true', async () => {
+ let calledCount = 0
+ const plugin: Plugin = {
+ name: 'p1',
+ async resolveId(id, importer) {
+ calledCount++
+ if (calledCount <= 1) {
+ return await this.resolve(id, importer, { skipSelf: true })
+ }
+ return id
+ },
+ }
+
+ const environment = await getDevEnvironment({ plugins: [plugin] })
+ await environment.pluginContainer.resolveId('/x.js')
+ expect(calledCount).toBe(1)
+ })
+
+ it('should skip the plugin only when id and importer is same', async () => {
+ const p1: Plugin = {
+ name: 'p1',
+ async resolveId(id, importer) {
+ if (id === 'foo/modified') {
+ return 'success'
+ }
+ return await this.resolve(id, importer, { skipSelf: true })
+ },
+ }
+ const p2: Plugin = {
+ name: 'p2',
+ async resolveId(id, importer) {
+ const resolved = await this.resolve(id + '/modified', importer, {
+ skipSelf: true,
+ })
+ return resolved ?? 'failed'
+ },
+ }
+
+ const environment = await getDevEnvironment({ plugins: [p1, p2] })
+ const result = await environment.pluginContainer.resolveId('foo')
+ expect(result).toStrictEqual({ id: 'success' })
+ })
+ })
+ })
})
async function getDevEnvironment(
diff --git a/packages/vite/src/node/server/pluginContainer.ts b/packages/vite/src/node/server/pluginContainer.ts
index c570c020a7bdfc..c72fa5b0c27355 100644
--- a/packages/vite/src/node/server/pluginContainer.ts
+++ b/packages/vite/src/node/server/pluginContainer.ts
@@ -144,6 +144,12 @@ export async function createEnvironmentPluginContainer(
return container
}
+export type SkipInformation = {
+ id: string
+ importer: string | undefined
+ plugin: Plugin
+}
+
class EnvironmentPluginContainer {
private _pluginContextMap = new Map()
private _resolvedRollupOptions?: InputOptions
@@ -336,7 +342,9 @@ class EnvironmentPluginContainer {
options?: {
attributes?: Record
custom?: CustomPluginOptions
+ /** @deprecated use `skipCalls` instead */
skip?: Set
+ skipCalls?: readonly SkipInformation[]
/**
* @internal
*/
@@ -349,9 +357,17 @@ class EnvironmentPluginContainer {
await this._buildStartPromise
}
const skip = options?.skip
+ const skipCalls = options?.skipCalls
const scan = !!options?.scan
const ssr = this.environment.config.consumer === 'server'
- const ctx = new ResolveIdContext(this, skip, scan)
+ const ctx = new ResolveIdContext(this, skip, skipCalls, scan)
+
+ const mergedSkip = new Set(skip)
+ for (const call of skipCalls ?? []) {
+ if (call.id === rawId && call.importer === importer) {
+ mergedSkip.add(call.plugin)
+ }
+ }
const resolveStart = debugResolve ? performance.now() : 0
let id: string | null = null
@@ -359,7 +375,7 @@ class EnvironmentPluginContainer {
for (const plugin of this.getSortedPlugins('resolveId')) {
if (this._closed && this.environment.config.dev.recoverable)
throwClosedServerError()
- if (skip?.has(plugin)) continue
+ if (mergedSkip?.has(plugin)) continue
ctx._plugin = plugin
@@ -534,6 +550,7 @@ class PluginContext implements Omit {
_activeId: string | null = null
_activeCode: string | null = null
_resolveSkips?: Set
+ _resolveSkipCalls?: readonly SkipInformation[]
meta: RollupPluginContext['meta']
environment: Environment
@@ -559,16 +576,19 @@ class PluginContext implements Omit {
skipSelf?: boolean
},
) {
- let skip: Set | undefined
- if (options?.skipSelf !== false) {
- skip = new Set(this._resolveSkips)
- skip.add(this._plugin)
- }
+ const skipCalls =
+ options?.skipSelf === false
+ ? this._resolveSkipCalls
+ : [
+ ...(this._resolveSkipCalls || []),
+ { id, importer, plugin: this._plugin },
+ ]
let out = await this._container.resolveId(id, importer, {
attributes: options?.attributes,
custom: options?.custom,
isEntry: !!options?.isEntry,
- skip,
+ skip: this._resolveSkips,
+ skipCalls,
scan: this._scan,
})
if (typeof out === 'string') out = { id: out }
@@ -794,10 +814,12 @@ class ResolveIdContext extends PluginContext {
constructor(
container: EnvironmentPluginContainer,
skip: Set | undefined,
+ skipCalls: readonly SkipInformation[] | undefined,
scan: boolean,
) {
super(null!, container)
this._resolveSkips = skip
+ this._resolveSkipCalls = skipCalls
this._scan = scan
}
}
@@ -999,7 +1021,9 @@ class PluginContainer {
options?: {
attributes?: Record
custom?: CustomPluginOptions
+ /** @deprecated use `skipCalls` instead */
skip?: Set
+ skipCalls?: readonly SkipInformation[]
ssr?: boolean
/**
* @internal
From 258cdd637d1ee80a3c4571685135e89fe283f3a6 Mon Sep 17 00:00:00 2001
From: Bjorn Lu
Date: Tue, 10 Dec 2024 17:52:58 +0800
Subject: [PATCH 10/19] fix: merge client and ssr values for
`pluginContainer.getModuleInfo` (#18895)
---
.../vite/src/node/server/mixedModuleGraph.ts | 51 ++++++++++++++++++-
.../vite/src/node/server/pluginContainer.ts | 43 +++++++++++++---
2 files changed, 84 insertions(+), 10 deletions(-)
diff --git a/packages/vite/src/node/server/mixedModuleGraph.ts b/packages/vite/src/node/server/mixedModuleGraph.ts
index 51fdc3ad1d3809..b86c6eb752e783 100644
--- a/packages/vite/src/node/server/mixedModuleGraph.ts
+++ b/packages/vite/src/node/server/mixedModuleGraph.ts
@@ -13,6 +13,9 @@ import type {
* We are going to deprecate these types and we can try to use them back in the future.
*/
+// same default value of "moduleInfo.meta" as in Rollup
+const EMPTY_OBJECT = Object.freeze({})
+
export class ModuleNode {
_moduleGraph: ModuleGraph
_clientModule: EnvironmentModuleNode | undefined
@@ -76,6 +79,48 @@ export class ModuleNode {
}
return importedModules
}
+ _getModuleInfoUnion(prop: 'info'): ModuleInfo | undefined {
+ const _clientValue = this._clientModule?.[prop]
+ const _ssrValue = this._ssrModule?.[prop]
+
+ if (_clientValue == null && _ssrValue == null) return undefined
+
+ return new Proxy({} as any, {
+ get: (_, key: string) => {
+ // `meta` refers to `ModuleInfo.meta` so we refer to `this.meta` to
+ // handle the object union between client and ssr
+ if (key === 'meta') {
+ return this.meta || EMPTY_OBJECT
+ }
+ if (_clientValue) {
+ if (key in _clientValue) {
+ return _clientValue[key as keyof ModuleInfo]
+ }
+ }
+ if (_ssrValue) {
+ if (key in _ssrValue) {
+ return _ssrValue[key as keyof ModuleInfo]
+ }
+ }
+ },
+ })
+ }
+ _getModuleObjectUnion(prop: 'meta'): Record | undefined {
+ const _clientValue = this._clientModule?.[prop]
+ const _ssrValue = this._ssrModule?.[prop]
+
+ if (_clientValue == null && _ssrValue == null) return undefined
+
+ const info: Record = {}
+ if (_ssrValue) {
+ Object.assign(info, _ssrValue)
+ }
+ if (_clientValue) {
+ Object.assign(info, _clientValue)
+ }
+ return info
+ }
+
get url(): string {
return this._get('url')
}
@@ -97,11 +142,13 @@ export class ModuleNode {
get type(): 'js' | 'css' {
return this._get('type')
}
+ // `info` needs special care as it's defined as a proxy in `pluginContainer`,
+ // so we also merge it as a proxy too
get info(): ModuleInfo | undefined {
- return this._get('info')
+ return this._getModuleInfoUnion('info')
}
get meta(): Record | undefined {
- return this._get('meta')
+ return this._getModuleObjectUnion('meta')
}
get importers(): Set {
return this._getModuleSetUnion('importers')
diff --git a/packages/vite/src/node/server/pluginContainer.ts b/packages/vite/src/node/server/pluginContainer.ts
index c72fa5b0c27355..616a16a9885c74 100644
--- a/packages/vite/src/node/server/pluginContainer.ts
+++ b/packages/vite/src/node/server/pluginContainer.ts
@@ -982,14 +982,41 @@ class PluginContainer {
}
getModuleInfo(id: string): ModuleInfo | null {
- return (
- (
- this.environments.client as DevEnvironment
- ).pluginContainer.getModuleInfo(id) ||
- (this.environments.ssr as DevEnvironment).pluginContainer.getModuleInfo(
- id,
- )
- )
+ const clientModuleInfo = (
+ this.environments.client as DevEnvironment
+ ).pluginContainer.getModuleInfo(id)
+ const ssrModuleInfo = (
+ this.environments.ssr as DevEnvironment
+ ).pluginContainer.getModuleInfo(id)
+
+ if (clientModuleInfo == null && ssrModuleInfo == null) return null
+
+ return new Proxy({} as any, {
+ get: (_, key: string) => {
+ // `meta` refers to `ModuleInfo.meta` of both environments, so we also
+ // need to merge it here
+ if (key === 'meta') {
+ const meta: Record = {}
+ if (ssrModuleInfo) {
+ Object.assign(meta, ssrModuleInfo.meta)
+ }
+ if (clientModuleInfo) {
+ Object.assign(meta, clientModuleInfo.meta)
+ }
+ return meta
+ }
+ if (clientModuleInfo) {
+ if (key in clientModuleInfo) {
+ return clientModuleInfo[key as keyof ModuleInfo]
+ }
+ }
+ if (ssrModuleInfo) {
+ if (key in ssrModuleInfo) {
+ return ssrModuleInfo[key as keyof ModuleInfo]
+ }
+ }
+ },
+ })
}
get options(): InputOptions {
From 3400a5e258a597499c0f0808c8fca4d92eeabc17 Mon Sep 17 00:00:00 2001
From: Mohammad Bagher Abiyat
Date: Wed, 11 Dec 2024 11:18:13 +0330
Subject: [PATCH 11/19] ci: fix checkout pr in ecosystem ci (#18942)
---
.github/workflows/ecosystem-ci-trigger.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/ecosystem-ci-trigger.yml b/.github/workflows/ecosystem-ci-trigger.yml
index 8320207d2058e3..30951771278a60 100644
--- a/.github/workflows/ecosystem-ci-trigger.yml
+++ b/.github/workflows/ecosystem-ci-trigger.yml
@@ -188,6 +188,7 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
with:
+ ref: refs/pull/${{ fromJSON(steps.get-pr-data.outputs.result).num }}/head
fetch-depth: 0
# This step can be removed on May 26 2025
From 638de0ff39efead268ad4d00134e563c3f69e98a Mon Sep 17 00:00:00 2001
From: "@beer" <47961062+iiio2@users.noreply.github.com>
Date: Fri, 13 Dec 2024 17:24:02 +0600
Subject: [PATCH 12/19] docs: capitalize text (#18951)
---
docs/guide/build.md | 2 +-
docs/guide/philosophy.md | 2 +-
docs/guide/troubleshooting.md | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/docs/guide/build.md b/docs/guide/build.md
index d0c1da79bdab28..e08ad32b247f72 100644
--- a/docs/guide/build.md
+++ b/docs/guide/build.md
@@ -71,7 +71,7 @@ window.addEventListener('vite:preloadError', (event) => {
When a new deployment occurs, the hosting service may delete the assets from previous deployments. As a result, a user who visited your site before the new deployment might encounter an import error. This error happens because the assets running on that user's device are outdated and it tries to import the corresponding old chunk, which is deleted. This event is useful for addressing this situation.
-## Rebuild on files changes
+## Rebuild on Files Changes
You can enable rollup watcher with `vite build --watch`. Or, you can directly adjust the underlying [`WatcherOptions`](https://rollupjs.org/configuration-options/#watch) via `build.watch`:
diff --git a/docs/guide/philosophy.md b/docs/guide/philosophy.md
index 9e4012825435bc..ccceeb7016241d 100644
--- a/docs/guide/philosophy.md
+++ b/docs/guide/philosophy.md
@@ -18,7 +18,7 @@ When adding new features, these patterns are followed to create a future-proof A
Vite has been focused on performance since its [origins](./why.md). Its dev server architecture allows HMR that stays fast as projects scale. Vite uses native tools like [esbuild](https://esbuild.github.io/) and [SWC](https://github.com/vitejs/vite-plugin-react-swc) to implement intensive tasks but keeps the rest of the code in JS to balance speed with flexibility. When needed, framework plugins will tap into [Babel](https://babeljs.io/) to compile user code. And during build time Vite currently uses [Rollup](https://rollupjs.org/) where bundling size and having access to a wide ecosystem of plugins are more important than raw speed. Vite will continue to evolve internally, using new libraries as they appear to improve DX while keeping its API stable.
-## Building Frameworks on top of Vite
+## Building Frameworks on Top of Vite
Although Vite can be used by users directly, it shines as a tool to create frameworks. Vite core is framework agnostic, but there are polished plugins for each UI framework. Its [JS API](./api-javascript.md) allows App Framework authors to use Vite features to create tailored experiences for their users. Vite includes support for [SSR primitives](./ssr.md), usually present in higher-level tools but fundamental to building modern web frameworks. And Vite plugins complete the picture by offering a way to share between frameworks. Vite is also a great fit when paired with [Backend frameworks](./backend-integration.md) like [Ruby](https://vite-ruby.netlify.app/) and [Laravel](https://laravel.com/docs/10.x/vite).
diff --git a/docs/guide/troubleshooting.md b/docs/guide/troubleshooting.md
index 1804b589ceb3ed..051ca18a7cd894 100644
--- a/docs/guide/troubleshooting.md
+++ b/docs/guide/troubleshooting.md
@@ -172,7 +172,7 @@ You will need to access the file with `http` protocol. The easiest way to achiev
The hash key used to invalidate optimized dependencies depends on the package lock contents, the patches applied to dependencies, and the options in the Vite config file that affects the bundling of node modules. This means that Vite will detect when a dependency is overridden using a feature as [npm overrides](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides), and re-bundle your dependencies on the next server start. Vite won't invalidate the dependencies when you use a feature like [npm link](https://docs.npmjs.com/cli/v9/commands/npm-link). In case you link or unlink a dependency, you'll need to force re-optimization on the next server start by using `vite --force`. We recommend using overrides instead, which are supported now by every package manager (see also [pnpm overrides](https://pnpm.io/package_json#pnpmoverrides) and [yarn resolutions](https://yarnpkg.com/configuration/manifest/#resolutions)).
-## Performance bottlenecks
+## Performance Bottlenecks
If you suffer any application performance bottlenecks resulting in slow load times, you can start the built-in Node.js inspector with your Vite dev server or when building your application to create the CPU profile:
From 63b82f1e29a00d06a82144fd03ea8d6eff114290 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BF=A0=20/=20green?=
Date: Fri, 13 Dec 2024 21:02:06 +0900
Subject: [PATCH 13/19] chore: better validation error message for dts build
(#18948)
---
packages/vite/rollup.dts.config.ts | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/packages/vite/rollup.dts.config.ts b/packages/vite/rollup.dts.config.ts
index e622053ba156ba..46306f0a22d6b5 100644
--- a/packages/vite/rollup.dts.config.ts
+++ b/packages/vite/rollup.dts.config.ts
@@ -112,13 +112,15 @@ function patchTypes(): Plugin {
* Runner chunk should only import local dependencies to stay lightweight
*/
function validateRunnerChunk(this: PluginContext, chunk: RenderedChunk) {
- for (const id of chunk.imports) {
+ for (const [id, bindings] of Object.entries(chunk.importedBindings)) {
if (
!id.startsWith('./') &&
!id.startsWith('../') &&
!id.startsWith('types.d')
) {
- this.warn(`${chunk.fileName} imports "${id}" which is not allowed`)
+ this.warn(
+ `${chunk.fileName} imports "${bindings.join(', ')}" from "${id}" which is not allowed`,
+ )
process.exitCode = 1
}
}
@@ -129,7 +131,7 @@ function validateRunnerChunk(this: PluginContext, chunk: RenderedChunk) {
*/
function validateChunkImports(this: PluginContext, chunk: RenderedChunk) {
const deps = Object.keys(pkg.dependencies)
- for (const id of chunk.imports) {
+ for (const [id, bindings] of Object.entries(chunk.importedBindings)) {
if (
!id.startsWith('./') &&
!id.startsWith('../') &&
@@ -141,7 +143,9 @@ function validateChunkImports(this: PluginContext, chunk: RenderedChunk) {
) {
// If validation failed, only warn and set exit code 1 so that files
// are written to disk for inspection, but the build will fail
- this.warn(`${chunk.fileName} imports "${id}" which is not allowed`)
+ this.warn(
+ `${chunk.fileName} imports "${bindings.join(', ')}" from "${id}" which is not allowed`,
+ )
process.exitCode = 1
}
}
From 30f256ec8c3a737c35afc186f8a77cecb68bb7ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BF=A0=20/=20green?=
Date: Mon, 16 Dec 2024 12:50:54 +0900
Subject: [PATCH 14/19] test: don't use `__dirname` in tailwind config (#18969)
---
playground/backend-integration/tailwind.config.js | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/playground/backend-integration/tailwind.config.js b/playground/backend-integration/tailwind.config.js
index bf91cec6521e40..7295b40ddd2b1b 100644
--- a/playground/backend-integration/tailwind.config.js
+++ b/playground/backend-integration/tailwind.config.js
@@ -1,5 +1,10 @@
-/** @type {import('tailwindcss').Config} */
+import { fileURLToPath } from 'node:url'
+import { dirname } from 'node:path'
+
+const __filename = fileURLToPath(import.meta.url)
+const __dirname = dirname(__filename)
+/** @type {import('tailwindcss').Config} */
export default {
content: [__dirname + '/frontend/**/*.{css,html,ts,js}'],
theme: {
From 27f691b0c7dca2259108fe6b79583b459429bf7f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BF=A0=20/=20green?=
Date: Mon, 16 Dec 2024 20:42:09 +0900
Subject: [PATCH 15/19] refactor: make internal invoke event to use the same
interface with `handleInvoke` (#18902)
---
packages/vite/src/node/server/hmr.ts | 14 ++++----------
packages/vite/src/shared/invokeMethods.ts | 4 ++--
packages/vite/src/shared/moduleRunnerTransport.ts | 8 ++++----
3 files changed, 10 insertions(+), 16 deletions(-)
diff --git a/packages/vite/src/node/server/hmr.ts b/packages/vite/src/node/server/hmr.ts
index b4993bd31c6b7e..8683f9a7b37c24 100644
--- a/packages/vite/src/node/server/hmr.ts
+++ b/packages/vite/src/node/server/hmr.ts
@@ -193,7 +193,7 @@ export const normalizeHotChannel = (
) => {
if (!invokeHandlers) {
return {
- e: {
+ error: {
name: 'TransportError',
message: 'invokeHandlers is not set',
stack: new Error().stack,
@@ -207,10 +207,10 @@ export const normalizeHotChannel = (
const invokeHandler = invokeHandlers[name]
// @ts-expect-error `invokeHandler` is `InvokeMethods[T]`, so passing the args is fine
const result = await invokeHandler(...args)
- return { r: result }
+ return { result }
} catch (error) {
return {
- e: {
+ error: {
name: error.name,
message: error.message,
stack: error.stack,
@@ -301,13 +301,7 @@ export const normalizeHotChannel = (
}
channel.on?.('vite:invoke', listenerForInvokeHandler)
},
- handleInvoke: async (payload) => {
- const data = await handleInvoke(payload)
- if (data.e) {
- return { error: data.e }
- }
- return { result: data.r }
- },
+ handleInvoke,
send: (...args: any[]) => {
let payload: HotPayload
if (typeof args[0] === 'string') {
diff --git a/packages/vite/src/shared/invokeMethods.ts b/packages/vite/src/shared/invokeMethods.ts
index b37adacc0cb3ef..7a6f3f02ef8e04 100644
--- a/packages/vite/src/shared/invokeMethods.ts
+++ b/packages/vite/src/shared/invokeMethods.ts
@@ -72,8 +72,8 @@ export type InvokeResponseData<
/** 'response' is for responses without an id */
id: 'response' | `response:${string}`
data:
- | { r: Awaited>; e?: undefined }
- | { r?: undefined; e: any }
+ | { result: Awaited>; error?: undefined }
+ | { result?: undefined; error: any }
}
export type InvokeMethods = {
diff --git a/packages/vite/src/shared/moduleRunnerTransport.ts b/packages/vite/src/shared/moduleRunnerTransport.ts
index 23b91c7a5bf50d..e70adb3067413a 100644
--- a/packages/vite/src/shared/moduleRunnerTransport.ts
+++ b/packages/vite/src/shared/moduleRunnerTransport.ts
@@ -96,11 +96,11 @@ const createInvokeableTransport = (
rpcPromises.delete(invokeId)
- const { e, r } = data.data
- if (e) {
- promise.reject(e)
+ const { error, result } = data.data
+ if (error) {
+ promise.reject(error)
} else {
- promise.resolve(r)
+ promise.resolve(result)
}
return
}
From c4b532cc900bf988073583511f57bd581755d5e3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BF=A0=20/=20green?=
Date: Mon, 16 Dec 2024 20:43:52 +0900
Subject: [PATCH 16/19] fix(css): root relative import in sass modern API on
Windows (#18945)
---
packages/vite/src/node/plugins/css.ts | 10 ++++++++--
playground/css/__tests__/css.spec.ts | 1 +
playground/css/index.html | 3 +++
playground/css/nested/_index.scss | 1 +
playground/css/nested/root-relative.scss | 3 +++
5 files changed, 16 insertions(+), 2 deletions(-)
create mode 100644 playground/css/nested/root-relative.scss
diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts
index 04c0f87982fa2e..3453cadf1d2332 100644
--- a/packages/vite/src/node/plugins/css.ts
+++ b/packages/vite/src/node/plugins/css.ts
@@ -82,7 +82,7 @@ import {
urlRE,
} from '../utils'
import type { Logger } from '../logger'
-import { cleanUrl, slash } from '../../shared/utils'
+import { cleanUrl, isWindows, slash } from '../../shared/utils'
import { createBackCompatIdResolver } from '../idResolver'
import type { ResolveIdFn } from '../idResolver'
import { PartialEnvironment } from '../baseEnvironment'
@@ -1162,8 +1162,14 @@ function createCSSResolvers(config: ResolvedConfig): CSSAtImportResolvers {
preferRelative: true,
})
sassResolve = async (...args) => {
+ // the modern API calls `canonicalize` with resolved file URLs
+ // for relative URLs before raw specifiers
if (args[1].startsWith('file://')) {
- args[1] = fileURLToPath(args[1])
+ args[1] = fileURLToPath(args[1], {
+ windows:
+ // file:///foo cannot be converted to path with windows mode
+ isWindows && args[1].startsWith('file:///') ? false : undefined,
+ })
}
return resolver(...args)
}
diff --git a/playground/css/__tests__/css.spec.ts b/playground/css/__tests__/css.spec.ts
index 553a1c70331793..f0ff63c6b5dbb5 100644
--- a/playground/css/__tests__/css.spec.ts
+++ b/playground/css/__tests__/css.spec.ts
@@ -101,6 +101,7 @@ test('sass', async () => {
expect(await getColor(partialImport)).toBe('orchid')
expect(await getColor(await page.$('.sass-file-absolute'))).toBe('orange')
expect(await getColor(await page.$('.sass-dir-index'))).toBe('orange')
+ expect(await getColor(await page.$('.sass-root-relative'))).toBe('orange')
if (isBuild) return
diff --git a/playground/css/index.html b/playground/css/index.html
index 45525412570992..9918757eb1bee6 100644
--- a/playground/css/index.html
+++ b/playground/css/index.html
@@ -43,6 +43,9 @@ CSS
@import "file:///xxx/absolute-path.scss" should be orange
@import "./dir" should be orange
+
+ @import "/nested/root-relative.scss" should be orange
+
Less: This should be blue
diff --git a/playground/css/nested/_index.scss b/playground/css/nested/_index.scss
index 72e6b14268334e..ff81e7d82351b9 100644
--- a/playground/css/nested/_index.scss
+++ b/playground/css/nested/_index.scss
@@ -1,4 +1,5 @@
@use 'sass:string';
+@use '/nested/root-relative'; // root relative path
@import './css-in-scss.css';
diff --git a/playground/css/nested/root-relative.scss b/playground/css/nested/root-relative.scss
new file mode 100644
index 00000000000000..775dca855743b3
--- /dev/null
+++ b/playground/css/nested/root-relative.scss
@@ -0,0 +1,3 @@
+.sass-root-relative {
+ color: orange;
+}
From 7d6dd5d1d655d173668192509f63ac4ebf7af299 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BF=A0=20/=20green?=
Date: Tue, 17 Dec 2024 04:46:27 +0900
Subject: [PATCH 17/19] fix(ssr): recreate ssrCompatModuleRunner on restart
(#18973)
---
packages/vite/src/node/server/index.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts
index 5828a90be3043d..32a3371cef527b 100644
--- a/packages/vite/src/node/server/index.ts
+++ b/packages/vite/src/node/server/index.ts
@@ -690,6 +690,7 @@ export async function _createServer(
server._ssrCompatModuleRunner?.close(),
])
server.resolvedUrls = null
+ server._ssrCompatModuleRunner = undefined
},
printUrls() {
if (server.resolvedUrls) {
From 8a6bb4e11d5c1b61511ae1e5ed3ae3c65a33b2dc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BF=A0=20/=20green?=
Date: Tue, 17 Dec 2024 04:48:42 +0900
Subject: [PATCH 18/19] fix(optimizer): keep NODE_ENV as-is when keepProcessEnv
is `true` (#18899)
Co-authored-by: Dario Piotrowicz
---
packages/vite/src/node/optimizer/index.ts | 12 ++++++++----
.../__tests__/environment-react-ssr.spec.ts | 13 +++++++++++++
2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts
index 36503d4ee37f5e..1e528190f85b7d 100644
--- a/packages/vite/src/node/optimizer/index.ts
+++ b/packages/vite/src/node/optimizer/index.ts
@@ -775,9 +775,11 @@ async function prepareEsbuildOptimizerRun(
if (optimizerContext.cancelled) return { context: undefined, idToExports }
const define = {
- 'process.env.NODE_ENV': JSON.stringify(
- process.env.NODE_ENV || environment.config.mode,
- ),
+ 'process.env.NODE_ENV': environment.config.keepProcessEnv
+ ? // define process.env.NODE_ENV even for keepProcessEnv === true
+ // as esbuild will replace it automatically when `platform` is `'browser'`
+ 'process.env.NODE_ENV'
+ : JSON.stringify(process.env.NODE_ENV || environment.config.mode),
}
const platform =
@@ -1210,7 +1212,9 @@ function getConfigHash(environment: Environment): string {
const { optimizeDeps } = config
const content = JSON.stringify(
{
- mode: process.env.NODE_ENV || config.mode,
+ define: !config.keepProcessEnv
+ ? process.env.NODE_ENV || config.mode
+ : null,
root: config.root,
resolve: config.resolve,
assetsInclude: config.assetsInclude,
diff --git a/playground/environment-react-ssr/__tests__/environment-react-ssr.spec.ts b/playground/environment-react-ssr/__tests__/environment-react-ssr.spec.ts
index 2f4da3b570395d..247f980cab9944 100644
--- a/playground/environment-react-ssr/__tests__/environment-react-ssr.spec.ts
+++ b/playground/environment-react-ssr/__tests__/environment-react-ssr.spec.ts
@@ -38,6 +38,19 @@ describe.runIf(!isBuild)('pre-bundling', () => {
expect(metaJson.optimized['react/jsx-dev-runtime']).toBeTruthy()
expect(metaJson.optimized['react-dom/client']).toBeFalsy()
+
+ // process.env.NODE_ENV should be kept as keepProcessEnv is true
+ const depsFiles = fs
+ .readdirSync(path.resolve(testDir, 'node_modules/.vite/deps_ssr'), {
+ withFileTypes: true,
+ })
+ .filter((file) => file.isFile() && file.name.endsWith('.js'))
+ .map((file) => path.join(file.parentPath, file.name))
+ const depsFilesWithProcessEnvNodeEnv = depsFiles.filter((file) =>
+ fs.readFileSync(file, 'utf-8').includes('process.env.NODE_ENV'),
+ )
+
+ expect(depsFilesWithProcessEnvNodeEnv.length).toBeGreaterThan(0)
})
test('deps reload', async () => {
From ccd1a4c4145ee1069d7baea56981a0322e7be864 Mon Sep 17 00:00:00 2001
From: Hichem Fantar
Date: Mon, 16 Dec 2024 21:54:47 +0100
Subject: [PATCH 19/19] docs: display file name in a better way (#18937)
---
docs/config/index.md | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/docs/config/index.md b/docs/config/index.md
index b380b4b5988230..0583f69bd52d13 100644
--- a/docs/config/index.md
+++ b/docs/config/index.md
@@ -8,8 +8,7 @@ When running `vite` from the command line, Vite will automatically try to resolv
The most basic config file looks like this:
-```js
-// vite.config.js
+```js [vite.config.js]
export default {
// config options
}