>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
diff --git a/packages/vite/package.json b/packages/vite/package.json
index aefddcba192196..97141f087b2e0a 100644
--- a/packages/vite/package.json
+++ b/packages/vite/package.json
@@ -1,6 +1,6 @@
{
"name": "vite",
- "version": "4.0.2",
+ "version": "4.0.3",
"type": "module",
"license": "MIT",
"author": "Evan You",
diff --git a/packages/vite/src/node/__tests__/build.spec.ts b/packages/vite/src/node/__tests__/build.spec.ts
index 4e65a2848602d3..94ebb685b7b7cb 100644
--- a/packages/vite/src/node/__tests__/build.spec.ts
+++ b/packages/vite/src/node/__tests__/build.spec.ts
@@ -3,14 +3,107 @@ import { fileURLToPath } from 'node:url'
import colors from 'picocolors'
import type { Logger } from 'vite'
import { describe, expect, test, vi } from 'vitest'
-import type { OutputOptions } from 'rollup'
+import type { OutputChunk, OutputOptions, RollupOutput } from 'rollup'
import type { LibraryFormats, LibraryOptions } from '../build'
-import { resolveBuildOutputs, resolveLibFilename } from '../build'
+import { build, resolveBuildOutputs, resolveLibFilename } from '../build'
import { createLogger } from '../logger'
const __dirname = resolve(fileURLToPath(import.meta.url), '..')
type FormatsToFileNames = [LibraryFormats, string][]
+
+describe('build', () => {
+ test('file hash should change when css changes for dynamic entries', async () => {
+ const buildProject = async (cssColor: string) => {
+ return (await build({
+ root: resolve(__dirname, 'packages/build-project'),
+ logLevel: 'silent',
+ build: {
+ write: false,
+ },
+ plugins: [
+ {
+ name: 'test',
+ resolveId(id) {
+ if (
+ id === 'entry.js' ||
+ id === 'subentry.js' ||
+ id === 'foo.css'
+ ) {
+ return '\0' + id
+ }
+ },
+ load(id) {
+ if (id === '\0entry.js') {
+ return `window.addEventListener('click', () => { import('subentry.js') });`
+ }
+ if (id === '\0subentry.js') {
+ return `import 'foo.css'`
+ }
+ if (id === '\0foo.css') {
+ return `.foo { color: ${cssColor} }`
+ }
+ },
+ },
+ ],
+ })) as RollupOutput
+ }
+ const result = await Promise.all([
+ buildProject('red'),
+ buildProject('blue'),
+ ])
+ assertOutputHashContentChange(result[0], result[1])
+ })
+
+ test('file hash should change when pure css chunk changes', async () => {
+ const buildProject = async (cssColor: string) => {
+ return (await build({
+ root: resolve(__dirname, 'packages/build-project'),
+ logLevel: 'silent',
+ build: {
+ write: false,
+ },
+ plugins: [
+ {
+ name: 'test',
+ resolveId(id) {
+ if (
+ id === 'entry.js' ||
+ id === 'foo.js' ||
+ id === 'bar.js' ||
+ id === 'baz.js' ||
+ id === 'foo.css' ||
+ id === 'bar.css' ||
+ id === 'baz.css'
+ ) {
+ return '\0' + id
+ }
+ },
+ load(id) {
+ if (id === '\0entry.js') {
+ return `
+ window.addEventListener('click', () => { import('foo.js') });
+ window.addEventListener('click', () => { import('bar.js') });`
+ }
+ if (id === '\0foo.js') return `import 'foo.css'; import 'baz.js'`
+ if (id === '\0bar.js') return `import 'bar.css'; import 'baz.js'`
+ if (id === '\0baz.js') return `import 'baz.css'`
+ if (id === '\0foo.css') return `.foo { color: red }`
+ if (id === '\0bar.css') return `.foo { color: green }`
+ if (id === '\0baz.css') return `.foo { color: ${cssColor} }`
+ },
+ },
+ ],
+ })) as RollupOutput
+ }
+ const result = await Promise.all([
+ buildProject('yellow'),
+ buildProject('blue'),
+ ])
+ assertOutputHashContentChange(result[0], result[1])
+ })
+})
+
const baseLibOptions: LibraryOptions = {
fileName: 'my-lib',
entry: 'mylib.js',
@@ -439,3 +532,26 @@ describe('resolveBuildOutputs', () => {
)
})
})
+
+/**
+ * for each chunks in output1, if there's a chunk in output2 with the same fileName,
+ * ensure that the chunk code is the same. if not, the chunk hash should have changed.
+ */
+function assertOutputHashContentChange(
+ output1: RollupOutput,
+ output2: RollupOutput,
+) {
+ for (const chunk of output1.output) {
+ if (chunk.type === 'chunk') {
+ const chunk2 = output2.output.find(
+ (c) => c.type === 'chunk' && c.fileName === chunk.fileName,
+ ) as OutputChunk | undefined
+ if (chunk2) {
+ expect(
+ chunk.code,
+ `the ${chunk.fileName} chunk has the same hash but different contents between builds`,
+ ).toEqual(chunk2.code)
+ }
+ }
+ }
+}
diff --git a/packages/vite/src/node/__tests__/packages/build-project/index.html b/packages/vite/src/node/__tests__/packages/build-project/index.html
new file mode 100644
index 00000000000000..f05e0c91dbb125
--- /dev/null
+++ b/packages/vite/src/node/__tests__/packages/build-project/index.html
@@ -0,0 +1,3 @@
+Hello world
+
+
diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts
index 954d50e936862d..d2dcb607a1b630 100644
--- a/packages/vite/src/node/plugins/asset.ts
+++ b/packages/vite/src/node/plugins/asset.ts
@@ -210,6 +210,10 @@ export function checkPublicFile(
return
}
const publicFile = path.join(publicDir, cleanUrl(url))
+ if (!publicFile.startsWith(publicDir)) {
+ // can happen if URL starts with '../'
+ return
+ }
if (fs.existsSync(publicFile)) {
return publicFile
} else {
diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts
index 9834858bf1a878..142a696662f5e3 100644
--- a/packages/vite/src/node/plugins/css.ts
+++ b/packages/vite/src/node/plugins/css.ts
@@ -622,6 +622,16 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
return null
},
+ augmentChunkHash(chunk) {
+ if (chunk.viteMetadata?.importedCss.size) {
+ let hash = ''
+ for (const id of chunk.viteMetadata.importedCss) {
+ hash += id
+ }
+ return hash
+ }
+ },
+
async generateBundle(opts, bundle) {
// @ts-expect-error asset emits are skipped in legacy bundle
if (opts.__vite_skip_asset_emit__) {
diff --git a/packages/vite/src/node/ssr/ssrModuleLoader.ts b/packages/vite/src/node/ssr/ssrModuleLoader.ts
index 4952eed7645a79..4cb226de83944e 100644
--- a/packages/vite/src/node/ssr/ssrModuleLoader.ts
+++ b/packages/vite/src/node/ssr/ssrModuleLoader.ts
@@ -8,7 +8,7 @@ import {
usingDynamicImport,
} from '../utils'
import { transformRequest } from '../server/transformRequest'
-import type { InternalResolveOptions } from '../plugins/resolve'
+import type { InternalResolveOptionsWithOverrideConditions } from '../plugins/resolve'
import { tryNodeResolve } from '../plugins/resolve'
import {
ssrDynamicImportKey,
@@ -112,10 +112,11 @@ async function instantiateModule(
root,
} = server.config
- const resolveOptions: InternalResolveOptions = {
+ const resolveOptions: InternalResolveOptionsWithOverrideConditions = {
mainFields: ['main'],
browserField: true,
conditions: [],
+ overrideConditions: ['production', 'development'],
extensions: ['.js', '.cjs', '.json'],
dedupe,
preserveSymlinks,
@@ -223,7 +224,7 @@ async function instantiateModule(
async function nodeImport(
id: string,
importer: string,
- resolveOptions: InternalResolveOptions,
+ resolveOptions: InternalResolveOptionsWithOverrideConditions,
) {
let url: string
if (id.startsWith('node:') || isBuiltin(id)) {
diff --git a/packages/vite/src/types/chokidar.d.ts b/packages/vite/src/types/chokidar.d.ts
index 83f96ed952024f..36ae23279c7349 100644
--- a/packages/vite/src/types/chokidar.d.ts
+++ b/packages/vite/src/types/chokidar.d.ts
@@ -158,7 +158,7 @@ export interface WatchOptions {
/**
* Whether to use the `fsevents` watching interface if available. When set to `true` explicitly
- * and `fsevents` is available this supercedes the `usePolling` setting. When set to `false` on
+ * and `fsevents` is available this supersedes the `usePolling` setting. When set to `false` on
* OS X, `usePolling: true` becomes the default.
*/
useFsEvents?: boolean
diff --git a/playground/optimize-deps/__tests__/optimize-deps.spec.ts b/playground/optimize-deps/__tests__/optimize-deps.spec.ts
index d5c1db21d4db3b..9b6106e39940da 100644
--- a/playground/optimize-deps/__tests__/optimize-deps.spec.ts
+++ b/playground/optimize-deps/__tests__/optimize-deps.spec.ts
@@ -113,8 +113,10 @@ test('CJS dep with css import', async () => {
expect(await getColor('.cjs-with-assets')).toBe('blue')
})
-test('dep w/ non-js files handled via plugin', async () => {
- expect(await page.textContent('.plugin')).toMatch(`[success]`)
+test('externalize known non-js files in optimize included dep', async () => {
+ expect(await page.textContent('.externalize-known-non-js')).toMatch(
+ `[success]`,
+ )
})
test('vue + vuex', async () => {
diff --git a/playground/optimize-deps/index.html b/playground/optimize-deps/index.html
index d0587e0905dd4d..16f72b9a4899a2 100644
--- a/playground/optimize-deps/index.html
+++ b/playground/optimize-deps/index.html
@@ -65,8 +65,8 @@ Import from dependency with dynamic import
Import from dependency with optional peer dep
-Dep w/ special file format supported via plugins
-
+Externalize known non-js files in optimize included dep
+
Vue & Vuex
@@ -111,7 +111,7 @@ Non Optimized Module isn't duplicated
import { msg, VueSFC } from '@vitejs/test-dep-linked-include'
text('.force-include', msg)
- text('.plugin', VueSFC.render())
+ text('.externalize-known-non-js', VueSFC.render())
import * as linked from '@vitejs/test-dep-linked-include'
const keys = Object.keys(linked)
diff --git a/playground/optimize-deps/package.json b/playground/optimize-deps/package.json
index 7e74b72566b346..675dd035e494d2 100644
--- a/playground/optimize-deps/package.json
+++ b/playground/optimize-deps/package.json
@@ -38,8 +38,5 @@
"vuex": "^4.1.0",
"lodash": "^4.17.21",
"lodash.clonedeep": "^4.5.0"
- },
- "devDependencies": {
- "@vitejs/plugin-vue": "^4.0.0"
}
}
diff --git a/playground/optimize-deps/vite.config.js b/playground/optimize-deps/vite.config.js
index 3465f66ff2efe6..b07f519783762e 100644
--- a/playground/optimize-deps/vite.config.js
+++ b/playground/optimize-deps/vite.config.js
@@ -1,5 +1,4 @@
const fs = require('node:fs')
-const vue = require('@vitejs/plugin-vue')
// Overriding the NODE_ENV set by vitest
process.env.NODE_ENV = ''
@@ -52,7 +51,7 @@ module.exports = {
},
plugins: [
- vue(),
+ testVue(),
notjs(),
// for axios request test
{
@@ -95,6 +94,29 @@ module.exports = {
],
}
+// Handles Test.vue in dep-linked-include package
+function testVue() {
+ return {
+ name: 'testvue',
+ transform(code, id) {
+ if (id.includes('dep-linked-include/Test.vue')) {
+ return {
+ code: `
+import { defineComponent } from 'vue'
+
+export default defineComponent({
+ name: 'Test',
+ render() {
+ return '[success] rendered from Vue'
+ }
+})
+`.trim(),
+ }
+ }
+ },
+ }
+}
+
// Handles .notjs file, basically remove wrapping and tags
function notjs() {
return {
diff --git a/playground/preload/__tests__/preload-disabled/preload-disabled.spec.ts b/playground/preload/__tests__/preload-disabled/preload-disabled.spec.ts
index 5be5b07a0774f6..638b8f241a0943 100644
--- a/playground/preload/__tests__/preload-disabled/preload-disabled.spec.ts
+++ b/playground/preload/__tests__/preload-disabled/preload-disabled.spec.ts
@@ -1,5 +1,5 @@
import { describe, expect, test } from 'vitest'
-import { browserLogs, isBuild, page, viteTestUrl } from '~utils'
+import { browserLogs, isBuild, page } from '~utils'
test('should have no 404s', () => {
browserLogs.forEach((msg) => {
@@ -9,12 +9,14 @@ test('should have no 404s', () => {
describe.runIf(isBuild)('build', () => {
test('dynamic import', async () => {
- const appHtml = await page.content()
- expect(appHtml).toMatch('This is home page.')
+ await page.waitForSelector('#done')
+ expect(await page.textContent('#done')).toBe('ran js')
})
test('dynamic import with comments', async () => {
- await page.goto(viteTestUrl + '/#/hello')
+ await page.click('#hello .load')
+ await page.waitForSelector('#hello output')
+
const html = await page.content()
expect(html).not.toMatch(/link rel="modulepreload"/)
expect(html).not.toMatch(/link rel="stylesheet"/)
diff --git a/playground/preload/__tests__/preload.spec.ts b/playground/preload/__tests__/preload.spec.ts
index 9407d26942456a..fd89d58a80b1a9 100644
--- a/playground/preload/__tests__/preload.spec.ts
+++ b/playground/preload/__tests__/preload.spec.ts
@@ -1,5 +1,5 @@
import { describe, expect, test } from 'vitest'
-import { browserLogs, isBuild, page, viteTestUrl } from '~utils'
+import { browserLogs, isBuild, page } from '~utils'
test('should have no 404s', () => {
browserLogs.forEach((msg) => {
@@ -9,18 +9,20 @@ test('should have no 404s', () => {
describe.runIf(isBuild)('build', () => {
test('dynamic import', async () => {
- const appHtml = await page.content()
- expect(appHtml).toMatch('This is home page.')
+ await page.waitForSelector('#done')
+ expect(await page.textContent('#done')).toBe('ran js')
})
test('dynamic import with comments', async () => {
- await page.goto(viteTestUrl + '/#/hello')
+ await page.click('#hello .load')
+ await page.waitForSelector('#hello output')
+
const html = await page.content()
expect(html).toMatch(
- /link rel="modulepreload".*?href=".*?\/assets\/Hello-\w{8}\.js"/,
+ /link rel="modulepreload".*?href=".*?\/assets\/hello-\w{8}\.js"/,
)
expect(html).toMatch(
- /link rel="stylesheet".*?href=".*?\/assets\/Hello-\w{8}\.css"/,
+ /link rel="stylesheet".*?href=".*?\/assets\/hello-\w{8}\.css"/,
)
})
})
diff --git a/playground/preload/__tests__/resolve-deps/preload-resolve-deps.spec.ts b/playground/preload/__tests__/resolve-deps/preload-resolve-deps.spec.ts
index 78a19d7c09cb35..c255919c4cf598 100644
--- a/playground/preload/__tests__/resolve-deps/preload-resolve-deps.spec.ts
+++ b/playground/preload/__tests__/resolve-deps/preload-resolve-deps.spec.ts
@@ -1,5 +1,5 @@
import { describe, expect, test } from 'vitest'
-import { browserLogs, isBuild, page, viteTestUrl } from '~utils'
+import { browserLogs, isBuild, page } from '~utils'
test('should have no 404s', () => {
browserLogs.forEach((msg) => {
@@ -9,19 +9,21 @@ test('should have no 404s', () => {
describe.runIf(isBuild)('build', () => {
test('dynamic import', async () => {
- const appHtml = await page.content()
- expect(appHtml).toMatch('This is home page.')
+ await page.waitForSelector('#done')
+ expect(await page.textContent('#done')).toBe('ran js')
})
test('dynamic import with comments', async () => {
- await page.goto(viteTestUrl + '/#/hello')
+ await page.click('#hello .load')
+ await page.waitForSelector('#hello output')
+
const html = await page.content()
expect(html).toMatch(
- /link rel="modulepreload".*?href="http.*?\/Hello-\w{8}\.js"/,
+ /link rel="modulepreload".*?href="http.*?\/hello-\w{8}\.js"/,
)
expect(html).toMatch(/link rel="modulepreload".*?href="\/preloaded.js"/)
expect(html).toMatch(
- /link rel="stylesheet".*?href="http.*?\/Hello-\w{8}\.css"/,
+ /link rel="stylesheet".*?href="http.*?\/hello-\w{8}\.css"/,
)
})
})
diff --git a/playground/preload/index.html b/playground/preload/index.html
index 492481daeea2a5..59f13ff117eb5d 100644
--- a/playground/preload/index.html
+++ b/playground/preload/index.html
@@ -1,10 +1,19 @@
-
+preload
+
+
+
diff --git a/playground/preload/package.json b/playground/preload/package.json
index 187ab8f45adb40..2e236a4a69b83e 100644
--- a/playground/preload/package.json
+++ b/playground/preload/package.json
@@ -16,12 +16,7 @@
"debug:preload-disabled": "node --inspect-brk ../../packages/vite/bin/vite --config vite.config-preload-disabled.ts",
"preview:preload-disabled": "vite preview --config vite.config-preload-disabled.ts"
},
- "dependencies": {
- "vue": "^3.2.45",
- "vue-router": "^4.1.6"
- },
"devDependencies": {
- "@vitejs/plugin-vue": "^4.0.0",
"terser": "^5.16.1",
"@vitejs/test-dep-a": "file:./dep-a",
"@vitejs/test-dep-including-a": "file:./dep-including-a"
diff --git a/playground/preload/router.js b/playground/preload/router.js
deleted file mode 100644
index 2e4388967838ae..00000000000000
--- a/playground/preload/router.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import { createRouter, createWebHashHistory } from 'vue-router'
-import Home from './src/components/Home.vue'
-
-const routes = [
- { path: '/', name: 'Home', component: Home },
- {
- path: '/hello',
- name: 'Hello',
- component: () => import(/* a comment */ './src/components/Hello.vue'),
- },
- {
- path: '/about',
- name: 'About',
- component: () => import('./src/components/About.vue'),
- }, // Lazy load route component
-]
-
-export default createRouter({
- routes,
- history: createWebHashHistory(),
-})
diff --git a/playground/preload/src/App.vue b/playground/preload/src/App.vue
deleted file mode 100644
index 3582faf75e1216..00000000000000
--- a/playground/preload/src/App.vue
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/playground/preload/src/about.js b/playground/preload/src/about.js
new file mode 100644
index 00000000000000..56b5fd6e8bcfe1
--- /dev/null
+++ b/playground/preload/src/about.js
@@ -0,0 +1,3 @@
+import { msg } from '@vitejs/test-dep-including-a'
+
+document.querySelector('#about .msg').textContent = msg
diff --git a/playground/preload/src/components/About.vue b/playground/preload/src/components/About.vue
deleted file mode 100644
index a9449af186e38a..00000000000000
--- a/playground/preload/src/components/About.vue
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
- This is about page.
-
- Go to Home page
-
- {{ msg }}
-
-
diff --git a/playground/preload/src/components/Hello.vue b/playground/preload/src/components/Hello.vue
deleted file mode 100644
index 33b44d278d305d..00000000000000
--- a/playground/preload/src/components/Hello.vue
+++ /dev/null
@@ -1,18 +0,0 @@
-
- {{ msg }}
-
- This is hello page.
-
- Go to Home page
-
-
-
-
-
-
diff --git a/playground/preload/src/components/Home.vue b/playground/preload/src/components/Home.vue
deleted file mode 100644
index 20f6b4948ac30a..00000000000000
--- a/playground/preload/src/components/Home.vue
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- This is home page.
-
- Go to About page
-
- Go to Hello page
-
-
-
-
diff --git a/playground/preload/src/hello.js b/playground/preload/src/hello.js
new file mode 100644
index 00000000000000..d2c5ee4ff3f9e5
--- /dev/null
+++ b/playground/preload/src/hello.js
@@ -0,0 +1,5 @@
+import style from './hello.module.css'
+
+const msg = document.querySelector('#hello .msg')
+msg.textContent = 'hello'
+msg.classList.add(style.h1)
diff --git a/playground/preload/src/hello.module.css b/playground/preload/src/hello.module.css
new file mode 100644
index 00000000000000..23910a7820b889
--- /dev/null
+++ b/playground/preload/src/hello.module.css
@@ -0,0 +1,3 @@
+.h1 {
+ color: red;
+}
diff --git a/playground/preload/src/main.js b/playground/preload/src/main.js
new file mode 100644
index 00000000000000..d6c80df573ebff
--- /dev/null
+++ b/playground/preload/src/main.js
@@ -0,0 +1,16 @@
+const ids = {
+ hello: async () => {
+ await import(/* a comment */ './hello.js')
+ },
+ about: async () => {
+ await import('./about.js') // lazy load
+ },
+}
+
+for (const [id, loader] of Object.entries(ids)) {
+ const loadButton = document.querySelector(`#${id} .load`)
+ loadButton.addEventListener('click', async () => {
+ await loader()
+ loadButton.insertAdjacentHTML('afterend', '')
+ })
+}
diff --git a/playground/preload/vite.config-preload-disabled.ts b/playground/preload/vite.config-preload-disabled.ts
index ea420d7e721590..4cef9067fe93f2 100644
--- a/playground/preload/vite.config-preload-disabled.ts
+++ b/playground/preload/vite.config-preload-disabled.ts
@@ -1,8 +1,6 @@
-import vuePlugin from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
export default defineConfig({
- plugins: [vuePlugin()],
build: {
outDir: 'dist/preload-disabled',
minify: 'terser',
diff --git a/playground/preload/vite.config-resolve-deps.ts b/playground/preload/vite.config-resolve-deps.ts
index 499096e09c69bb..d9a859c2491b5e 100644
--- a/playground/preload/vite.config-resolve-deps.ts
+++ b/playground/preload/vite.config-resolve-deps.ts
@@ -1,8 +1,6 @@
-import vuePlugin from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
export default defineConfig({
- plugins: [vuePlugin()],
build: {
outDir: 'dist/resolve-deps',
minify: 'terser',
@@ -16,7 +14,7 @@ export default defineConfig({
},
modulePreload: {
resolveDependencies(filename, deps, { hostId, hostType }) {
- if (filename.includes('Hello')) {
+ if (filename.includes('hello')) {
return [...deps, 'preloaded.js']
}
return deps
diff --git a/playground/preload/vite.config.ts b/playground/preload/vite.config.ts
index 2c50a70759c138..c6aa914e71aadf 100644
--- a/playground/preload/vite.config.ts
+++ b/playground/preload/vite.config.ts
@@ -1,8 +1,6 @@
-import vuePlugin from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
export default defineConfig({
- plugins: [vuePlugin()],
build: {
outDir: 'dist/normal',
minify: 'terser',
diff --git a/playground/ssr-deps/__tests__/ssr-deps.spec.ts b/playground/ssr-deps/__tests__/ssr-deps.spec.ts
index 5a45d047ee86a0..a6d8973977e7a3 100644
--- a/playground/ssr-deps/__tests__/ssr-deps.spec.ts
+++ b/playground/ssr-deps/__tests__/ssr-deps.spec.ts
@@ -116,3 +116,8 @@ test('import css library', async () => {
await page.goto(url)
expect(await getColor('.css-lib')).toBe('blue')
})
+
+test('import css library', async () => {
+ await page.goto(url)
+ expect(await page.textContent('.module-condition')).toMatch('[success]')
+})
diff --git a/playground/ssr-deps/module-condition/import.mjs b/playground/ssr-deps/module-condition/import.mjs
new file mode 100644
index 00000000000000..2ecbfe1a42cf13
--- /dev/null
+++ b/playground/ssr-deps/module-condition/import.mjs
@@ -0,0 +1 @@
+export default '[success]'
diff --git a/playground/ssr-deps/module-condition/module.js b/playground/ssr-deps/module-condition/module.js
new file mode 100644
index 00000000000000..2a5cbd94bcad9b
--- /dev/null
+++ b/playground/ssr-deps/module-condition/module.js
@@ -0,0 +1,4 @@
+// this is written in ESM but the file extension implies this is evaluated as CJS.
+// BUT this doesn't matter in practice as the `module` condition is not used in node.
+// hence SSR should not load this file.
+export default '[fail] should not load me'
diff --git a/playground/ssr-deps/module-condition/package.json b/playground/ssr-deps/module-condition/package.json
new file mode 100644
index 00000000000000..e7809eced127bb
--- /dev/null
+++ b/playground/ssr-deps/module-condition/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@vitejs/test-module-condition",
+ "private": true,
+ "version": "0.0.0",
+ "exports": {
+ ".": {
+ "module": "./module.js",
+ "import": "./import.mjs"
+ }
+ }
+}
diff --git a/playground/ssr-deps/package.json b/playground/ssr-deps/package.json
index 13d641b4d6efaf..ce48077dc196d0 100644
--- a/playground/ssr-deps/package.json
+++ b/playground/ssr-deps/package.json
@@ -29,7 +29,8 @@
"@vitejs/test-external-using-external-entry": "file:./external-using-external-entry",
"@vitejs/test-external-entry": "file:./external-entry",
"@vitejs/test-linked-no-external": "link:./linked-no-external",
- "@vitejs/test-pkg-exports": "file:./pkg-exports"
+ "@vitejs/test-pkg-exports": "file:./pkg-exports",
+ "@vitejs/test-module-condition": "file:./module-condition"
},
"devDependencies": {
"express": "^4.18.2"
diff --git a/playground/ssr-deps/src/app.js b/playground/ssr-deps/src/app.js
index 0f71a24d9d0bd9..0af57b094d76e0 100644
--- a/playground/ssr-deps/src/app.js
+++ b/playground/ssr-deps/src/app.js
@@ -15,6 +15,7 @@ import noExternalCjs from '@vitejs/test-no-external-cjs'
import importBuiltinCjs from '@vitejs/test-import-builtin-cjs'
import { hello as linkedNoExternal } from '@vitejs/test-linked-no-external'
import virtualMessage from '@vitejs/test-pkg-exports/virtual'
+import moduleConditionMessage from '@vitejs/test-module-condition'
import '@vitejs/test-css-lib'
// This import will set a 'Hello World!" message in the nested-external non-entry dependency
@@ -87,5 +88,7 @@ export async function render(url, rootDir) {
html += `\nI should be blue
`
+ html += `\n${moduleConditionMessage}
`
+
return html + '\n'
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6fb5671e0e696a..99b11979a3f3dc 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -609,7 +609,6 @@ importers:
playground/optimize-deps:
specifiers:
- '@vitejs/plugin-vue': ^4.0.0
'@vitejs/test-added-in-entries': file:./added-in-entries
'@vitejs/test-dep-cjs-browser-field-bare': file:./dep-cjs-browser-field-bare
'@vitejs/test-dep-cjs-compiled-from-cjs': file:./dep-cjs-compiled-from-cjs
@@ -669,8 +668,6 @@ importers:
url: 0.11.0
vue: 3.2.45
vuex: 4.1.0_vue@3.2.45
- devDependencies:
- '@vitejs/plugin-vue': 4.0.0_vue@3.2.45
playground/optimize-deps/added-in-entries:
specifiers: {}
@@ -758,17 +755,10 @@ importers:
playground/preload:
specifiers:
- '@vitejs/plugin-vue': ^4.0.0
'@vitejs/test-dep-a': file:./dep-a
'@vitejs/test-dep-including-a': file:./dep-including-a
terser: ^5.16.1
- vue: ^3.2.45
- vue-router: ^4.1.6
- dependencies:
- vue: 3.2.45
- vue-router: 4.1.6_vue@3.2.45
devDependencies:
- '@vitejs/plugin-vue': 4.0.0_vue@3.2.45
'@vitejs/test-dep-a': file:playground/preload/dep-a
'@vitejs/test-dep-including-a': file:playground/preload/dep-including-a
terser: 5.16.1
@@ -878,6 +868,7 @@ importers:
'@vitejs/test-forwarded-export': file:./forwarded-export
'@vitejs/test-import-builtin-cjs': file:./import-builtin-cjs
'@vitejs/test-linked-no-external': link:./linked-no-external
+ '@vitejs/test-module-condition': file:./module-condition
'@vitejs/test-no-external-cjs': file:./no-external-cjs
'@vitejs/test-no-external-css': file:./no-external-css
'@vitejs/test-non-optimized-with-nested-external': file:./non-optimized-with-nested-external
@@ -901,6 +892,7 @@ importers:
'@vitejs/test-forwarded-export': file:playground/ssr-deps/forwarded-export
'@vitejs/test-import-builtin-cjs': file:playground/ssr-deps/import-builtin-cjs
'@vitejs/test-linked-no-external': link:linked-no-external
+ '@vitejs/test-module-condition': file:playground/ssr-deps/module-condition
'@vitejs/test-no-external-cjs': file:playground/ssr-deps/no-external-cjs
'@vitejs/test-no-external-css': file:playground/ssr-deps/no-external-css
'@vitejs/test-non-optimized-with-nested-external': file:playground/ssr-deps/non-optimized-with-nested-external
@@ -947,6 +939,9 @@ importers:
playground/ssr-deps/linked-no-external:
specifiers: {}
+ playground/ssr-deps/module-condition:
+ specifiers: {}
+
playground/ssr-deps/nested-external:
specifiers: {}
@@ -8752,6 +8747,12 @@ packages:
version: 0.0.0
dev: false
+ file:playground/ssr-deps/module-condition:
+ resolution: {directory: playground/ssr-deps/module-condition, type: directory}
+ name: '@vitejs/test-module-condition'
+ version: 0.0.0
+ dev: false
+
file:playground/ssr-deps/nested-external:
resolution: {directory: playground/ssr-deps/nested-external, type: directory}
name: '@vitejs/test-nested-external'