- Learn Preact
+
+ Vite + Preact
+
+
setCount((count) => count + 1)}>
+ count is {count}
+
+
+ Edit src/app.tsx
and save to test HMR
+
+
+
+ Click on the Vite and Preact logos to learn more
>
)
diff --git a/packages/create-vite/template-preact-ts/src/assets/preact.svg b/packages/create-vite/template-preact-ts/src/assets/preact.svg
new file mode 100644
index 00000000000000..908f17def0b5a4
--- /dev/null
+++ b/packages/create-vite/template-preact-ts/src/assets/preact.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-preact-ts/src/favicon.svg b/packages/create-vite/template-preact-ts/src/favicon.svg
deleted file mode 100644
index de4aeddc12bdfe..00000000000000
--- a/packages/create-vite/template-preact-ts/src/favicon.svg
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/create-vite/template-preact-ts/src/index.css b/packages/create-vite/template-preact-ts/src/index.css
index 3d36f1648343ec..917888c1d1115a 100644
--- a/packages/create-vite/template-preact-ts/src/index.css
+++ b/packages/create-vite/template-preact-ts/src/index.css
@@ -1,30 +1,70 @@
-html,
-body {
- height: 100%;
- width: 100%;
- padding: 0;
- margin: 0;
- background: #fafafa;
- font-family: 'Helvetica Neue', arial, sans-serif;
+:root {
+ font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
+ font-size: 16px;
+ line-height: 24px;
font-weight: 400;
- color: #444;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
+ -webkit-text-size-adjust: 100%;
}
-* {
- box-sizing: border-box;
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
}
-#app {
- height: 100%;
- text-align: center;
- background-color: #673ab8;
- color: #fff;
- font-size: 1.5em;
- padding-top: 100px;
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
+button {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+button:hover {
+ border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
}
-.link {
- color: #fff;
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
}
diff --git a/packages/create-vite/template-preact-ts/src/logo.tsx b/packages/create-vite/template-preact-ts/src/logo.tsx
deleted file mode 100644
index dee6f347a90a54..00000000000000
--- a/packages/create-vite/template-preact-ts/src/logo.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-export const Logo = () => (
-
-
-
-
-
-
-
-)
diff --git a/packages/create-vite/template-preact-ts/src/main.tsx b/packages/create-vite/template-preact-ts/src/main.tsx
index 812f602e33bc95..e0ce3e9980eecd 100644
--- a/packages/create-vite/template-preact-ts/src/main.tsx
+++ b/packages/create-vite/template-preact-ts/src/main.tsx
@@ -2,4 +2,4 @@ import { render } from 'preact'
import { App } from './app'
import './index.css'
-render( , document.getElementById('app')!)
+render( , document.getElementById('app') as HTMLElement)
diff --git a/packages/create-vite/template-preact/index.html b/packages/create-vite/template-preact/index.html
index c06e9fce67a28f..9f89c1bcc0ddef 100644
--- a/packages/create-vite/template-preact/index.html
+++ b/packages/create-vite/template-preact/index.html
@@ -2,9 +2,9 @@
-
+
- Vite App
+ Vite + Preact
diff --git a/packages/create-vite/template-preact/package.json b/packages/create-vite/template-preact/package.json
index 438307a4c75b61..327f2d0e1dcaa4 100644
--- a/packages/create-vite/template-preact/package.json
+++ b/packages/create-vite/template-preact/package.json
@@ -9,10 +9,10 @@
"preview": "vite preview"
},
"dependencies": {
- "preact": "^10.7.2"
+ "preact": "^10.7.3"
},
"devDependencies": {
"@preact/preset-vite": "^2.2.0",
- "vite": "^2.9.9"
+ "vite": "^2.9.12"
}
}
diff --git a/packages/create-vite/template-preact/public/vite.svg b/packages/create-vite/template-preact/public/vite.svg
new file mode 100644
index 00000000000000..e7b8dfb1b2a60b
--- /dev/null
+++ b/packages/create-vite/template-preact/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-preact/src/app.css b/packages/create-vite/template-preact/src/app.css
new file mode 100644
index 00000000000000..088ed3ace55196
--- /dev/null
+++ b/packages/create-vite/template-preact/src/app.css
@@ -0,0 +1,25 @@
+#app {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
+ text-align: center;
+}
+
+.logo {
+ height: 6em;
+ padding: 1.5em;
+}
+.logo:hover {
+ filter: drop-shadow(0 0 2em #646cffaa);
+}
+.logo.preact:hover {
+ filter: drop-shadow(0 0 2em #673ab8aa);
+}
+
+.card {
+ padding: 2em;
+}
+
+.read-the-docs {
+ color: #888;
+}
diff --git a/packages/create-vite/template-preact/src/app.jsx b/packages/create-vite/template-preact/src/app.jsx
index 64fe3eda94c933..717cc480198df8 100644
--- a/packages/create-vite/template-preact/src/app.jsx
+++ b/packages/create-vite/template-preact/src/app.jsx
@@ -1,19 +1,32 @@
-import { Logo } from './logo'
+import { useState } from 'preact/hooks'
+import viteLogo from '/vite.svg'
+import preactLogo from './assets/preact.svg'
+import './app.css'
export function App() {
+ const [count, setCount] = useState(0)
+
return (
<>
-
- Hello Vite + Preact!
-
-
- Learn Preact
+
+ Vite + Preact
+
+
setCount((count) => count + 1)}>
+ count is {count}
+
+
+ Edit src/app.jsx
and save to test HMR
+
+
+
+ Click on the Vite and Preact logos to learn more
>
)
diff --git a/packages/create-vite/template-preact/src/assets/preact.svg b/packages/create-vite/template-preact/src/assets/preact.svg
new file mode 100644
index 00000000000000..908f17def0b5a4
--- /dev/null
+++ b/packages/create-vite/template-preact/src/assets/preact.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-preact/src/favicon.svg b/packages/create-vite/template-preact/src/favicon.svg
deleted file mode 100644
index de4aeddc12bdfe..00000000000000
--- a/packages/create-vite/template-preact/src/favicon.svg
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/create-vite/template-preact/src/index.css b/packages/create-vite/template-preact/src/index.css
index 3d36f1648343ec..917888c1d1115a 100644
--- a/packages/create-vite/template-preact/src/index.css
+++ b/packages/create-vite/template-preact/src/index.css
@@ -1,30 +1,70 @@
-html,
-body {
- height: 100%;
- width: 100%;
- padding: 0;
- margin: 0;
- background: #fafafa;
- font-family: 'Helvetica Neue', arial, sans-serif;
+:root {
+ font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
+ font-size: 16px;
+ line-height: 24px;
font-weight: 400;
- color: #444;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
+ -webkit-text-size-adjust: 100%;
}
-* {
- box-sizing: border-box;
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
}
-#app {
- height: 100%;
- text-align: center;
- background-color: #673ab8;
- color: #fff;
- font-size: 1.5em;
- padding-top: 100px;
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
+button {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+button:hover {
+ border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
}
-.link {
- color: #fff;
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
}
diff --git a/packages/create-vite/template-preact/src/logo.jsx b/packages/create-vite/template-preact/src/logo.jsx
deleted file mode 100644
index dee6f347a90a54..00000000000000
--- a/packages/create-vite/template-preact/src/logo.jsx
+++ /dev/null
@@ -1,47 +0,0 @@
-export const Logo = () => (
-
-
-
-
-
-
-
-)
diff --git a/packages/create-vite/template-react-ts/index.html b/packages/create-vite/template-react-ts/index.html
index 38f386110323c3..e0d1c840806ee7 100644
--- a/packages/create-vite/template-react-ts/index.html
+++ b/packages/create-vite/template-react-ts/index.html
@@ -2,9 +2,9 @@
-
+
- Vite App
+ Vite + React + TS
diff --git a/packages/create-vite/template-react-ts/package.json b/packages/create-vite/template-react-ts/package.json
index 7e91f9c6589b16..ce427c4eb447a5 100644
--- a/packages/create-vite/template-react-ts/package.json
+++ b/packages/create-vite/template-react-ts/package.json
@@ -13,10 +13,10 @@
"react-dom": "^18.1.0"
},
"devDependencies": {
- "@types/react": "^18.0.9",
+ "@types/react": "^18.0.12",
"@types/react-dom": "^18.0.5",
"@vitejs/plugin-react": "^1.3.2",
"typescript": "^4.6.4",
- "vite": "^2.9.9"
+ "vite": "^2.9.12"
}
}
diff --git a/packages/create-vite/template-react-ts/public/vite.svg b/packages/create-vite/template-react-ts/public/vite.svg
new file mode 100644
index 00000000000000..e7b8dfb1b2a60b
--- /dev/null
+++ b/packages/create-vite/template-react-ts/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-react-ts/src/App.css b/packages/create-vite/template-react-ts/src/App.css
index 8da3fde63d9e7d..2c5e2ef5cd1a2e 100644
--- a/packages/create-vite/template-react-ts/src/App.css
+++ b/packages/create-vite/template-react-ts/src/App.css
@@ -1,34 +1,23 @@
-.App {
+#root {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
text-align: center;
}
-.App-logo {
- height: 40vmin;
- pointer-events: none;
+.logo {
+ height: 6em;
+ padding: 1.5em;
+ will-change: filter;
}
-
-@media (prefers-reduced-motion: no-preference) {
- .App-logo {
- animation: App-logo-spin infinite 20s linear;
- }
+.logo:hover {
+ filter: drop-shadow(0 0 2em #646cffaa);
}
-
-.App-header {
- background-color: #282c34;
- min-height: 100vh;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- font-size: calc(10px + 2vmin);
- color: white;
-}
-
-.App-link {
- color: #61dafb;
+.logo.react:hover {
+ filter: drop-shadow(0 0 2em #61dafbaa);
}
-@keyframes App-logo-spin {
+@keyframes logo-spin {
from {
transform: rotate(0deg);
}
@@ -37,6 +26,16 @@
}
}
-button {
- font-size: calc(10px + 2vmin);
+@media (prefers-reduced-motion: no-preference) {
+ a:nth-of-type(2) .logo {
+ animation: logo-spin infinite 20s linear;
+ }
+}
+
+.card {
+ padding: 2em;
+}
+
+.read-the-docs {
+ color: #888;
}
diff --git a/packages/create-vite/template-react-ts/src/App.tsx b/packages/create-vite/template-react-ts/src/App.tsx
index 3d9bd71e51303e..dfe8ceddf40982 100644
--- a/packages/create-vite/template-react-ts/src/App.tsx
+++ b/packages/create-vite/template-react-ts/src/App.tsx
@@ -1,5 +1,6 @@
import { useState } from 'react'
-import logo from './logo.svg'
+import viteLogo from '/vite.svg'
+import reactLogo from './assets/react.svg'
import './App.css'
function App() {
@@ -7,37 +8,26 @@ function App() {
return (
-
-
- Hello Vite + React!
+
+ Vite + React
+
+
setCount((count) => count + 1)}>
+ count is {count}
+
- setCount((count) => count + 1)}>
- count is: {count}
-
+ Edit src/App.tsx
and save to test HMR
-
- Edit App.tsx
and save to test HMR updates.
-
-
-
- Learn React
-
- {' | '}
-
- Vite Docs
-
-
-
+
+
+ Click on the Vite and React logos to learn more
+
)
}
diff --git a/packages/create-vite/template-react-ts/src/assets/react.svg b/packages/create-vite/template-react-ts/src/assets/react.svg
new file mode 100644
index 00000000000000..6c87de9bb33584
--- /dev/null
+++ b/packages/create-vite/template-react-ts/src/assets/react.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-react-ts/src/favicon.svg b/packages/create-vite/template-react-ts/src/favicon.svg
deleted file mode 100644
index de4aeddc12bdfe..00000000000000
--- a/packages/create-vite/template-react-ts/src/favicon.svg
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/create-vite/template-react-ts/src/index.css b/packages/create-vite/template-react-ts/src/index.css
index ec2585e8c0bb81..917888c1d1115a 100644
--- a/packages/create-vite/template-react-ts/src/index.css
+++ b/packages/create-vite/template-react-ts/src/index.css
@@ -1,13 +1,70 @@
-body {
- margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
- 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
- sans-serif;
+:root {
+ font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
+ font-size: 16px;
+ line-height: 24px;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
+ -webkit-text-size-adjust: 100%;
+}
+
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
+}
+
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
+button {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+button:hover {
+ border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
}
-code {
- font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
- monospace;
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
}
diff --git a/packages/create-vite/template-react-ts/src/logo.svg b/packages/create-vite/template-react-ts/src/logo.svg
deleted file mode 100644
index 6b60c1042f58d9..00000000000000
--- a/packages/create-vite/template-react-ts/src/logo.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/packages/create-vite/template-react/index.html b/packages/create-vite/template-react/index.html
index b46ab83364e374..79c470191164e9 100644
--- a/packages/create-vite/template-react/index.html
+++ b/packages/create-vite/template-react/index.html
@@ -2,9 +2,9 @@
-
+
- Vite App
+ Vite + React
diff --git a/packages/create-vite/template-react/package.json b/packages/create-vite/template-react/package.json
index b79e9889800e06..e49194201425da 100644
--- a/packages/create-vite/template-react/package.json
+++ b/packages/create-vite/template-react/package.json
@@ -13,9 +13,9 @@
"react-dom": "^18.1.0"
},
"devDependencies": {
- "@types/react": "^18.0.9",
+ "@types/react": "^18.0.12",
"@types/react-dom": "^18.0.5",
"@vitejs/plugin-react": "^1.3.2",
- "vite": "^2.9.9"
+ "vite": "^2.9.12"
}
}
diff --git a/packages/create-vite/template-react/public/vite.svg b/packages/create-vite/template-react/public/vite.svg
new file mode 100644
index 00000000000000..e7b8dfb1b2a60b
--- /dev/null
+++ b/packages/create-vite/template-react/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-react/src/App.css b/packages/create-vite/template-react/src/App.css
index 8da3fde63d9e7d..2c5e2ef5cd1a2e 100644
--- a/packages/create-vite/template-react/src/App.css
+++ b/packages/create-vite/template-react/src/App.css
@@ -1,34 +1,23 @@
-.App {
+#root {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
text-align: center;
}
-.App-logo {
- height: 40vmin;
- pointer-events: none;
+.logo {
+ height: 6em;
+ padding: 1.5em;
+ will-change: filter;
}
-
-@media (prefers-reduced-motion: no-preference) {
- .App-logo {
- animation: App-logo-spin infinite 20s linear;
- }
+.logo:hover {
+ filter: drop-shadow(0 0 2em #646cffaa);
}
-
-.App-header {
- background-color: #282c34;
- min-height: 100vh;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- font-size: calc(10px + 2vmin);
- color: white;
-}
-
-.App-link {
- color: #61dafb;
+.logo.react:hover {
+ filter: drop-shadow(0 0 2em #61dafbaa);
}
-@keyframes App-logo-spin {
+@keyframes logo-spin {
from {
transform: rotate(0deg);
}
@@ -37,6 +26,16 @@
}
}
-button {
- font-size: calc(10px + 2vmin);
+@media (prefers-reduced-motion: no-preference) {
+ a:nth-of-type(2) .logo {
+ animation: logo-spin infinite 20s linear;
+ }
+}
+
+.card {
+ padding: 2em;
+}
+
+.read-the-docs {
+ color: #888;
}
diff --git a/packages/create-vite/template-react/src/App.jsx b/packages/create-vite/template-react/src/App.jsx
index 7d4eb10ff833d1..14be1971f75675 100644
--- a/packages/create-vite/template-react/src/App.jsx
+++ b/packages/create-vite/template-react/src/App.jsx
@@ -1,5 +1,6 @@
import { useState } from 'react'
-import logo from './logo.svg'
+import viteLogo from '/vite.svg'
+import reactLogo from './assets/react.svg'
import './App.css'
function App() {
@@ -7,37 +8,26 @@ function App() {
return (
-
-
- Hello Vite + React!
+
+ Vite + React
+
+
setCount((count) => count + 1)}>
+ count is {count}
+
- setCount((count) => count + 1)}>
- count is: {count}
-
+ Edit src/App.jsx
and save to test HMR
-
- Edit App.jsx
and save to test HMR updates.
-
-
-
- Learn React
-
- {' | '}
-
- Vite Docs
-
-
-
+
+
+ Click on the Vite and React logos to learn more
+
)
}
diff --git a/packages/create-vite/template-react/src/assets/react.svg b/packages/create-vite/template-react/src/assets/react.svg
new file mode 100644
index 00000000000000..6c87de9bb33584
--- /dev/null
+++ b/packages/create-vite/template-react/src/assets/react.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-react/src/favicon.svg b/packages/create-vite/template-react/src/favicon.svg
deleted file mode 100644
index de4aeddc12bdfe..00000000000000
--- a/packages/create-vite/template-react/src/favicon.svg
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/create-vite/template-react/src/index.css b/packages/create-vite/template-react/src/index.css
index ec2585e8c0bb81..917888c1d1115a 100644
--- a/packages/create-vite/template-react/src/index.css
+++ b/packages/create-vite/template-react/src/index.css
@@ -1,13 +1,70 @@
-body {
- margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
- 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
- sans-serif;
+:root {
+ font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
+ font-size: 16px;
+ line-height: 24px;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
+ -webkit-text-size-adjust: 100%;
+}
+
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
+}
+
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
+button {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+button:hover {
+ border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
}
-code {
- font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
- monospace;
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
}
diff --git a/packages/create-vite/template-react/src/logo.svg b/packages/create-vite/template-react/src/logo.svg
deleted file mode 100644
index 6b60c1042f58d9..00000000000000
--- a/packages/create-vite/template-react/src/logo.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/packages/create-vite/template-svelte-ts/index.html b/packages/create-vite/template-svelte-ts/index.html
index d2f6839bab176c..b5b125269662aa 100644
--- a/packages/create-vite/template-svelte-ts/index.html
+++ b/packages/create-vite/template-svelte-ts/index.html
@@ -2,9 +2,9 @@
-
+
- Svelte + TS + Vite App
+ Vite + Svelte + TS
diff --git a/packages/create-vite/template-svelte-ts/package.json b/packages/create-vite/template-svelte-ts/package.json
index 53a4c5ea8e01a0..35754a8efcd2e1 100644
--- a/packages/create-vite/template-svelte-ts/package.json
+++ b/packages/create-vite/template-svelte-ts/package.json
@@ -10,13 +10,13 @@
"check": "svelte-check --tsconfig ./tsconfig.json"
},
"devDependencies": {
- "@sveltejs/vite-plugin-svelte": "^1.0.0-next.46",
+ "@sveltejs/vite-plugin-svelte": "^1.0.0-next.49",
"@tsconfig/svelte": "^3.0.0",
"svelte": "^3.48.0",
- "svelte-check": "^2.7.1",
- "svelte-preprocess": "^4.10.6",
+ "svelte-check": "^2.7.2",
+ "svelte-preprocess": "^4.10.7",
"tslib": "^2.4.0",
"typescript": "^4.6.4",
- "vite": "^2.9.9"
+ "vite": "^2.9.12"
}
}
diff --git a/packages/create-vite/template-svelte-ts/public/favicon.ico b/packages/create-vite/template-svelte-ts/public/favicon.ico
deleted file mode 100644
index d75d248ef0b150..00000000000000
Binary files a/packages/create-vite/template-svelte-ts/public/favicon.ico and /dev/null differ
diff --git a/packages/create-vite/template-svelte-ts/public/vite.svg b/packages/create-vite/template-svelte-ts/public/vite.svg
new file mode 100644
index 00000000000000..e7b8dfb1b2a60b
--- /dev/null
+++ b/packages/create-vite/template-svelte-ts/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-svelte-ts/src/App.svelte b/packages/create-vite/template-svelte-ts/src/App.svelte
index 4023b8b9774246..480e1d072d5a2e 100644
--- a/packages/create-vite/template-svelte-ts/src/App.svelte
+++ b/packages/create-vite/template-svelte-ts/src/App.svelte
@@ -1,65 +1,46 @@
-
- Hello Typescript!
-
-
+
+ Vite + Svelte
+
+
+
+
- Visit svelte.dev to learn how to build Svelte
- apps.
+ Check out SvelteKit , the official Svelte app framework powered by Vite!
-
- Check out SvelteKit for
- the officially supported framework, also powered by Vite!
+
+ Click on the Vite and Svelte logos to learn more
+
\ No newline at end of file
diff --git a/packages/create-vite/template-svelte-ts/src/app.css b/packages/create-vite/template-svelte-ts/src/app.css
new file mode 100644
index 00000000000000..bcc7233dd1ca85
--- /dev/null
+++ b/packages/create-vite/template-svelte-ts/src/app.css
@@ -0,0 +1,81 @@
+:root {
+ font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
+ font-size: 16px;
+ line-height: 24px;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-text-size-adjust: 100%;
+}
+
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
+}
+
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
+.card {
+ padding: 2em;
+}
+
+#app {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
+ text-align: center;
+}
+
+button {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+button:hover {
+ border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
+}
+
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
+}
diff --git a/packages/create-vite/template-svelte-ts/src/assets/svelte.png b/packages/create-vite/template-svelte-ts/src/assets/svelte.png
deleted file mode 100644
index e673c91c7bcb0e..00000000000000
Binary files a/packages/create-vite/template-svelte-ts/src/assets/svelte.png and /dev/null differ
diff --git a/packages/create-vite/template-svelte-ts/src/assets/svelte.svg b/packages/create-vite/template-svelte-ts/src/assets/svelte.svg
new file mode 100644
index 00000000000000..c5e08481f8aede
--- /dev/null
+++ b/packages/create-vite/template-svelte-ts/src/assets/svelte.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-svelte-ts/src/lib/Counter.svelte b/packages/create-vite/template-svelte-ts/src/lib/Counter.svelte
index b8e7524c2232aa..979b4dfc91c86e 100644
--- a/packages/create-vite/template-svelte-ts/src/lib/Counter.svelte
+++ b/packages/create-vite/template-svelte-ts/src/lib/Counter.svelte
@@ -6,29 +6,5 @@
- Clicks: {count}
+ count is {count}
-
-
diff --git a/packages/create-vite/template-svelte-ts/src/main.ts b/packages/create-vite/template-svelte-ts/src/main.ts
index d8200ac4fe3078..5c1f795f9f55a6 100644
--- a/packages/create-vite/template-svelte-ts/src/main.ts
+++ b/packages/create-vite/template-svelte-ts/src/main.ts
@@ -1,3 +1,4 @@
+import './app.css'
import App from './App.svelte'
const app = new App({
diff --git a/packages/create-vite/template-svelte/index.html b/packages/create-vite/template-svelte/index.html
index 4a3886b62cf793..26c29c45b2689e 100644
--- a/packages/create-vite/template-svelte/index.html
+++ b/packages/create-vite/template-svelte/index.html
@@ -2,9 +2,9 @@
-
+
- Svelte + Vite App
+ Vite + Svelte
diff --git a/packages/create-vite/template-svelte/package.json b/packages/create-vite/template-svelte/package.json
index 5d469f55d796b9..7b4bb4e615b5a7 100644
--- a/packages/create-vite/template-svelte/package.json
+++ b/packages/create-vite/template-svelte/package.json
@@ -9,8 +9,8 @@
"preview": "vite preview"
},
"devDependencies": {
- "@sveltejs/vite-plugin-svelte": "^1.0.0-next.46",
+ "@sveltejs/vite-plugin-svelte": "^1.0.0-next.49",
"svelte": "^3.48.0",
- "vite": "^2.9.9"
+ "vite": "^2.9.12"
}
}
diff --git a/packages/create-vite/template-svelte/public/favicon.ico b/packages/create-vite/template-svelte/public/favicon.ico
deleted file mode 100644
index d75d248ef0b150..00000000000000
Binary files a/packages/create-vite/template-svelte/public/favicon.ico and /dev/null differ
diff --git a/packages/create-vite/template-svelte/public/vite.svg b/packages/create-vite/template-svelte/public/vite.svg
new file mode 100644
index 00000000000000..e7b8dfb1b2a60b
--- /dev/null
+++ b/packages/create-vite/template-svelte/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-svelte/src/App.svelte b/packages/create-vite/template-svelte/src/App.svelte
index 90ca0665a7416a..b2eb01b52ac2de 100644
--- a/packages/create-vite/template-svelte/src/App.svelte
+++ b/packages/create-vite/template-svelte/src/App.svelte
@@ -1,65 +1,46 @@
-
- Hello world!
-
-
+
+ Vite + Svelte
+
+
+
+
- Visit svelte.dev to learn how to build Svelte
- apps.
+ Check out SvelteKit , the official Svelte app framework powered by Vite!
-
- Check out SvelteKit for
- the officially supported framework, also powered by Vite!
+
+ Click on the Vite and Svelte logos to learn more
diff --git a/packages/create-vite/template-svelte/src/app.css b/packages/create-vite/template-svelte/src/app.css
new file mode 100644
index 00000000000000..bcc7233dd1ca85
--- /dev/null
+++ b/packages/create-vite/template-svelte/src/app.css
@@ -0,0 +1,81 @@
+:root {
+ font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
+ font-size: 16px;
+ line-height: 24px;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-text-size-adjust: 100%;
+}
+
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
+}
+
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
+.card {
+ padding: 2em;
+}
+
+#app {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
+ text-align: center;
+}
+
+button {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+button:hover {
+ border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
+}
+
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
+}
diff --git a/packages/create-vite/template-svelte/src/assets/svelte.png b/packages/create-vite/template-svelte/src/assets/svelte.png
deleted file mode 100644
index e673c91c7bcb0e..00000000000000
Binary files a/packages/create-vite/template-svelte/src/assets/svelte.png and /dev/null differ
diff --git a/packages/create-vite/template-svelte/src/assets/svelte.svg b/packages/create-vite/template-svelte/src/assets/svelte.svg
new file mode 100644
index 00000000000000..c5e08481f8aede
--- /dev/null
+++ b/packages/create-vite/template-svelte/src/assets/svelte.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-svelte/src/lib/Counter.svelte b/packages/create-vite/template-svelte/src/lib/Counter.svelte
index 37a92cbf4bbd10..e45f903109790d 100644
--- a/packages/create-vite/template-svelte/src/lib/Counter.svelte
+++ b/packages/create-vite/template-svelte/src/lib/Counter.svelte
@@ -6,29 +6,5 @@
- Clicks: {count}
+ count is {count}
-
-
diff --git a/packages/create-vite/template-svelte/src/main.js b/packages/create-vite/template-svelte/src/main.js
index d8200ac4fe3078..5c1f795f9f55a6 100644
--- a/packages/create-vite/template-svelte/src/main.js
+++ b/packages/create-vite/template-svelte/src/main.js
@@ -1,3 +1,4 @@
+import './app.css'
import App from './App.svelte'
const app = new App({
diff --git a/packages/create-vite/template-vanilla-ts/index.html b/packages/create-vite/template-vanilla-ts/index.html
index 867581c5124fa1..f86e483c942e8d 100644
--- a/packages/create-vite/template-vanilla-ts/index.html
+++ b/packages/create-vite/template-vanilla-ts/index.html
@@ -2,9 +2,9 @@
-
+
- Vite App
+ Vite + TS
diff --git a/packages/create-vite/template-vanilla-ts/package.json b/packages/create-vite/template-vanilla-ts/package.json
index ff74d1a70ac3aa..d1df1e67eeb8b6 100644
--- a/packages/create-vite/template-vanilla-ts/package.json
+++ b/packages/create-vite/template-vanilla-ts/package.json
@@ -10,6 +10,6 @@
},
"devDependencies": {
"typescript": "^4.6.4",
- "vite": "^2.9.9"
+ "vite": "^2.9.12"
}
}
diff --git a/packages/create-vite/template-vanilla-ts/public/vite.svg b/packages/create-vite/template-vanilla-ts/public/vite.svg
new file mode 100644
index 00000000000000..e7b8dfb1b2a60b
--- /dev/null
+++ b/packages/create-vite/template-vanilla-ts/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-vanilla-ts/src/counter.ts b/packages/create-vite/template-vanilla-ts/src/counter.ts
new file mode 100644
index 00000000000000..a3529e1f26bfc8
--- /dev/null
+++ b/packages/create-vite/template-vanilla-ts/src/counter.ts
@@ -0,0 +1,9 @@
+export function setupCounter(element: HTMLButtonElement) {
+ let counter = 0
+ const setCounter = (count: number) => {
+ counter = count
+ element.innerHTML = `count is ${counter}`
+ }
+ element.addEventListener('click', () => setCounter(++counter))
+ setCounter(0)
+}
diff --git a/packages/create-vite/template-vanilla-ts/src/main.ts b/packages/create-vite/template-vanilla-ts/src/main.ts
index f77db7a8fcab13..b4a91405cdee25 100644
--- a/packages/create-vite/template-vanilla-ts/src/main.ts
+++ b/packages/create-vite/template-vanilla-ts/src/main.ts
@@ -1,8 +1,24 @@
import './style.css'
+import viteLogo from '/vite.svg'
+import typescriptLogo from './typescript.svg'
+import { setupCounter } from './counter'
-const app = document.querySelector('#app')!
-
-app.innerHTML = `
- Hello Vite!
- Documentation
+document.querySelector('#app')!.innerHTML = `
+
+
+
+
+
+
+
+
Vite + TypeScript
+
+
+
+
+ Click on the Vite and TypeScript logos to learn more
+
+
`
+
+setupCounter(document.querySelector('#counter')!)
diff --git a/packages/create-vite/template-vanilla-ts/src/style.css b/packages/create-vite/template-vanilla-ts/src/style.css
index 852de7aa2ae573..12320801d3635d 100644
--- a/packages/create-vite/template-vanilla-ts/src/style.css
+++ b/packages/create-vite/template-vanilla-ts/src/style.css
@@ -1,8 +1,97 @@
-#app {
- font-family: Avenir, Helvetica, Arial, sans-serif;
+:root {
+ font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
+ font-size: 16px;
+ line-height: 24px;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
+ -webkit-text-size-adjust: 100%;
+}
+
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
+}
+
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
+#app {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
text-align: center;
- color: #2c3e50;
- margin-top: 60px;
+}
+
+.logo {
+ height: 6em;
+ padding: 1.5em;
+ will-change: filter;
+}
+.logo:hover {
+ filter: drop-shadow(0 0 2em #646cffaa);
+}
+.logo.vanilla:hover {
+ filter: drop-shadow(0 0 2em #f7df1eaa);
+}
+
+.card {
+ padding: 2em;
+}
+
+.read-the-docs {
+ color: #888;
+}
+
+button {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+button:hover {
+ border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
+}
+
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
}
diff --git a/packages/create-vite/template-vanilla-ts/src/typescript.svg b/packages/create-vite/template-vanilla-ts/src/typescript.svg
new file mode 100644
index 00000000000000..d91c910cc30bf4
--- /dev/null
+++ b/packages/create-vite/template-vanilla-ts/src/typescript.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-vanilla/counter.js b/packages/create-vite/template-vanilla/counter.js
new file mode 100644
index 00000000000000..12ae65abfaea09
--- /dev/null
+++ b/packages/create-vite/template-vanilla/counter.js
@@ -0,0 +1,9 @@
+export function setupCounter(element) {
+ let counter = 0
+ const setCounter = (count) => {
+ counter = count
+ element.innerHTML = `count is ${counter}`
+ }
+ element.addEventListener('click', () => setCounter(++counter))
+ setCounter(0)
+}
diff --git a/packages/create-vite/template-vanilla/favicon.svg b/packages/create-vite/template-vanilla/favicon.svg
deleted file mode 100644
index de4aeddc12bdfe..00000000000000
--- a/packages/create-vite/template-vanilla/favicon.svg
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/create-vite/template-vanilla/index.html b/packages/create-vite/template-vanilla/index.html
index f1dedb52dba233..2ad7b1ab9e691d 100644
--- a/packages/create-vite/template-vanilla/index.html
+++ b/packages/create-vite/template-vanilla/index.html
@@ -2,7 +2,7 @@
-
+
Vite App
diff --git a/packages/create-vite/template-vanilla/javascript.svg b/packages/create-vite/template-vanilla/javascript.svg
new file mode 100644
index 00000000000000..f9abb2b728d73b
--- /dev/null
+++ b/packages/create-vite/template-vanilla/javascript.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-vanilla/main.js b/packages/create-vite/template-vanilla/main.js
index 4c0070f03c7ba0..bbdb9004d5f3d8 100644
--- a/packages/create-vite/template-vanilla/main.js
+++ b/packages/create-vite/template-vanilla/main.js
@@ -1,6 +1,24 @@
import './style.css'
+import viteLogo from '/vite.svg'
+import javascriptLogo from './javascript.svg'
+import { setupCounter } from './counter.js'
document.querySelector('#app').innerHTML = `
- Hello Vite!
- Documentation
+
+
+
+
+
+
+
+
Hello Vite!
+
+
+
+
+ Click on the Vite logo to learn more
+
+
`
+
+setupCounter(document.querySelector('#counter'))
diff --git a/packages/create-vite/template-vanilla/package.json b/packages/create-vite/template-vanilla/package.json
index 470ae1e4770149..52837e6d7c0ecc 100644
--- a/packages/create-vite/template-vanilla/package.json
+++ b/packages/create-vite/template-vanilla/package.json
@@ -9,6 +9,6 @@
"preview": "vite preview"
},
"devDependencies": {
- "vite": "^2.9.9"
+ "vite": "^2.9.12"
}
}
diff --git a/packages/create-vite/template-vanilla/public/vite.svg b/packages/create-vite/template-vanilla/public/vite.svg
new file mode 100644
index 00000000000000..e7b8dfb1b2a60b
--- /dev/null
+++ b/packages/create-vite/template-vanilla/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-vanilla/style.css b/packages/create-vite/template-vanilla/style.css
index 852de7aa2ae573..12320801d3635d 100644
--- a/packages/create-vite/template-vanilla/style.css
+++ b/packages/create-vite/template-vanilla/style.css
@@ -1,8 +1,97 @@
-#app {
- font-family: Avenir, Helvetica, Arial, sans-serif;
+:root {
+ font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
+ font-size: 16px;
+ line-height: 24px;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
+ -webkit-text-size-adjust: 100%;
+}
+
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
+}
+
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
+#app {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
text-align: center;
- color: #2c3e50;
- margin-top: 60px;
+}
+
+.logo {
+ height: 6em;
+ padding: 1.5em;
+ will-change: filter;
+}
+.logo:hover {
+ filter: drop-shadow(0 0 2em #646cffaa);
+}
+.logo.vanilla:hover {
+ filter: drop-shadow(0 0 2em #f7df1eaa);
+}
+
+.card {
+ padding: 2em;
+}
+
+.read-the-docs {
+ color: #888;
+}
+
+button {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+button:hover {
+ border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
+}
+
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
}
diff --git a/packages/create-vite/template-vue-ts/index.html b/packages/create-vite/template-vue-ts/index.html
index 11603f878f1226..143557b5286bc1 100644
--- a/packages/create-vite/template-vue-ts/index.html
+++ b/packages/create-vite/template-vue-ts/index.html
@@ -2,9 +2,9 @@
-
+
- Vite App
+ Vite + Vue + TS
diff --git a/packages/create-vite/template-vue-ts/package.json b/packages/create-vite/template-vue-ts/package.json
index 5f352e2519aa25..208f8126f74c7a 100644
--- a/packages/create-vite/template-vue-ts/package.json
+++ b/packages/create-vite/template-vue-ts/package.json
@@ -9,12 +9,12 @@
"preview": "vite preview"
},
"dependencies": {
- "vue": "^3.2.36"
+ "vue": "^3.2.37"
},
"devDependencies": {
"@vitejs/plugin-vue": "^2.3.3",
"typescript": "^4.6.4",
- "vite": "^2.9.9",
- "vue-tsc": "^0.35.2"
+ "vite": "^2.9.12",
+ "vue-tsc": "^0.37.5"
}
}
diff --git a/packages/create-vite/template-vue-ts/public/favicon.ico b/packages/create-vite/template-vue-ts/public/favicon.ico
deleted file mode 100644
index df36fcfb72584e..00000000000000
Binary files a/packages/create-vite/template-vue-ts/public/favicon.ico and /dev/null differ
diff --git a/packages/create-vite/template-vue-ts/public/vite.svg b/packages/create-vite/template-vue-ts/public/vite.svg
new file mode 100644
index 00000000000000..e7b8dfb1b2a60b
--- /dev/null
+++ b/packages/create-vite/template-vue-ts/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-vue-ts/src/App.vue b/packages/create-vite/template-vue-ts/src/App.vue
index 1503baf999e683..76ebf08602f448 100644
--- a/packages/create-vite/template-vue-ts/src/App.vue
+++ b/packages/create-vite/template-vue-ts/src/App.vue
@@ -5,17 +5,27 @@ import HelloWorld from './components/HelloWorld.vue'
-
-
+
+
-
diff --git a/packages/create-vite/template-vue-ts/src/assets/logo.png b/packages/create-vite/template-vue-ts/src/assets/logo.png
deleted file mode 100644
index f3d2503fc2a44b..00000000000000
Binary files a/packages/create-vite/template-vue-ts/src/assets/logo.png and /dev/null differ
diff --git a/packages/create-vite/template-vue-ts/src/assets/vue.svg b/packages/create-vite/template-vue-ts/src/assets/vue.svg
new file mode 100644
index 00000000000000..770e9d333ee70e
--- /dev/null
+++ b/packages/create-vite/template-vue-ts/src/assets/vue.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-vue-ts/src/components/HelloWorld.vue b/packages/create-vite/template-vue-ts/src/components/HelloWorld.vue
index 38dae70739a15a..5230910336b442 100644
--- a/packages/create-vite/template-vue-ts/src/components/HelloWorld.vue
+++ b/packages/create-vite/template-vue-ts/src/components/HelloWorld.vue
@@ -9,44 +9,30 @@ const count = ref(0)
{{ msg }}
-
- Recommended IDE setup:
- VS Code
- +
- Volar
-
-
- See README.md
for more information.
+
+
count is {{ count }}
+
+ Edit
+ components/HelloWorld.vue
to test HMR
+
+
-
- Vite Docs
-
- |
- Vue 3 Docs
+ Check out
+ create-vue , the official Vue + Vite starter
-
- count is: {{ count }}
- Edit
- components/HelloWorld.vue
to test hot module replacement.
+ Install
+ Volar
+ in your IDE for a better DX
+ Click on the Vite and Vue logos to learn more
diff --git a/packages/create-vite/template-vue-ts/src/main.ts b/packages/create-vite/template-vue-ts/src/main.ts
index 01433bca2ac765..2425c0f745bef4 100644
--- a/packages/create-vite/template-vue-ts/src/main.ts
+++ b/packages/create-vite/template-vue-ts/src/main.ts
@@ -1,4 +1,5 @@
import { createApp } from 'vue'
+import './style.css'
import App from './App.vue'
createApp(App).mount('#app')
diff --git a/packages/create-vite/template-vue-ts/src/style.css b/packages/create-vite/template-vue-ts/src/style.css
new file mode 100644
index 00000000000000..0192f9aac987dc
--- /dev/null
+++ b/packages/create-vite/template-vue-ts/src/style.css
@@ -0,0 +1,81 @@
+:root {
+ font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
+ font-size: 16px;
+ line-height: 24px;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-text-size-adjust: 100%;
+}
+
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
+}
+
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
+button {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+button:hover {
+ border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
+}
+
+.card {
+ padding: 2em;
+}
+
+#app {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
+ text-align: center;
+}
+
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
+}
diff --git a/packages/create-vite/template-vue/index.html b/packages/create-vite/template-vue/index.html
index 030a6ff51bfc6f..795e4fbadb8831 100644
--- a/packages/create-vite/template-vue/index.html
+++ b/packages/create-vite/template-vue/index.html
@@ -2,9 +2,9 @@
-
+
- Vite App
+ Vite + Vue
diff --git a/packages/create-vite/template-vue/package.json b/packages/create-vite/template-vue/package.json
index c519cb36270f61..f2f7dee1baaf9d 100644
--- a/packages/create-vite/template-vue/package.json
+++ b/packages/create-vite/template-vue/package.json
@@ -9,10 +9,10 @@
"preview": "vite preview"
},
"dependencies": {
- "vue": "^3.2.36"
+ "vue": "^3.2.37"
},
"devDependencies": {
"@vitejs/plugin-vue": "^2.3.3",
- "vite": "^2.9.9"
+ "vite": "^2.9.12"
}
}
diff --git a/packages/create-vite/template-vue/public/favicon.ico b/packages/create-vite/template-vue/public/favicon.ico
deleted file mode 100644
index df36fcfb72584e..00000000000000
Binary files a/packages/create-vite/template-vue/public/favicon.ico and /dev/null differ
diff --git a/packages/create-vite/template-vue/public/vite.svg b/packages/create-vite/template-vue/public/vite.svg
new file mode 100644
index 00000000000000..e7b8dfb1b2a60b
--- /dev/null
+++ b/packages/create-vite/template-vue/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-vue/src/App.vue b/packages/create-vite/template-vue/src/App.vue
index 09bbb6a561285f..6febdb7581ea83 100644
--- a/packages/create-vite/template-vue/src/App.vue
+++ b/packages/create-vite/template-vue/src/App.vue
@@ -5,17 +5,27 @@ import HelloWorld from './components/HelloWorld.vue'
-
-
+
+
-
diff --git a/packages/create-vite/template-vue/src/assets/logo.png b/packages/create-vite/template-vue/src/assets/logo.png
deleted file mode 100644
index f3d2503fc2a44b..00000000000000
Binary files a/packages/create-vite/template-vue/src/assets/logo.png and /dev/null differ
diff --git a/packages/create-vite/template-vue/src/assets/vue.svg b/packages/create-vite/template-vue/src/assets/vue.svg
new file mode 100644
index 00000000000000..770e9d333ee70e
--- /dev/null
+++ b/packages/create-vite/template-vue/src/assets/vue.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/create-vite/template-vue/src/components/HelloWorld.vue b/packages/create-vite/template-vue/src/components/HelloWorld.vue
index aa607e31e0ad7c..91f9bfcbcb305d 100644
--- a/packages/create-vite/template-vue/src/components/HelloWorld.vue
+++ b/packages/create-vite/template-vue/src/components/HelloWorld.vue
@@ -11,30 +11,30 @@ const count = ref(0)
{{ msg }}
-
- Recommended IDE setup:
- VS Code
- +
- Volar
-
+
+
count is {{ count }}
+
+ Edit
+ components/HelloWorld.vue
to test HMR
+
+
-
- Vite Documentation
-
- |
- Vue 3 Documentation
+ Check out
+ create-vue , the official Vue + Vite starter
-
- count is: {{ count }}
- Edit
- components/HelloWorld.vue
to test hot module replacement.
+ Install
+ Volar
+ in your IDE for a better DX
+ Click on the Vite and Vue logos to learn more
diff --git a/packages/create-vite/template-vue/src/main.js b/packages/create-vite/template-vue/src/main.js
index 01433bca2ac765..2425c0f745bef4 100644
--- a/packages/create-vite/template-vue/src/main.js
+++ b/packages/create-vite/template-vue/src/main.js
@@ -1,4 +1,5 @@
import { createApp } from 'vue'
+import './style.css'
import App from './App.vue'
createApp(App).mount('#app')
diff --git a/packages/create-vite/template-vue/src/style.css b/packages/create-vite/template-vue/src/style.css
new file mode 100644
index 00000000000000..a566a347d0d5ee
--- /dev/null
+++ b/packages/create-vite/template-vue/src/style.css
@@ -0,0 +1,90 @@
+:root {
+ font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
+ font-size: 16px;
+ line-height: 24px;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-text-size-adjust: 100%;
+}
+
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
+}
+
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
+}
+
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
+button {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+button:hover {
+ border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
+}
+
+.card {
+ padding: 2em;
+}
+
+#app {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
+ text-align: center;
+}
+
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
+}
diff --git a/packages/plugin-legacy/README.md b/packages/plugin-legacy/README.md
index f7cd62b4dbe15c..4cec856f95d7af 100644
--- a/packages/plugin-legacy/README.md
+++ b/packages/plugin-legacy/README.md
@@ -27,6 +27,12 @@ export default {
}
```
+Terser must be installed because plugin-legacy uses Terser for minification.
+
+```sh
+npm add -D terser
+```
+
## Options
### `targets`
diff --git a/packages/plugin-legacy/package.json b/packages/plugin-legacy/package.json
index 3321c4de7815c7..9f854eb34d4228 100644
--- a/packages/plugin-legacy/package.json
+++ b/packages/plugin-legacy/package.json
@@ -35,17 +35,18 @@
},
"homepage": "https://github.com/vitejs/vite/tree/main/packages/plugin-legacy#readme",
"dependencies": {
- "@babel/standalone": "^7.18.4",
- "core-js": "^3.22.7",
+ "@babel/standalone": "^7.18.5",
+ "core-js": "^3.22.8",
"magic-string": "^0.26.2",
"regenerator-runtime": "^0.13.9",
"systemjs": "^6.12.1"
},
"peerDependencies": {
+ "terser": "^5.4.0",
"vite": "^3.0.0-alpha"
},
"devDependencies": {
- "vite": "workspace:*",
- "@babel/core": "^7.18.2"
+ "@babel/core": "^7.18.5",
+ "vite": "workspace:*"
}
}
diff --git a/packages/plugin-legacy/src/index.ts b/packages/plugin-legacy/src/index.ts
index 4aaab1aab2412d..0c9fb1c8c68d33 100644
--- a/packages/plugin-legacy/src/index.ts
+++ b/packages/plugin-legacy/src/index.ts
@@ -134,7 +134,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] {
config.build,
'es',
opts,
- options.externalSystemJS
+ true
)
return
}
@@ -566,7 +566,7 @@ async function buildPolyfillChunk(
buildOptions: BuildOptions,
format: 'iife' | 'es',
rollupOutputOptions: NormalizedOutputOptions,
- externalSystemJS?: boolean
+ excludeSystemJS?: boolean
) {
let { minify, assetsDir } = buildOptions
minify = minify ? 'terser' : false
@@ -575,7 +575,7 @@ async function buildPolyfillChunk(
root: path.dirname(fileURLToPath(import.meta.url)),
configFile: false,
logLevel: 'error',
- plugins: [polyfillsPlugin(imports, externalSystemJS)],
+ plugins: [polyfillsPlugin(imports, excludeSystemJS)],
build: {
write: false,
target: false,
@@ -614,7 +614,7 @@ const polyfillId = '\0vite/legacy-polyfills'
function polyfillsPlugin(
imports: Set,
- externalSystemJS?: boolean
+ excludeSystemJS?: boolean
): Plugin {
return {
name: 'vite:legacy-polyfills',
@@ -627,7 +627,7 @@ function polyfillsPlugin(
if (id === polyfillId) {
return (
[...imports].map((i) => `import "${i}";`).join('') +
- (externalSystemJS ? '' : `import "systemjs/dist/s.min.js";`)
+ (excludeSystemJS ? '' : `import "systemjs/dist/s.min.js";`)
)
}
}
diff --git a/packages/plugin-react/CHANGELOG.md b/packages/plugin-react/CHANGELOG.md
index d5f0d5195e707a..2690d9fb85a4f1 100644
--- a/packages/plugin-react/CHANGELOG.md
+++ b/packages/plugin-react/CHANGELOG.md
@@ -1,3 +1,12 @@
+## 2.0.0-alpha.3 (2022-06-12)
+
+* fix(deps): update all non-major dependencies (#8391) ([842f995](https://github.com/vitejs/vite/commit/842f995)), closes [#8391](https://github.com/vitejs/vite/issues/8391)
+* fix(plugin-react): apply manual runtime interop (#8546) ([f09299c](https://github.com/vitejs/vite/commit/f09299c)), closes [#8546](https://github.com/vitejs/vite/issues/8546)
+* fix(plugin-react): support import namespace in `parseReactAlias` (#5313) ([05b91cd](https://github.com/vitejs/vite/commit/05b91cd)), closes [#5313](https://github.com/vitejs/vite/issues/5313)
+* refactor: remove hooks ssr param support (#8491) ([f59adf8](https://github.com/vitejs/vite/commit/f59adf8)), closes [#8491](https://github.com/vitejs/vite/issues/8491)
+
+
+
## 2.0.0-alpha.2 (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/plugin-react/package.json b/packages/plugin-react/package.json
index 25ab4a39d72044..40cf3e60d72d6a 100644
--- a/packages/plugin-react/package.json
+++ b/packages/plugin-react/package.json
@@ -1,6 +1,6 @@
{
"name": "@vitejs/plugin-react",
- "version": "2.0.0-alpha.2",
+ "version": "2.0.0-alpha.3",
"license": "MIT",
"author": "Evan You",
"contributors": [
@@ -39,14 +39,12 @@
},
"homepage": "https://github.com/vitejs/vite/tree/main/packages/plugin-react#readme",
"dependencies": {
- "@babel/core": "^7.18.2",
+ "@babel/core": "^7.18.5",
"@babel/plugin-transform-react-jsx": "^7.17.12",
"@babel/plugin-transform-react-jsx-development": "^7.16.7",
"@babel/plugin-transform-react-jsx-self": "^7.17.12",
"@babel/plugin-transform-react-jsx-source": "^7.16.7",
- "@rollup/pluginutils": "^4.2.1",
- "react-refresh": "^0.13.0",
- "resolve": "^1.22.0"
+ "react-refresh": "^0.13.0"
},
"peerDependencies": {
"vite": "^3.0.0-alpha"
diff --git a/packages/plugin-react/src/index.ts b/packages/plugin-react/src/index.ts
index 562b8291112297..77ce68a630f631 100644
--- a/packages/plugin-react/src/index.ts
+++ b/packages/plugin-react/src/index.ts
@@ -1,8 +1,7 @@
import path from 'path'
import type { ParserOptions, TransformOptions, types as t } from '@babel/core'
import * as babel from '@babel/core'
-import { createFilter } from '@rollup/pluginutils'
-import { normalizePath } from 'vite'
+import { createFilter, normalizePath } from 'vite'
import type { Plugin, PluginOption, ResolvedConfig } from 'vite'
import {
addRefreshWrapper,
@@ -165,7 +164,7 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
}
},
async transform(code, id, options) {
- const ssr = typeof options === 'boolean' ? options : options?.ssr === true
+ const ssr = options?.ssr === true
// File extension could be mocked/overridden in querystring.
const [filepath, querystring = ''] = id.split('?')
const [extension = ''] =
@@ -361,7 +360,10 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
}
}
- // const runtimeId = 'react/jsx-runtime'
+ const reactJsxRuntimeId = 'react/jsx-runtime'
+ const reactJsxDevRuntimeId = 'react/jsx-dev-runtime'
+ const virtualReactJsxRuntimeId = '\0' + reactJsxRuntimeId
+ const virtualReactJsxDevRuntimeId = '\0' + reactJsxDevRuntimeId
// Adapted from https://github.com/alloc/vite-react-jsx
const viteReactJsx: Plugin = {
name: 'vite:react-jsx',
@@ -369,32 +371,42 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
config() {
return {
optimizeDeps: {
- include: ['react/jsx-dev-runtime']
+ include: [reactJsxRuntimeId, reactJsxDevRuntimeId]
}
}
- }
- // TODO: this optimization may not be necesary and it is breacking esbuild+rollup compat,
- // see https://github.com/vitejs/vite/pull/7246#discussion_r861552185
- // We could still do the same trick and resolve to the optimized dependency here
- /*
- resolveId(id: string) {
- return id === runtimeId ? id : null
- },
- load(id: string) {
- if (id === runtimeId) {
- const runtimePath = resolve.sync(runtimeId, {
- basedir: projectRoot
- })
- const exports = ['jsx', 'jsxs', 'Fragment']
+ },
+ resolveId(id, importer) {
+ // Resolve runtime to a virtual path to be interoped.
+ // Since the interop code re-imports `id`, we need to prevent re-resolving
+ // to the virtual id if the importer is already the virtual id.
+ if (id === reactJsxRuntimeId && importer !== virtualReactJsxRuntimeId) {
+ return virtualReactJsxRuntimeId
+ }
+ if (
+ id === reactJsxDevRuntimeId &&
+ importer !== virtualReactJsxDevRuntimeId
+ ) {
+ return virtualReactJsxDevRuntimeId
+ }
+ },
+ load(id) {
+ // Apply manual interop
+ if (id === virtualReactJsxRuntimeId) {
return [
- `import * as jsxRuntime from ${JSON.stringify(runtimePath)}`,
- // We can't use `export * from` or else any callsite that uses
- // this module will be compiled to `jsxRuntime.exports.jsx`
- // instead of the more concise `jsx` alias.
- ...exports.map((name) => `export const ${name} = jsxRuntime.${name}`)
+ `import * as jsxRuntime from ${JSON.stringify(reactJsxRuntimeId)}`,
+ `export const Fragment = jsxRuntime.Fragment`,
+ `export const jsx = jsxRuntime.jsx`,
+ `export const jsxs = jsxRuntime.jsxs`
].join('\n')
}
- } */
+ if (id === virtualReactJsxDevRuntimeId) {
+ return [
+ `import * as jsxRuntime from ${JSON.stringify(reactJsxDevRuntimeId)}`,
+ `export const Fragment = jsxRuntime.Fragment`,
+ `export const jsxDEV = jsxRuntime.jsxDEV`
+ ].join('\n')
+ }
+ }
}
return [viteBabel, viteReactRefresh, useAutomaticRuntime && viteReactJsx]
diff --git a/packages/plugin-react/src/jsx-runtime/restore-jsx.spec.ts b/packages/plugin-react/src/jsx-runtime/restore-jsx.spec.ts
index fcad0f78c3373b..7d5b14bfc9cfd4 100644
--- a/packages/plugin-react/src/jsx-runtime/restore-jsx.spec.ts
+++ b/packages/plugin-react/src/jsx-runtime/restore-jsx.spec.ts
@@ -1,6 +1,67 @@
import * as babel from '@babel/core'
import { describe, expect, it } from 'vitest'
-import { restoreJSX } from './restore-jsx'
+import { parseReactAlias, restoreJSX } from './restore-jsx'
+
+describe('parseReactAlias', () => {
+ it('handles cjs require', () => {
+ expect(parseReactAlias(`const React = require("react")`))
+ .toMatchInlineSnapshot(`
+ [
+ "React",
+ true,
+ ]
+ `)
+ })
+
+ it('handles cjs require (minified)', () => {
+ expect(parseReactAlias(`var F=require('foo');var R=require('react')`))
+ .toMatchInlineSnapshot(`
+ [
+ "R",
+ true,
+ ]
+ `)
+ })
+
+ it('does not handle destructured cjs require', () => {
+ expect(parseReactAlias(`var {createElement} = require("react")`))
+ .toMatchInlineSnapshot(`
+ [
+ undefined,
+ false,
+ ]
+ `)
+ })
+
+ it('handles esm import', () => {
+ expect(parseReactAlias(`import React from 'react'`)).toMatchInlineSnapshot(`
+ [
+ "React",
+ false,
+ ]
+ `)
+ })
+
+ it('handles esm import namespace', () => {
+ expect(parseReactAlias(`import * as React from "react"`))
+ .toMatchInlineSnapshot(`
+ [
+ "React",
+ false,
+ ]
+ `)
+ })
+
+ it('does not handle destructured esm import', () => {
+ expect(parseReactAlias(`import {createElement} from "react"`))
+ .toMatchInlineSnapshot(`
+ [
+ undefined,
+ false,
+ ]
+ `)
+ })
+})
async function jsx(sourceCode: string) {
const [ast] = await restoreJSX(babel, sourceCode, 'test.js')
diff --git a/packages/plugin-react/src/jsx-runtime/restore-jsx.ts b/packages/plugin-react/src/jsx-runtime/restore-jsx.ts
index 4acb6bb64f5e1b..d67a54e8f08aad 100644
--- a/packages/plugin-react/src/jsx-runtime/restore-jsx.ts
+++ b/packages/plugin-react/src/jsx-runtime/restore-jsx.ts
@@ -79,16 +79,16 @@ export async function restoreJSX(
return [result?.ast, isCommonJS]
}
-function parseReactAlias(
+export function parseReactAlias(
code: string
): [alias: string | undefined, isCommonJS: boolean] {
let match = code.match(
- /\b(var|let|const) +(\w+) *= *require\(["']react["']\)/
+ /\b(var|let|const)\s+([^=\{\s]+)\s*=\s*require\(["']react["']\)/
)
if (match) {
return [match[2], true]
}
- match = code.match(/^import (\w+).+? from ["']react["']/m)
+ match = code.match(/^import\s+(?:\*\s+as\s+)?(\w+).+?\bfrom\s*["']react["']/m)
if (match) {
return [match[1], false]
}
diff --git a/packages/plugin-vue-jsx/README.md b/packages/plugin-vue-jsx/README.md
index f6159cf3a82cab..c75e6d786f67b6 100644
--- a/packages/plugin-vue-jsx/README.md
+++ b/packages/plugin-vue-jsx/README.md
@@ -17,7 +17,23 @@ export default {
## Options
-See [@vue/babel-plugin-jsx](https://github.com/vuejs/jsx-next).
+### include
+
+Type: `(string | RegExp)[] | string | RegExp | null`
+
+Default: `/\.[jt]sx$/`
+
+A [picomatch pattern](https://github.com/micromatch/picomatch), or array of patterns, which specifies the files the plugin should operate on.
+
+### exclude
+
+Type: `(string | RegExp)[] | string | RegExp | null`
+
+Default: `undefined`
+
+A [picomatch pattern](https://github.com/micromatch/picomatch), or array of patterns, which specifies the files to be ignored by the plugin.
+
+> See [@vue/babel-plugin-jsx](https://github.com/vuejs/jsx-next) for other options.
## HMR Detection
diff --git a/packages/plugin-vue-jsx/package.json b/packages/plugin-vue-jsx/package.json
index 1e345081113256..e4e483dda373f6 100644
--- a/packages/plugin-vue-jsx/package.json
+++ b/packages/plugin-vue-jsx/package.json
@@ -35,10 +35,9 @@
},
"homepage": "https://github.com/vitejs/vite/tree/main/packages/plugin-vue-jsx#readme",
"dependencies": {
- "@babel/core": "^7.18.2",
+ "@babel/core": "^7.18.5",
"@babel/plugin-syntax-import-meta": "^7.10.4",
"@babel/plugin-transform-typescript": "^7.18.4",
- "@rollup/pluginutils": "^4.2.1",
"@vue/babel-plugin-jsx": "^1.1.1"
},
"devDependencies": {
diff --git a/packages/plugin-vue-jsx/src/index.ts b/packages/plugin-vue-jsx/src/index.ts
index 302cb323849ad6..48de3da46448ce 100644
--- a/packages/plugin-vue-jsx/src/index.ts
+++ b/packages/plugin-vue-jsx/src/index.ts
@@ -5,7 +5,7 @@ import * as babel from '@babel/core'
import jsx from '@vue/babel-plugin-jsx'
// @ts-expect-error missing type
import importMeta from '@babel/plugin-syntax-import-meta'
-import { createFilter, normalizePath } from '@rollup/pluginutils'
+import { createFilter, normalizePath } from 'vite'
import type { ComponentOptions } from 'vue'
import type { Plugin } from 'vite'
import type { Options } from './types'
@@ -74,7 +74,7 @@ function vueJsxPlugin(options: Options = {}): Plugin {
},
async transform(code, id, opt) {
- const ssr = typeof opt === 'boolean' ? opt : (opt && opt.ssr) === true
+ const ssr = opt?.ssr === true
const {
include,
exclude,
diff --git a/packages/plugin-vue-jsx/src/types.ts b/packages/plugin-vue-jsx/src/types.ts
index aa30b7435329f4..a3be580859ea00 100644
--- a/packages/plugin-vue-jsx/src/types.ts
+++ b/packages/plugin-vue-jsx/src/types.ts
@@ -1,5 +1,5 @@
import type { VueJSXPluginOptions } from '@vue/babel-plugin-jsx'
-import type { FilterPattern } from '@rollup/pluginutils'
+import type { FilterPattern } from 'vite'
export interface FilterOptions {
include?: FilterPattern
diff --git a/packages/plugin-vue/package.json b/packages/plugin-vue/package.json
index 999cda6486ad9f..7a5195fbf36703 100644
--- a/packages/plugin-vue/package.json
+++ b/packages/plugin-vue/package.json
@@ -42,13 +42,10 @@
"@jridgewell/gen-mapping": "^0.3.1",
"@jridgewell/trace-mapping": "^0.3.13",
"debug": "^4.3.4",
- "rollup": "^2.72.1",
+ "rollup": "^2.75.6",
"slash": "^4.0.0",
"source-map": "^0.6.1",
"vite": "workspace:*",
- "vue": "^3.2.36"
- },
- "dependencies": {
- "@rollup/pluginutils": "^4.2.1"
+ "vue": "^3.2.37"
}
}
diff --git a/packages/plugin-vue/src/index.ts b/packages/plugin-vue/src/index.ts
index 805df6fec674d0..3e1b2c3be1b7f5 100644
--- a/packages/plugin-vue/src/index.ts
+++ b/packages/plugin-vue/src/index.ts
@@ -1,6 +1,6 @@
import fs from 'fs'
import type { Plugin, ViteDevServer } from 'vite'
-import { createFilter } from '@rollup/pluginutils'
+import { createFilter } from 'vite'
/* eslint-disable import/no-duplicates */
import type {
SFCBlock,
@@ -107,14 +107,6 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin {
devToolsEnabled: process.env.NODE_ENV !== 'production'
}
- // Temporal handling for 2.7 breaking change
- const isSSR = (opt: { ssr?: boolean } | boolean | undefined) =>
- opt === undefined
- ? false
- : typeof opt === 'boolean'
- ? opt
- : opt?.ssr === true
-
return {
name: 'vite:vue',
@@ -169,7 +161,7 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin {
},
load(id, opt) {
- const ssr = isSSR(opt)
+ const ssr = opt?.ssr === true
if (id === EXPORT_HELPER_ID) {
return helperCode
}
@@ -202,7 +194,7 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin {
},
transform(code, id, opt) {
- const ssr = isSSR(opt)
+ const ssr = opt?.ssr === true
const { filename, query } = parseVueRequest(id)
if (query.raw) {
return
diff --git a/packages/plugin-vue/src/main.ts b/packages/plugin-vue/src/main.ts
index be11de7e33a23a..e92c48673a680e 100644
--- a/packages/plugin-vue/src/main.ts
+++ b/packages/plugin-vue/src/main.ts
@@ -1,13 +1,12 @@
import path from 'path'
import type { SFCBlock, SFCDescriptor } from 'vue/compiler-sfc'
-import type { PluginContext, SourceMap, TransformPluginContext } from 'rollup'
-import { normalizePath } from '@rollup/pluginutils'
+import type { PluginContext, TransformPluginContext } from 'rollup'
import type { RawSourceMap } from 'source-map'
import type { EncodedSourceMap as TraceEncodedSourceMap } from '@jridgewell/trace-mapping'
import { TraceMap, eachMapping } from '@jridgewell/trace-mapping'
import type { EncodedSourceMap as GenEncodedSourceMap } from '@jridgewell/gen-mapping'
import { addMapping, fromMap, toEncodedMap } from '@jridgewell/gen-mapping'
-import { transformWithEsbuild } from 'vite'
+import { normalizePath, transformWithEsbuild } from 'vite'
import {
createDescriptor,
getPrevDescriptor,
@@ -47,7 +46,7 @@ export async function transformMain(
const hasScoped = descriptor.styles.some((s) => s.scoped)
// script
- const { code: scriptCode, map } = await genScriptCode(
+ const { code: scriptCode, map: scriptMap } = await genScriptCode(
descriptor,
options,
pluginContext,
@@ -59,7 +58,7 @@ export async function transformMain(
descriptor.template && !isUseInlineTemplate(descriptor, !devServer)
let templateCode = ''
- let templateMap: RawSourceMap | undefined
+ let templateMap: RawSourceMap | undefined = undefined
if (hasTemplateImport) {
;({ code: templateCode, map: templateMap } = await genTemplateCode(
descriptor,
@@ -157,40 +156,46 @@ export async function transformMain(
)
}
- // if the template is inlined into the main module (indicated by the presence
- // of templateMap, we need to concatenate the two source maps.
- let resolvedMap = options.sourceMap ? map : undefined
- if (resolvedMap && templateMap) {
- const gen = fromMap(
- // version property of result.map is declared as string
- // but actually it is `3`
- map as Omit as TraceEncodedSourceMap
- )
- const tracer = new TraceMap(
- // same above
- templateMap as Omit as TraceEncodedSourceMap
- )
- const offset = (scriptCode.match(/\r?\n/g)?.length ?? 0) + 1
- eachMapping(tracer, (m) => {
- if (m.source == null) return
- addMapping(gen, {
- source: m.source,
- original: { line: m.originalLine, column: m.originalColumn },
- generated: {
- line: m.generatedLine + offset,
- column: m.generatedColumn
- }
+ let resolvedMap: RawSourceMap | undefined = undefined
+ if (options.sourceMap) {
+ if (scriptMap && templateMap) {
+ // if the template is inlined into the main module (indicated by the presence
+ // of templateMap, we need to concatenate the two source maps.
+
+ const gen = fromMap(
+ // version property of result.map is declared as string
+ // but actually it is `3`
+ scriptMap as Omit as TraceEncodedSourceMap
+ )
+ const tracer = new TraceMap(
+ // same above
+ templateMap as Omit as TraceEncodedSourceMap
+ )
+ const offset = (scriptCode.match(/\r?\n/g)?.length ?? 0) + 1
+ eachMapping(tracer, (m) => {
+ if (m.source == null) return
+ addMapping(gen, {
+ source: m.source,
+ original: { line: m.originalLine, column: m.originalColumn },
+ generated: {
+ line: m.generatedLine + offset,
+ column: m.generatedColumn
+ }
+ })
})
- })
- // same above
- resolvedMap = toEncodedMap(gen) as Omit<
- GenEncodedSourceMap,
- 'version'
- > as RawSourceMap
- // if this is a template only update, we will be reusing a cached version
- // of the main module compile result, which has outdated sourcesContent.
- resolvedMap.sourcesContent = templateMap.sourcesContent
+ // same above
+ resolvedMap = toEncodedMap(gen) as Omit<
+ GenEncodedSourceMap,
+ 'version'
+ > as RawSourceMap
+ // if this is a template only update, we will be reusing a cached version
+ // of the main module compile result, which has outdated sourcesContent.
+ resolvedMap.sourcesContent = templateMap.sourcesContent
+ } else {
+ // if one of `scriptMap` and `templateMap` is empty, use the other one
+ resolvedMap = scriptMap ?? templateMap
+ }
}
if (!attachedProps.length) {
@@ -288,10 +293,10 @@ async function genScriptCode(
ssr: boolean
): Promise<{
code: string
- map: RawSourceMap
+ map: RawSourceMap | undefined
}> {
let scriptCode = `const _sfc_main = {}`
- let map: RawSourceMap | SourceMap | undefined
+ let map: RawSourceMap | undefined
const script = resolveScript(descriptor, options, ssr)
if (script) {
@@ -323,7 +328,7 @@ async function genScriptCode(
}
return {
code: scriptCode,
- map: map as any
+ map
}
}
diff --git a/packages/vite/CHANGELOG.md b/packages/vite/CHANGELOG.md
index 7711aee6dc3b1f..03b7be90f66c65 100644
--- a/packages/vite/CHANGELOG.md
+++ b/packages/vite/CHANGELOG.md
@@ -1,3 +1,59 @@
+## 3.0.0-alpha.12 (2022-06-16)
+
+* chore: correct typo in console message (#8618) ([13d05bd](https://github.com/vitejs/vite/commit/13d05bd)), closes [#8618](https://github.com/vitejs/vite/issues/8618)
+* chore: enable eslint and prettier cache (#8585) ([d7beaeb](https://github.com/vitejs/vite/commit/d7beaeb)), closes [#8585](https://github.com/vitejs/vite/issues/8585)
+* chore: tweak server start output (#8582) ([3439132](https://github.com/vitejs/vite/commit/3439132)), closes [#8582](https://github.com/vitejs/vite/issues/8582)
+* fix: allow cache overlap in parallel builds (#8592) ([2dd0b49](https://github.com/vitejs/vite/commit/2dd0b49)), closes [#8592](https://github.com/vitejs/vite/issues/8592)
+* fix: avoid replacing defines and NODE_ENV in optimized deps (fix #8593) (#8606) ([739175b](https://github.com/vitejs/vite/commit/739175b)), closes [#8593](https://github.com/vitejs/vite/issues/8593) [#8606](https://github.com/vitejs/vite/issues/8606)
+* fix: sequential injection of tags in transformIndexHtml (#5851) (#6901) ([649c7f6](https://github.com/vitejs/vite/commit/649c7f6)), closes [#5851](https://github.com/vitejs/vite/issues/5851) [#6901](https://github.com/vitejs/vite/issues/6901)
+* fix(asset): respect assetFileNames if rollupOptions.output is an array (#8561) ([4e6c26f](https://github.com/vitejs/vite/commit/4e6c26f)), closes [#8561](https://github.com/vitejs/vite/issues/8561)
+* fix(css): escape pattern chars from base path in postcss dir-dependency messages (#7081) ([5151e74](https://github.com/vitejs/vite/commit/5151e74)), closes [#7081](https://github.com/vitejs/vite/issues/7081)
+* fix(optimizer): browser mapping for yarn pnp (#6493) ([c1c7af3](https://github.com/vitejs/vite/commit/c1c7af3)), closes [#6493](https://github.com/vitejs/vite/issues/6493)
+* feat: 500 response if the node proxy request fails (#7398) ([73e1775](https://github.com/vitejs/vite/commit/73e1775)), closes [#7398](https://github.com/vitejs/vite/issues/7398)
+* docs: worker related notes (#8554) ([c0c5e1a](https://github.com/vitejs/vite/commit/c0c5e1a)), closes [#8554](https://github.com/vitejs/vite/issues/8554)
+
+
+
+## 3.0.0-alpha.11 (2022-06-14)
+
+* fix: add missed JPEG file extensions to `KNOWN_ASSET_TYPES` (#8565) ([2dfc015](https://github.com/vitejs/vite/commit/2dfc015)), closes [#8565](https://github.com/vitejs/vite/issues/8565)
+* fix: default export module transformation for vitest spy (#8567) ([d357e33](https://github.com/vitejs/vite/commit/d357e33)), closes [#8567](https://github.com/vitejs/vite/issues/8567)
+* fix: default host to `localhost` instead of `127.0.0.1` (#8543) ([49c0896](https://github.com/vitejs/vite/commit/49c0896)), closes [#8543](https://github.com/vitejs/vite/issues/8543)
+* fix: dont handle sigterm in middleware mode (#8550) ([c6f43dd](https://github.com/vitejs/vite/commit/c6f43dd)), closes [#8550](https://github.com/vitejs/vite/issues/8550)
+* fix: mime missing extensions (#8568) ([acf3024](https://github.com/vitejs/vite/commit/acf3024)), closes [#8568](https://github.com/vitejs/vite/issues/8568)
+* fix: objurl for type module, and concurrent tests (#8541) ([26ecd5a](https://github.com/vitejs/vite/commit/26ecd5a)), closes [#8541](https://github.com/vitejs/vite/issues/8541)
+* fix: outdated optimized dep removed from module graph (#8533) ([3f4d22d](https://github.com/vitejs/vite/commit/3f4d22d)), closes [#8533](https://github.com/vitejs/vite/issues/8533)
+* fix(config): only rewrite .js loader in `loadConfigFromBundledFile` (#8556) ([2548dd3](https://github.com/vitejs/vite/commit/2548dd3)), closes [#8556](https://github.com/vitejs/vite/issues/8556)
+* fix(deps): update all non-major dependencies (#8558) ([9a1fd4c](https://github.com/vitejs/vite/commit/9a1fd4c)), closes [#8558](https://github.com/vitejs/vite/issues/8558)
+* fix(ssr): dont replace rollup input (#7275) ([9a88afa](https://github.com/vitejs/vite/commit/9a88afa)), closes [#7275](https://github.com/vitejs/vite/issues/7275)
+* chore: include 2.9.10-2.9.12 changelog in main (#8535) ([87f58ad](https://github.com/vitejs/vite/commit/87f58ad)), closes [#8535](https://github.com/vitejs/vite/issues/8535)
+* chore: refactor interop named imports (#8544) ([63b523a](https://github.com/vitejs/vite/commit/63b523a)), closes [#8544](https://github.com/vitejs/vite/issues/8544)
+* chore: remove rollup `namespaceToStringTag` (#8569) ([b85802a](https://github.com/vitejs/vite/commit/b85802a)), closes [#8569](https://github.com/vitejs/vite/issues/8569)
+* chore: remove unused timestamp option (#8545) ([d641860](https://github.com/vitejs/vite/commit/d641860)), closes [#8545](https://github.com/vitejs/vite/issues/8545)
+* chore: update major deps (#8572) ([0e20949](https://github.com/vitejs/vite/commit/0e20949)), closes [#8572](https://github.com/vitejs/vite/issues/8572)
+* feat: expose createFilter util (#8562) ([c5c424a](https://github.com/vitejs/vite/commit/c5c424a)), closes [#8562](https://github.com/vitejs/vite/issues/8562)
+
+
+
+## 3.0.0-alpha.10 (2022-06-10)
+
+* fix: deps optimizer idle logic for workers (fix #8479) (#8511) ([1e05548](https://github.com/vitejs/vite/commit/1e05548)), closes [#8479](https://github.com/vitejs/vite/issues/8479) [#8511](https://github.com/vitejs/vite/issues/8511)
+* fix: not match \n when injecting esbuild helpers (#8414) ([5a57626](https://github.com/vitejs/vite/commit/5a57626)), closes [#8414](https://github.com/vitejs/vite/issues/8414)
+* fix: respect optimize deps entries (#8489) ([fba82d0](https://github.com/vitejs/vite/commit/fba82d0)), closes [#8489](https://github.com/vitejs/vite/issues/8489)
+* fix(optimizer): encode `_` and `.` in different way (#8508) ([9065b37](https://github.com/vitejs/vite/commit/9065b37)), closes [#8508](https://github.com/vitejs/vite/issues/8508)
+* fix(optimizer): external require-import conversion (fixes #2492, #3409) (#8459) ([1061bbd](https://github.com/vitejs/vite/commit/1061bbd)), closes [#2492](https://github.com/vitejs/vite/issues/2492) [#3409](https://github.com/vitejs/vite/issues/3409) [#8459](https://github.com/vitejs/vite/issues/8459)
+* feat: better config `__dirname` support (#8442) ([51e9195](https://github.com/vitejs/vite/commit/51e9195)), closes [#8442](https://github.com/vitejs/vite/issues/8442)
+* feat: expose `version` (#8456) ([e992594](https://github.com/vitejs/vite/commit/e992594)), closes [#8456](https://github.com/vitejs/vite/issues/8456)
+* feat: handle named imports of builtin modules (#8338) ([e2e44ff](https://github.com/vitejs/vite/commit/e2e44ff)), closes [#8338](https://github.com/vitejs/vite/issues/8338)
+* feat: preserve process env vars in lib build (#8090) ([908c9e4](https://github.com/vitejs/vite/commit/908c9e4)), closes [#8090](https://github.com/vitejs/vite/issues/8090)
+* refactor!: make terser an optional dependency (#8049) ([164f528](https://github.com/vitejs/vite/commit/164f528)), closes [#8049](https://github.com/vitejs/vite/issues/8049)
+* chore: generate vite sourcemap when not production (#8453) ([129b499](https://github.com/vitejs/vite/commit/129b499)), closes [#8453](https://github.com/vitejs/vite/issues/8453)
+* chore: resolve ssr options (#8455) ([d97e402](https://github.com/vitejs/vite/commit/d97e402)), closes [#8455](https://github.com/vitejs/vite/issues/8455)
+* chore(deps): update all non-major dependencies (#8474) ([6d0ede7](https://github.com/vitejs/vite/commit/6d0ede7)), closes [#8474](https://github.com/vitejs/vite/issues/8474)
+* perf: disable postcss sourcemap when unused (#8451) ([64fc61c](https://github.com/vitejs/vite/commit/64fc61c)), closes [#8451](https://github.com/vitejs/vite/issues/8451)
+
+
+
## 3.0.0-alpha.9 (2022-06-01)
* fix: make array `acornInjectPlugins` work (fixes #8410) (#8415) ([08d594b](https://github.com/vitejs/vite/commit/08d594b)), closes [#8410](https://github.com/vitejs/vite/issues/8410) [#8415](https://github.com/vitejs/vite/issues/8415)
@@ -69,11 +125,9 @@
* fix: correctly replace process.env.NODE_ENV (#8283) ([ec52baa](https://github.com/vitejs/vite/commit/ec52baa)), closes [#8283](https://github.com/vitejs/vite/issues/8283)
* fix: dev sourcemap (#8269) ([505f75e](https://github.com/vitejs/vite/commit/505f75e)), closes [#8269](https://github.com/vitejs/vite/issues/8269)
-* fix: EPERM error on Windows when processing dependencies (#8235) ([67743a3](https://github.com/vitejs/vite/commit/67743a3)), closes [#8235](https://github.com/vitejs/vite/issues/8235)
* fix: glob types (#8257) ([03b227e](https://github.com/vitejs/vite/commit/03b227e)), closes [#8257](https://github.com/vitejs/vite/issues/8257)
* fix: srcset handling in html (#6419) ([a0ee4ff](https://github.com/vitejs/vite/commit/a0ee4ff)), closes [#6419](https://github.com/vitejs/vite/issues/6419)
* fix: support set NODE_ENV in scripts when custom mode option (#8218) ([adcf041](https://github.com/vitejs/vite/commit/adcf041)), closes [#8218](https://github.com/vitejs/vite/issues/8218)
-* fix(css): remove `?used` hack (fixes #6421, #8245) (#8278) ([0b25cc1](https://github.com/vitejs/vite/commit/0b25cc1)), closes [#6421](https://github.com/vitejs/vite/issues/6421) [#8245](https://github.com/vitejs/vite/issues/8245) [#8278](https://github.com/vitejs/vite/issues/8278)
* fix(hmr): catch thrown errors when connecting to hmr websocket (#7111) ([4bc9284](https://github.com/vitejs/vite/commit/4bc9284)), closes [#7111](https://github.com/vitejs/vite/issues/7111)
* fix(plugin-legacy): respect `entryFileNames` for polyfill chunks (#8247) ([baa9632](https://github.com/vitejs/vite/commit/baa9632)), closes [#8247](https://github.com/vitejs/vite/issues/8247)
* fix(plugin-react): broken optimized deps dir check (#8255) ([9e2a1ea](https://github.com/vitejs/vite/commit/9e2a1ea)), closes [#8255](https://github.com/vitejs/vite/issues/8255)
@@ -106,9 +160,7 @@
* feat: allow any JS identifier in define, not ASCII-only (#5972) ([95eb45b](https://github.com/vitejs/vite/commit/95eb45b)), closes [#5972](https://github.com/vitejs/vite/issues/5972)
* feat: enable `generatedCode: 'es2015'` for rollup build (#5018) ([46d5e67](https://github.com/vitejs/vite/commit/46d5e67)), closes [#5018](https://github.com/vitejs/vite/issues/5018)
-* feat: new hook `configurePreviewServer` (#7658) ([20ea999](https://github.com/vitejs/vite/commit/20ea999)), closes [#7658](https://github.com/vitejs/vite/issues/7658)
* feat: rework `dynamic-import-vars` (#7756) ([80d113b](https://github.com/vitejs/vite/commit/80d113b)), closes [#7756](https://github.com/vitejs/vite/issues/7756)
-* feat: treat Astro file scripts as TS (#8151) ([559c952](https://github.com/vitejs/vite/commit/559c952)), closes [#8151](https://github.com/vitejs/vite/issues/8151)
* feat: worker emit fileName with config (#7804) ([04c2edd](https://github.com/vitejs/vite/commit/04c2edd)), closes [#7804](https://github.com/vitejs/vite/issues/7804)
* feat(glob-import): support `{ import: '*' }` (#8071) ([0b78b2a](https://github.com/vitejs/vite/commit/0b78b2a)), closes [#8071](https://github.com/vitejs/vite/issues/8071)
* fix: add hash to lib chunk names (#7190) ([c81cedf](https://github.com/vitejs/vite/commit/c81cedf)), closes [#7190](https://github.com/vitejs/vite/issues/7190)
@@ -146,7 +198,6 @@
* chore: using Unicode instead of unicode in doc and tests (#6852) ([c2bf62b](https://github.com/vitejs/vite/commit/c2bf62b)), closes [#6852](https://github.com/vitejs/vite/issues/6852)
* chore(deps): update tsconfck to 2.0.0 built for node14+ (#8144) ([0513d13](https://github.com/vitejs/vite/commit/0513d13)), closes [#8144](https://github.com/vitejs/vite/issues/8144)
* chore(deps): use `esno` to replace `ts-node` (#8152) ([2363bd3](https://github.com/vitejs/vite/commit/2363bd3)), closes [#8152](https://github.com/vitejs/vite/issues/8152)
-* chore(lint): sort for imports (#8113) ([43a58dd](https://github.com/vitejs/vite/commit/43a58dd)), closes [#8113](https://github.com/vitejs/vite/issues/8113)
* build!: remove node v12 support (#7833) ([eeac2d2](https://github.com/vitejs/vite/commit/eeac2d2)), closes [#7833](https://github.com/vitejs/vite/issues/7833)
* feat!: rework `import.meta.glob` (#7537) ([330e0a9](https://github.com/vitejs/vite/commit/330e0a9)), closes [#7537](https://github.com/vitejs/vite/issues/7537)
* feat!: vite dev default port is now 5173 (#8148) ([1cc2e2d](https://github.com/vitejs/vite/commit/1cc2e2d)), closes [#8148](https://github.com/vitejs/vite/issues/8148)
@@ -158,6 +209,30 @@
+## 2.9.12 (2022-06-10)
+
+* fix: outdated optimized dep removed from module graph (#8534) ([c0d6c60](https://github.com/vitejs/vite/commit/c0d6c60)), closes [#8534](https://github.com/vitejs/vite/issues/8534)
+
+
+
+## 2.9.11 (2022-06-10)
+
+* fix: respect server.headers in static middlewares (#8481) ([ab7dc1c](https://github.com/vitejs/vite/commit/ab7dc1c)), closes [#8481](https://github.com/vitejs/vite/issues/8481)
+* fix(dev): avoid FOUC when swapping out link tag (fix #7973) (#8495) ([01fa807](https://github.com/vitejs/vite/commit/01fa807)), closes [#7973](https://github.com/vitejs/vite/issues/7973) [#8495](https://github.com/vitejs/vite/issues/8495)
+
+
+
+## 2.9.10 (2022-06-06)
+
+* feat: treat Astro file scripts as TS (#8151) ([9fdd0a3](https://github.com/vitejs/vite/commit/9fdd0a3)), closes [#8151](https://github.com/vitejs/vite/issues/8151)
+* feat: new hook `configurePreviewServer` (#7658) (#8437) ([7b972bc](https://github.com/vitejs/vite/commit/7b972bc)), closes [#7658](https://github.com/vitejs/vite/issues/7658) [#8437](https://github.com/vitejs/vite/issues/8437)
+* fix: remove empty chunk css imports when using esnext (#8345) ([9fbc1a9](https://github.com/vitejs/vite/commit/9fbc1a9)), closes [#8345](https://github.com/vitejs/vite/issues/8345)
+* fix: EPERM error on Windows when processing dependencies (#8235) ([dfe4307](https://github.com/vitejs/vite/commit/dfe4307)), closes [#8235](https://github.com/vitejs/vite/issues/8235)
+* fix(css): remove `?used` hack (fixes #6421, #8245) (#8278) (#8471) ([8d7bac4](https://github.com/vitejs/vite/commit/8d7bac4)), closes [#6421](https://github.com/vitejs/vite/issues/6421) [#8245](https://github.com/vitejs/vite/issues/8245) [#8278](https://github.com/vitejs/vite/issues/8278) [#8471](https://github.com/vitejs/vite/issues/8471)
+* chore(lint): sort for imports (#8113) ([4bd1531](https://github.com/vitejs/vite/commit/4bd1531)), closes [#8113](https://github.com/vitejs/vite/issues/8113)
+
+
+
## 2.9.9 (2022-05-11)
* fix: add direct query to html-proxy css (fixes #8091) (#8094) ([a24b5e3](https://github.com/vitejs/vite/commit/a24b5e3)), closes [#8091](https://github.com/vitejs/vite/issues/8091) [#8094](https://github.com/vitejs/vite/issues/8094)
diff --git a/packages/vite/LICENSE.md b/packages/vite/LICENSE.md
index e65a09826f0f4a..995c28ad9fad20 100644
--- a/packages/vite/LICENSE.md
+++ b/packages/vite/LICENSE.md
@@ -535,6 +535,28 @@ License: MIT
By: Rich Harris
Repository: rollup/plugins
+> The MIT License (MIT)
+>
+> Copyright (c) 2019 RollupJS Plugin Contributors (https://github.com/rollup/plugins/graphs/contributors)
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
---------------------------------------
## @vue/compiler-core
@@ -660,7 +682,7 @@ Repository: chalk/ansi-regex
> MIT License
>
-> Copyright (c) Sindre Sorhus (sindresorhus.com)
+> Copyright (c) Sindre Sorhus (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
@@ -3455,7 +3477,7 @@ Repository: chalk/strip-ansi
> MIT License
>
-> Copyright (c) Sindre Sorhus (sindresorhus.com)
+> Copyright (c) Sindre Sorhus (https://sindresorhus.com)
>
> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
>
@@ -3832,7 +3854,7 @@ License: ISC
By: Eemeli Aro
Repository: github:eemeli/yaml
-> Copyright 2018 Eemeli Aro
+> Copyright Eemeli Aro
>
> Permission to use, copy, modify, and/or distribute this software for any purpose
> with or without fee is hereby granted, provided that the above copyright notice
diff --git a/packages/vite/client.d.ts b/packages/vite/client.d.ts
index 948d66d1d7ad74..e99b4a526b7a58 100644
--- a/packages/vite/client.d.ts
+++ b/packages/vite/client.d.ts
@@ -74,6 +74,18 @@ declare module '*.jpeg' {
const src: string
export default src
}
+declare module '*.jfif' {
+ const src: string
+ export default src
+}
+declare module '*.pjpeg' {
+ const src: string
+ export default src
+}
+declare module '*.pjp' {
+ const src: string
+ export default src
+}
declare module '*.png' {
const src: string
export default src
diff --git a/packages/vite/package.json b/packages/vite/package.json
index 3b20f0e566d28b..805d6485d53acd 100644
--- a/packages/vite/package.json
+++ b/packages/vite/package.json
@@ -1,6 +1,6 @@
{
"name": "vite",
- "version": "3.0.0-alpha.9",
+ "version": "3.0.0-alpha.12",
"type": "module",
"license": "MIT",
"author": "Evan You",
@@ -20,10 +20,7 @@
"./client": {
"types": "./client.d.ts"
},
- "./dist/client/*": "./dist/client/*",
- "./terser": {
- "require": "./dist/node-cjs/terser.cjs"
- }
+ "./dist/client/*": "./dist/client/*"
},
"files": [
"bin",
@@ -54,23 +51,23 @@
"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\"",
+ "lint": "eslint --cache --ext .ts src/**",
+ "format": "prettier --write --cache --parser typescript \"src/**/*.ts\"",
"prepublishOnly": "npm run build"
},
"//": "READ CONTRIBUTING.md to understand what to put under deps vs. devDeps!",
"dependencies": {
- "esbuild": "^0.14.38",
+ "esbuild": "^0.14.43",
"postcss": "^8.4.14",
"resolve": "^1.22.0",
- "rollup": "^2.72.1"
+ "rollup": "^2.75.6"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
},
"devDependencies": {
"@ampproject/remapping": "^2.2.0",
- "@babel/parser": "^7.18.4",
+ "@babel/parser": "^7.18.5",
"@babel/types": "^7.18.4",
"@jridgewell/trace-mapping": "^0.3.13",
"@rollup/plugin-alias": "^3.1.9",
@@ -78,11 +75,11 @@
"@rollup/plugin-dynamic-import-vars": "^1.4.3",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "13.3.0",
- "@rollup/plugin-typescript": "^8.3.2",
+ "@rollup/plugin-typescript": "^8.3.3",
"@rollup/pluginutils": "^4.2.1",
- "@vue/compiler-dom": "^3.2.36",
+ "@vue/compiler-dom": "^3.2.37",
"acorn": "^8.7.1",
- "cac": "6.7.9",
+ "cac": "^6.7.12",
"chokidar": "^3.5.3",
"connect": "^3.7.0",
"connect-history-api-fallback": "^1.6.0",
@@ -94,7 +91,7 @@
"dotenv-expand": "^5.1.0",
"es-module-lexer": "^0.10.5",
"esno": "^0.16.3",
- "estree-walker": "^2.0.2",
+ "estree-walker": "^3.0.1",
"etag": "^1.8.1",
"fast-glob": "^3.2.11",
"http-proxy": "^1.18.1",
@@ -102,33 +99,33 @@
"launch-editor-middleware": "^2.4.0",
"magic-string": "^0.26.2",
"micromatch": "^4.0.5",
- "mrmime": "^1.0.0",
+ "mrmime": "^1.0.1",
"node-forge": "^1.3.1",
"okie": "^1.0.1",
"open": "^8.4.0",
- "periscopic": "^2.0.3",
+ "periscopic": "^3.0.4",
"picocolors": "^1.0.0",
"postcss-import": "^14.1.0",
- "postcss-load-config": "^3.1.4",
+ "postcss-load-config": "^4.0.1",
"postcss-modules": "^4.3.1",
"resolve.exports": "^1.1.0",
- "rollup-plugin-license": "^2.8.0",
+ "rollup-plugin-license": "^2.8.1",
"sirv": "^2.0.2",
"source-map-js": "^1.0.2",
"source-map-support": "^0.5.21",
- "strip-ansi": "^6.0.1",
+ "strip-ansi": "^7.0.1",
"strip-literal": "^0.3.0",
- "terser": "^5.14.0",
"tsconfck": "^2.0.1",
"tslib": "^2.4.0",
"types": "link:./types",
"ufo": "^0.8.4",
- "ws": "^8.7.0"
+ "ws": "^8.8.0"
},
"peerDependencies": {
"less": "*",
"sass": "*",
- "stylus": "*"
+ "stylus": "*",
+ "terser": "^5.4.0"
},
"peerDependenciesMeta": {
"sass": {
@@ -139,6 +136,9 @@
},
"less": {
"optional": true
+ },
+ "terser": {
+ "optional": true
}
}
}
diff --git a/packages/vite/rollup.config.ts b/packages/vite/rollup.config.ts
index 6759ede01d14c2..0e321956a0d287 100644
--- a/packages/vite/rollup.config.ts
+++ b/packages/vite/rollup.config.ts
@@ -118,20 +118,11 @@ function createNodePlugins(
// Shim them with eval() so rollup can skip these calls.
isProduction &&
shimDepsPlugin({
- 'plugins/terser.ts': {
- src: `require.resolve('terser'`,
- replacement: `require.resolve('vite/terser'`
- },
// chokidar -> fsevents
'fsevents-handler.js': {
src: `require('fsevents')`,
replacement: `__require('fsevents')`
},
- // cac re-assigns module.exports even in its mjs dist
- 'cac/dist/index.mjs': {
- src: `if (typeof module !== "undefined") {`,
- replacement: `if (false) {`
- },
// postcss-import -> sugarss
'process-content.js': {
src: 'require("sugarss")',
@@ -183,7 +174,7 @@ function createNodeConfig(isProduction: boolean) {
],
plugins: createNodePlugins(
isProduction,
- false,
+ !isProduction,
// in production we use api-extractor for dts generation
// in development we need to rely on the rollup ts plugin
isProduction ? false : path.resolve(__dirname, 'dist/node')
@@ -191,27 +182,6 @@ function createNodeConfig(isProduction: boolean) {
})
}
-/**
- * Terser needs to be run inside a worker, so it cannot be part of the main
- * bundle. We produce a separate bundle for it and shims plugin/terser.ts to
- * use the production path during build.
- */
-const terserConfig = defineConfig({
- ...sharedNodeOptions,
- output: {
- ...sharedNodeOptions.output,
- entryFileNames: `node-cjs/[name].cjs`,
- exports: 'default',
- format: 'cjs',
- sourcemap: false
- },
- input: {
- // eslint-disable-next-line node/no-restricted-require
- terser: require.resolve('terser')
- },
- plugins: [nodeResolve(), commonjs()]
-})
-
function createCjsConfig(isProduction: boolean) {
return defineConfig({
...sharedNodeOptions,
@@ -233,7 +203,7 @@ function createCjsConfig(isProduction: boolean) {
...Object.keys(pkg.dependencies),
...(isProduction ? [] : Object.keys(pkg.devDependencies))
],
- plugins: [...createNodePlugins(false, false, false), bundleSizeLimit(55)]
+ plugins: [...createNodePlugins(false, false, false), bundleSizeLimit(120)]
})
}
@@ -245,8 +215,7 @@ export default (commandLineArgs: any) => {
envConfig,
clientConfig,
createNodeConfig(isProduction),
- createCjsConfig(isProduction),
- ...(isProduction ? [terserConfig] : [])
+ createCjsConfig(isProduction)
])
}
diff --git a/packages/vite/src/client/client.ts b/packages/vite/src/client/client.ts
index 5aec1eae9c5bc0..8f39164e05a774 100644
--- a/packages/vite/src/client/client.ts
+++ b/packages/vite/src/client/client.ts
@@ -101,7 +101,18 @@ async function handleMessage(payload: HMRPayload) {
const newPath = `${base}${searchUrl.slice(1)}${
searchUrl.includes('?') ? '&' : '?'
}t=${timestamp}`
- el.href = new URL(newPath, el.href).href
+
+ // rather than swapping the href on the existing tag, we will
+ // create a new link tag. Once the new stylesheet has loaded we
+ // will remove the existing link tag. This removes a Flash Of
+ // Unstyled Content that can occur when swapping out the tag href
+ // directly, as the new stylesheet has not yet been loaded.
+ const newLinkTag = el.cloneNode() as HTMLLinkElement
+ newLinkTag.href = new URL(newPath, el.href).href
+ const removeOldEl = () => el.remove()
+ newLinkTag.addEventListener('load', removeOldEl)
+ newLinkTag.addEventListener('error', removeOldEl)
+ el.after(newLinkTag)
}
console.log(`[vite] css hot updated: ${searchUrl}`)
}
diff --git a/packages/vite/src/node/__tests__/utils.spec.ts b/packages/vite/src/node/__tests__/utils.spec.ts
index c8a824bbb3d28f..5a6ea4d55de30c 100644
--- a/packages/vite/src/node/__tests__/utils.spec.ts
+++ b/packages/vite/src/node/__tests__/utils.spec.ts
@@ -49,9 +49,9 @@ describe('injectQuery', () => {
})
describe('resolveHostname', () => {
- test('defaults to 127.0.0.1', () => {
+ test('defaults to localhost', () => {
expect(resolveHostname(undefined)).toEqual({
- host: '127.0.0.1',
+ host: 'localhost',
name: 'localhost'
})
})
@@ -62,6 +62,27 @@ describe('resolveHostname', () => {
name: 'localhost'
})
})
+
+ test('accepts 0.0.0.0', () => {
+ expect(resolveHostname('0.0.0.0')).toEqual({
+ host: '0.0.0.0',
+ name: 'localhost'
+ })
+ })
+
+ test('accepts ::', () => {
+ expect(resolveHostname('::')).toEqual({
+ host: '::',
+ name: 'localhost'
+ })
+ })
+
+ test('accepts 0000:0000:0000:0000:0000:0000:0000:0000', () => {
+ expect(resolveHostname('0000:0000:0000:0000:0000:0000:0000:0000')).toEqual({
+ host: '0000:0000:0000:0000:0000:0000:0000:0000',
+ name: 'localhost'
+ })
+ })
})
test('ts import of file with .js extension', () => {
diff --git a/packages/vite/src/node/build.ts b/packages/vite/src/node/build.ts
index 705465400ca5ca..c3d59d88a0549b 100644
--- a/packages/vite/src/node/build.ts
+++ b/packages/vite/src/node/build.ts
@@ -407,7 +407,6 @@ async function doBuild(
}
const rollupOptions: RollupOptions = {
- input,
context: 'globalThis',
preserveEntrySignatures: ssr
? 'allow-extension'
@@ -415,6 +414,7 @@ async function doBuild(
? 'strict'
: false,
...options.rollupOptions,
+ input,
plugins,
external,
onwarn(warning, warn) {
@@ -460,6 +460,9 @@ async function doBuild(
exports: cjsSsrBuild ? 'named' : 'auto',
sourcemap: options.sourcemap,
name: libOptions ? libOptions.name : undefined,
+ // es2015 enables `generatedCode.symbols`
+ // - #764 add `Symbol.toStringTag` when build es module into cjs chunk
+ // - #1048 add `Symbol.toStringTag` for module default export
generatedCode: 'es2015',
entryFileNames: ssr
? `[name].${jsExt}`
@@ -472,9 +475,6 @@ async function doBuild(
assetFileNames: libOptions
? `[name].[ext]`
: path.posix.join(options.assetsDir, `[name].[hash].[ext]`),
- // #764 add `Symbol.toStringTag` when build es module into cjs chunk
- // #1048 add `Symbol.toStringTag` for module default export
- namespaceToStringTag: true,
inlineDynamicImports:
output.format === 'umd' ||
output.format === 'iife' ||
diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts
index b7f90c162fd475..c8ede65abfd2b4 100644
--- a/packages/vite/src/node/config.ts
+++ b/packages/vite/src/node/config.ts
@@ -5,7 +5,6 @@ import { performance } from 'perf_hooks'
import { createRequire } from 'module'
import colors from 'picocolors'
import type { Alias, AliasOptions } from 'types/alias'
-import { createFilter } from '@rollup/pluginutils'
import aliasPlugin from '@rollup/plugin-alias'
import { build } from 'esbuild'
import type { RollupOptions } from 'rollup'
@@ -19,6 +18,7 @@ import { resolvePreviewOptions } from './preview'
import type { CSSOptions } from './plugins/css'
import {
createDebugger,
+ createFilter,
dynamicImport,
isExternalUrl,
isObject,
@@ -41,6 +41,8 @@ import type { PluginContainer } from './server/pluginContainer'
import { createPluginContainer } from './server/pluginContainer'
import type { PackageCache } from './packages'
import { loadEnv, resolveEnvPrefix } from './env'
+import type { ResolvedSSROptions, SSROptions } from './ssr'
+import { resolveSSROptions } from './ssr'
const debug = createDebugger('vite:config')
@@ -236,29 +238,6 @@ export interface ExperimentalOptions {
importGlobRestoreExtension?: boolean
}
-export type SSRTarget = 'node' | 'webworker'
-
-export type SSRFormat = 'esm' | 'cjs'
-
-export interface SSROptions {
- external?: string[]
- noExternal?: string | RegExp | (string | RegExp)[] | true
- /**
- * Define the target for the ssr build. The browser field in package.json
- * is ignored for node but used if webworker is the target
- * Default: 'node'
- */
- target?: SSRTarget
- /**
- * Define the format for the ssr build. Since Vite v3 the SSR build generates ESM by default.
- * `'cjs'` can be selected to generate a CJS build, but it isn't recommended. This option is
- * left marked as experimental to give users more time to update to ESM. CJS builds requires
- * complex externalization heuristics that aren't present in the ESM format.
- * @experimental
- */
- format?: SSRFormat
-}
-
export interface ResolveWorkerOptions {
format: 'es' | 'iife'
plugins: Plugin[]
@@ -282,6 +261,7 @@ export type ResolvedConfig = Readonly<
command: 'build' | 'serve'
mode: string
isWorker: boolean
+ // in nested worker bundle to find the main config
/** @internal */
mainConfig: ResolvedConfig | null
isProduction: boolean
@@ -293,6 +273,7 @@ export type ResolvedConfig = Readonly<
server: ResolvedServerOptions
build: ResolvedBuildOptions
preview: ResolvedPreviewOptions
+ ssr: ResolvedSSROptions | undefined
assetsInclude: (file: string) => boolean
logger: Logger
createResolver: (options?: Partial) => ResolveFn
@@ -499,6 +480,7 @@ export async function resolveConfig(
: ''
const server = resolveServerOptions(resolvedRoot, config.server, logger)
+ const ssr = resolveSSROptions(config.ssr)
const optimizeDeps = config.optimizeDeps || {}
@@ -516,6 +498,7 @@ export async function resolveConfig(
cacheDir,
command,
mode,
+ ssr,
isWorker: false,
mainConfig: null,
isProduction,
@@ -550,7 +533,9 @@ export async function resolveConfig(
: 'spa'
}
- // flat config.worker.plugin
+ // Some plugins that aren't intended to work in the bundling of workers (doing post-processing at build time for example).
+ // And Plugins may also have cached that could be corrupted by being used in these extra rollup calls.
+ // So we need to separate the worker plugin from the plugin that vite needs to run.
const [workerPrePlugins, workerNormalPlugins, workerPostPlugins] =
sortUserPlugins(config.worker?.plugins as Plugin[])
const workerResolved: ResolvedConfig = {
@@ -595,6 +580,29 @@ export async function resolveConfig(
)
}
+ // Check if all assetFileNames have the same reference.
+ // If not, display a warn for user.
+ const outputOption = config.build?.rollupOptions?.output ?? []
+ // Use isArray to narrow its type to array
+ if (Array.isArray(outputOption)) {
+ const assetFileNamesList = outputOption.map(
+ (output) => output.assetFileNames
+ )
+ if (assetFileNamesList.length > 1) {
+ const firstAssetFileNames = assetFileNamesList[0]
+ const hasDifferentReference = assetFileNamesList.some(
+ (assetFileNames) => assetFileNames !== firstAssetFileNames
+ )
+ if (hasDifferentReference) {
+ resolved.logger.warn(
+ colors.yellow(`
+assetFileNames isn't equal for every build.rollupOptions.output. A single pattern across all outputs is supported by Vite.
+`)
+ )
+ }
+ }
+ }
+
return resolved
}
@@ -801,6 +809,7 @@ async function bundleConfigFile(
fileName: string,
isESM = false
): Promise<{ code: string; dependencies: string[] }> {
+ const importMetaUrlVarName = '__vite_injected_original_import_meta_url'
const result = await build({
absWorkingDir: process.cwd(),
entryPoints: [fileName],
@@ -811,6 +820,9 @@ async function bundleConfigFile(
format: isESM ? 'esm' : 'cjs',
sourcemap: 'inline',
metafile: true,
+ define: {
+ 'import.meta.url': importMetaUrlVarName
+ },
plugins: [
{
name: 'externalize-deps',
@@ -826,22 +838,20 @@ async function bundleConfigFile(
}
},
{
- name: 'replace-import-meta',
+ name: 'inject-file-scope-variables',
setup(build) {
build.onLoad({ filter: /\.[jt]s$/ }, async (args) => {
const contents = await fs.promises.readFile(args.path, 'utf8')
+ const injectValues =
+ `const __dirname = ${JSON.stringify(path.dirname(args.path))};` +
+ `const __filename = ${JSON.stringify(args.path)};` +
+ `const ${importMetaUrlVarName} = ${JSON.stringify(
+ pathToFileURL(args.path).href
+ )};`
+
return {
loader: args.path.endsWith('.ts') ? 'ts' : 'js',
- contents: contents
- .replace(
- /\bimport\.meta\.url\b/g,
- JSON.stringify(pathToFileURL(args.path).href)
- )
- .replace(
- /\b__dirname\b/g,
- JSON.stringify(path.dirname(args.path))
- )
- .replace(/\b__filename\b/g, JSON.stringify(args.path))
+ contents: injectValues + contents
}
})
}
@@ -864,10 +874,9 @@ async function loadConfigFromBundledFile(
fileName: string,
bundledCode: string
): Promise {
- const extension = path.extname(fileName)
const realFileName = fs.realpathSync(fileName)
- const defaultLoader = _require.extensions[extension]!
- _require.extensions[extension] = (module: NodeModule, filename: string) => {
+ const defaultLoader = _require.extensions['.js']
+ _require.extensions['.js'] = (module: NodeModule, filename: string) => {
if (filename === realFileName) {
;(module as NodeModuleWithCompile)._compile(bundledCode, filename)
} else {
@@ -877,9 +886,8 @@ async function loadConfigFromBundledFile(
// clear cache in case of server restart
delete _require.cache[_require.resolve(fileName)]
const raw = _require(fileName)
- const config = raw.__esModule ? raw.default : raw
- _require.extensions[extension] = defaultLoader
- return config
+ _require.extensions['.js'] = defaultLoader
+ return raw.__esModule ? raw.default : raw
}
export function isDepsOptimizerEnabled(config: ResolvedConfig): boolean {
diff --git a/packages/vite/src/node/constants.ts b/packages/vite/src/node/constants.ts
index 4e5d3da96f50da..3b4d496e30bd3c 100644
--- a/packages/vite/src/node/constants.ts
+++ b/packages/vite/src/node/constants.ts
@@ -62,11 +62,17 @@ export const CLIENT_DIR = path.dirname(CLIENT_ENTRY)
// ** READ THIS ** before editing `KNOWN_ASSET_TYPES`.
// If you add an asset to `KNOWN_ASSET_TYPES`, make sure to also add it
-// to the TypeScript declaration file `packages/vite/client.d.ts`.
+// to the TypeScript declaration file `packages/vite/client.d.ts` and
+// add a mime type to the `registerCustomMime` in
+// `packages/vite/src/node/plugin/assets.ts` if mime type cannot be
+// looked up by mrmime.
export const KNOWN_ASSET_TYPES = [
// images
'png',
'jpe?g',
+ 'jfif',
+ 'pjpeg',
+ 'pjp',
'gif',
'svg',
'ico',
@@ -99,3 +105,15 @@ export const DEFAULT_ASSETS_RE = new RegExp(
)
export const DEP_VERSION_RE = /[\?&](v=[\w\.-]+)\b/
+
+export const loopbackHosts = new Set([
+ 'localhost',
+ '127.0.0.1',
+ '::1',
+ '0000:0000:0000:0000:0000:0000:0000:0001'
+])
+export const wildcardHosts = new Set([
+ '0.0.0.0',
+ '::',
+ '0000:0000:0000:0000:0000:0000:0000:0000'
+])
diff --git a/packages/vite/src/node/http.ts b/packages/vite/src/node/http.ts
index 2a1c7c920b8ea9..c2757f36477600 100644
--- a/packages/vite/src/node/http.ts
+++ b/packages/vite/src/node/http.ts
@@ -5,6 +5,7 @@ import type {
OutgoingHttpHeaders as HttpServerHeaders
} from 'http'
import type { ServerOptions as HttpsServerOptions } from 'https'
+import { promises as dns } from 'dns'
import type { Connect } from 'types/connect'
import { isObject } from './utils'
import type { ProxyOptions } from './server/middlewares/proxy'
@@ -184,9 +185,16 @@ export async function httpServerStart(
logger: Logger
}
): Promise {
- return new Promise((resolve, reject) => {
- let { port, strictPort, host, logger } = serverOptions
+ let { port, strictPort, host, logger } = serverOptions
+
+ // This could be removed when Vite only supports Node 17+ because verbatim=true is default
+ // https://github.com/nodejs/node/pull/39987
+ if (host === 'localhost') {
+ const addr = await dns.lookup('localhost', { verbatim: true })
+ host = addr.address
+ }
+ return new Promise((resolve, reject) => {
const onError = (e: Error & { code?: string }) => {
if (e.code === 'EADDRINUSE') {
if (strictPort) {
diff --git a/packages/vite/src/node/index.ts b/packages/vite/src/node/index.ts
index ff8c0ebdf6abab..38952e8a466b62 100644
--- a/packages/vite/src/node/index.ts
+++ b/packages/vite/src/node/index.ts
@@ -10,6 +10,7 @@ export { resolvePackageData } from './packages'
export * from './publicUtils'
// additional types
+export type { FilterPattern } from './utils'
export type { CorsOptions, CorsOrigin, CommonServerOptions } from './http'
export type {
ViteDevServer,
@@ -39,6 +40,12 @@ export type {
DepsOptimizer,
ExportsData
} from './optimizer'
+export type {
+ ResolvedSSROptions,
+ SSROptions,
+ SSRFormat,
+ SSRTarget
+} from './ssr'
export type { Plugin } from './plugin'
export type { PackageCache, PackageData } from './packages'
export type {
diff --git a/packages/vite/src/node/logger.ts b/packages/vite/src/node/logger.ts
index 1176a265a4fcbe..0518d86b271ac7 100644
--- a/packages/vite/src/node/logger.ts
+++ b/packages/vite/src/node/logger.ts
@@ -8,6 +8,7 @@ import type { RollupError } from 'rollup'
import type { CommonServerOptions } from './http'
import type { Hostname } from './utils'
import { resolveHostname } from './utils'
+import { loopbackHosts, wildcardHosts } from './constants'
import type { ResolvedConfig } from '.'
export type LogType = 'error' | 'warn' | 'info'
@@ -172,19 +173,30 @@ function printServerUrls(
info: Logger['info']
): void {
const urls: Array<{ label: string; url: string }> = []
+ const notes: Array<{ label: string; message: string }> = []
+
+ if (hostname.host && loopbackHosts.has(hostname.host)) {
+ let hostnameName = hostname.name
+ if (
+ hostnameName === '::1' ||
+ hostnameName === '0000:0000:0000:0000:0000:0000:0000:0001'
+ ) {
+ hostnameName = `[${hostnameName}]`
+ }
- if (hostname.host === '127.0.0.1') {
urls.push({
label: 'Local',
url: colors.cyan(
- `${protocol}://${hostname.name}:${colors.bold(port)}${base}`
+ `${protocol}://${hostnameName}:${colors.bold(port)}${base}`
)
})
- if (hostname.name !== '127.0.0.1') {
- urls.push({
- label: 'Network',
- url: colors.dim(`use ${colors.white(colors.bold('--host'))} to expose`)
+ if (hostname.name === 'localhost') {
+ notes.push({
+ label: 'Hint',
+ message: colors.dim(
+ `Use ${colors.white(colors.bold('--host'))} to expose to network.`
+ )
})
}
} else {
@@ -208,15 +220,34 @@ function printServerUrls(
})
}
- const length = urls.reduce(
- (length, { label }) => Math.max(length, label.length),
- 0
+ if (!hostname.host || wildcardHosts.has(hostname.host)) {
+ notes.push({
+ label: 'Note',
+ message: colors.dim(
+ 'You are using a wildcard host. Ports might be overridden.'
+ )
+ })
+ }
+
+ const length = Math.max(
+ ...[...urls, ...notes].map(({ label }) => label.length)
)
- urls.forEach(({ label, url: text }) => {
+ const print = (
+ iconWithColor: string,
+ label: string,
+ messageWithColor: string
+ ) => {
info(
- ` ${colors.green('➜')} ${colors.bold(label)}: ${' '.repeat(
+ ` ${iconWithColor} ${colors.bold(label)}: ${' '.repeat(
length - label.length
- )}${text}`
+ )}${messageWithColor}`
)
+ }
+
+ urls.forEach(({ label, url: text }) => {
+ print(colors.green('➜'), label, text)
+ })
+ notes.forEach(({ label, message: text }) => {
+ print(colors.white('❖'), label, text)
})
}
diff --git a/packages/vite/src/node/optimizer/esbuildDepPlugin.ts b/packages/vite/src/node/optimizer/esbuildDepPlugin.ts
index 0c32af75219438..aacabbdf9b1a3c 100644
--- a/packages/vite/src/node/optimizer/esbuildDepPlugin.ts
+++ b/packages/vite/src/node/optimizer/esbuildDepPlugin.ts
@@ -13,6 +13,10 @@ import {
import { browserExternalId } from '../plugins/resolve'
import type { ExportsData } from '.'
+const externalWithConversionNamespace =
+ 'vite:dep-pre-bundle:external-conversion'
+const convertedExternalPrefix = 'vite-dep-pre-bundle-external:'
+
const externalTypes = [
'css',
// supported pre-processor types
@@ -76,24 +80,64 @@ export function esbuildDepPlugin(
return resolver(id, _importer, undefined)
}
+ const resolveResult = (id: string, resolved: string) => {
+ if (resolved.startsWith(browserExternalId)) {
+ return {
+ path: id,
+ namespace: 'browser-external'
+ }
+ }
+ if (isExternalUrl(resolved)) {
+ return {
+ path: resolved,
+ external: true
+ }
+ }
+ return {
+ path: path.resolve(resolved)
+ }
+ }
+
return {
name: 'vite:dep-pre-bundle',
setup(build) {
// externalize assets and commonly known non-js file types
+ // See #8459 for more details about this require-import conversion
build.onResolve(
{
filter: new RegExp(`\\.(` + allExternalTypes.join('|') + `)(\\?.*)?$`)
},
async ({ path: id, importer, kind }) => {
+ // if the prefix exist, it is already converted to `import`, so set `external: true`
+ if (id.startsWith(convertedExternalPrefix)) {
+ return {
+ path: id.slice(convertedExternalPrefix.length),
+ external: true
+ }
+ }
+
const resolved = await resolve(id, importer, kind)
if (resolved) {
+ // here it is not set to `external: true` to convert `require` to `import`
return {
path: resolved,
- external: true
+ namespace: externalWithConversionNamespace
}
}
}
)
+ build.onLoad(
+ { filter: /./, namespace: externalWithConversionNamespace },
+ (args) => {
+ // import itself with prefix (this is the actual part of require-import conversion)
+ return {
+ contents:
+ `export { default } from "${convertedExternalPrefix}${args.path}";` +
+ `export * from "${convertedExternalPrefix}${args.path}";`,
+ loader: 'js'
+ }
+ }
+ )
function resolveEntry(id: string) {
const flatId = flattenId(id)
@@ -130,21 +174,7 @@ export function esbuildDepPlugin(
// use vite's own resolver
const resolved = await resolve(id, importer, kind)
if (resolved) {
- if (resolved.startsWith(browserExternalId)) {
- return {
- path: id,
- namespace: 'browser-external'
- }
- }
- if (isExternalUrl(resolved)) {
- return {
- path: resolved,
- external: true
- }
- }
- return {
- path: path.resolve(resolved)
- }
+ return resolveResult(id, resolved)
}
}
)
@@ -193,15 +223,43 @@ export function esbuildDepPlugin(
build.onLoad(
{ filter: /.*/, namespace: 'browser-external' },
- ({ path: id }) => {
- return {
- contents:
- `export default new Proxy({}, {
- get() {
- throw new Error('Module "${id}" has been externalized for ` +
- `browser compatibility and cannot be accessed in client code.')
+ ({ path }) => {
+ if (config.isProduction) {
+ return {
+ contents: 'module.exports = {}'
+ }
+ } else {
+ return {
+ // Return in CJS to intercept named imports. Use `Object.create` to
+ // create the Proxy in the prototype to workaround esbuild issue. Why?
+ //
+ // In short, esbuild cjs->esm flow:
+ // 1. Create empty object using `Object.create(Object.getPrototypeOf(module.exports))`.
+ // 2. Assign props of `module.exports` to the object.
+ // 3. Return object for ESM use.
+ //
+ // If we do `module.exports = new Proxy({}, {})`, step 1 returns empty object,
+ // step 2 does nothing as there's no props for `module.exports`. The final object
+ // is just an empty object.
+ //
+ // Creating the Proxy in the prototype satisfies step 1 immediately, which means
+ // the returned object is a Proxy that we can intercept.
+ //
+ // Note: Skip keys that are accessed by esbuild and browser devtools.
+ contents: `\
+module.exports = Object.create(new Proxy({}, {
+ get(_, key) {
+ if (
+ key !== '__esModule' &&
+ key !== '__proto__' &&
+ key !== 'constructor' &&
+ key !== 'splice'
+ ) {
+ throw new Error(\`Module "${path}" has been externalized for browser compatibility. Cannot access "${path}.\${key}" in client code.\`)
+ }
}
-})`
+}))`
+ }
}
}
)
@@ -210,11 +268,20 @@ export function esbuildDepPlugin(
if (isRunningWithYarnPnp) {
build.onResolve(
{ filter: /.*/ },
- async ({ path, importer, kind, resolveDir }) => ({
- // pass along resolveDir for entries
- path: await resolve(path, importer, kind, resolveDir)
- })
+ async ({ path: id, importer, kind, resolveDir, namespace }) => {
+ const resolved = await resolve(
+ id,
+ importer,
+ kind,
+ // pass along resolveDir for entries
+ namespace === 'dep' ? resolveDir : undefined
+ )
+ if (resolved) {
+ return resolveResult(id, resolved)
+ }
+ }
)
+
build.onLoad({ filter: /.*/ }, async (args) => ({
contents: await fs.readFile(args.path),
loader: 'default'
diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts
index ea291675ccc8cf..b5e3f1d0b13565 100644
--- a/packages/vite/src/node/optimizer/index.ts
+++ b/packages/vite/src/node/optimizer/index.ts
@@ -45,11 +45,18 @@ export type ExportsData = {
export interface DepsOptimizer {
metadata: DepOptimizationMetadata
scanProcessing?: Promise
+
registerMissingImport: (id: string, resolved: string) => OptimizedDepInfo
run: () => void
+
isOptimizedDepFile: (id: string) => boolean
isOptimizedDepUrl: (url: string) => boolean
getOptimizedDepId: (depInfo: OptimizedDepInfo) => string
+
+ delayDepsOptimizerUntil: (id: string, done: () => Promise) => void
+ registerWorkersSource: (id: string) => void
+ resetRegisteredIds: () => void
+
options: DepOptimizationOptions
}
@@ -378,6 +385,7 @@ export async function runOptimizeDeps(
resolvedConfig: ResolvedConfig,
depsInfo: Record
): Promise {
+ const isBuild = resolvedConfig.command === 'build'
const config: ResolvedConfig = {
...resolvedConfig,
command: 'build'
@@ -464,20 +472,15 @@ export async function runOptimizeDeps(
flatIdToExports[flatId] = exportsData
}
- const define: Record = {
- 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || config.mode)
- }
- for (const key in config.define) {
- const value = config.define[key]
- define[key] = typeof value === 'string' ? value : JSON.stringify(value)
- }
-
const start = performance.now()
const result = await build({
absWorkingDir: process.cwd(),
entryPoints: Object.keys(flatIdDeps),
bundle: true,
+ // Ensure resolution is handled by esbuildDepPlugin and
+ // avoid replacing `process.env.NODE_ENV` for 'browser'
+ platform: 'neutral',
format: 'esm',
target: config.build.target || undefined,
external: config.optimizeDeps?.exclude,
@@ -485,9 +488,8 @@ export async function runOptimizeDeps(
splitting: true,
sourcemap: true,
outdir: processingCacheDir,
- ignoreAnnotations: resolvedConfig.command !== 'build',
+ ignoreAnnotations: !isBuild,
metafile: true,
- define,
plugins: [
...plugins,
esbuildDepPlugin(flatIdDeps, flatIdToExports, config)
@@ -613,7 +615,11 @@ export function getOptimizedDepPath(
function getDepsCacheSuffix(config: ResolvedConfig): string {
let suffix = ''
if (config.command === 'build') {
- suffix += '_build'
+ // Differentiate build caches depending on outDir to allow parallel builds
+ const { outDir } = config.build
+ const buildId =
+ outDir.length > 8 || outDir.includes('/') ? getHash(outDir) : outDir
+ suffix += `_build-${buildId}`
if (config.build.ssr) {
suffix += '_ssr'
}
@@ -880,7 +886,6 @@ export function getDepHash(config: ResolvedConfig): string {
{
mode: process.env.NODE_ENV || config.mode,
root: config.root,
- define: config.define,
resolve: config.resolve,
buildTarget: config.build.target,
assetsInclude: config.assetsInclude,
diff --git a/packages/vite/src/node/optimizer/optimizer.ts b/packages/vite/src/node/optimizer/optimizer.ts
index d1846903d95269..5dbccae6a73db3 100644
--- a/packages/vite/src/node/optimizer/optimizer.ts
+++ b/packages/vite/src/node/optimizer/optimizer.ts
@@ -1,6 +1,8 @@
import colors from 'picocolors'
import _debug from 'debug'
+import glob from 'fast-glob'
import { getHash } from '../utils'
+import { transformRequest } from '../server/transformRequest'
import type { ResolvedConfig, ViteDevServer } from '..'
import {
addOptimizedDepInfo,
@@ -65,6 +67,9 @@ export async function initDepsOptimizer(
isOptimizedDepUrl: createIsOptimizedDepUrl(config),
getOptimizedDepId: (depInfo: OptimizedDepInfo) =>
isBuild ? depInfo.file : `${depInfo.file}?v=${depInfo.browserHash}`,
+ registerWorkersSource,
+ delayDepsOptimizerUntil,
+ resetRegisteredIds,
options: config.optimizeDeps
}
@@ -101,8 +106,12 @@ export async function initDepsOptimizer(
let enqueuedRerun: (() => void) | undefined
let currentlyProcessing = false
+ // Only pretransform optimizeDeps.entries on cold start
+ let optimizeDepsEntriesVisited = !!cachedMetadata
+
// If there wasn't a cache or it is outdated, we need to prepare a first run
let firstRunCalled = !!cachedMetadata
+
if (!cachedMetadata) {
if (!scan) {
// Initialize discovered deps with manually added optimizeDeps.include info
@@ -126,9 +135,7 @@ export async function initDepsOptimizer(
setTimeout(async () => {
try {
- debug(colors.green(`scanning for dependencies...`), {
- timestamp: true
- })
+ debug(colors.green(`scanning for dependencies...`))
const { metadata } = depsOptimizer
@@ -148,10 +155,7 @@ export async function initDepsOptimizer(
debug(
colors.green(
`dependencies found: ${depsLogString(Object.keys(discovered))}`
- ),
- {
- timestamp: true
- }
+ )
)
scanPhaseProcessing.resolve()
@@ -316,9 +320,7 @@ export async function initDepsOptimizer(
logNewlyDiscoveredDeps()
}, 2 * debounceMs)
} else {
- debug(colors.green(`✨ optimized dependencies unchanged`), {
- timestamp: true
- })
+ debug(colors.green(`✨ optimized dependencies unchanged`))
}
} else {
if (newDepsDiscovered) {
@@ -331,10 +333,7 @@ export async function initDepsOptimizer(
debug(
colors.green(
`✨ delaying reload as new dependencies have been found...`
- ),
- {
- timestamp: true
- }
+ )
)
} else {
await commitProcessing()
@@ -403,9 +402,7 @@ export async function initDepsOptimizer(
// optimizeDeps processing is finished
const deps = Object.keys(depsOptimizer.metadata.discovered)
const depsString = depsLogString(deps)
- debug(colors.green(`new dependencies found: ${depsString}`), {
- timestamp: true
- })
+ debug(colors.green(`new dependencies found: ${depsString}`))
runOptimizer()
}
@@ -496,5 +493,91 @@ export async function initDepsOptimizer(
}, timeout)
}
+ const runOptimizerIfIdleAfterMs = 100
+
+ let registeredIds: { id: string; done: () => Promise }[] = []
+ let seenIds = new Set()
+ let workersSources = new Set()
+ let waitingOn: string | undefined
+
+ function resetRegisteredIds() {
+ registeredIds = []
+ seenIds = new Set()
+ workersSources = new Set()
+ waitingOn = undefined
+ }
+
+ function registerWorkersSource(id: string): void {
+ workersSources.add(id)
+ // Avoid waiting for this id, as it may be blocked by the rollup
+ // bundling process of the worker that also depends on the optimizer
+ registeredIds = registeredIds.filter((registered) => registered.id !== id)
+ if (waitingOn === id) {
+ waitingOn = undefined
+ runOptimizerWhenIdle()
+ }
+ }
+
+ function delayDepsOptimizerUntil(id: string, done: () => Promise): void {
+ if (!depsOptimizer.isOptimizedDepFile(id) && !seenIds.has(id)) {
+ seenIds.add(id)
+ registeredIds.push({ id, done })
+ runOptimizerWhenIdle()
+ }
+ if (server && !optimizeDepsEntriesVisited) {
+ optimizeDepsEntriesVisited = true
+ preTransformOptimizeDepsEntries(server)
+ }
+ }
+
+ function runOptimizerWhenIdle() {
+ if (!waitingOn) {
+ const next = registeredIds.pop()
+ if (next) {
+ waitingOn = next.id
+ const afterLoad = () => {
+ waitingOn = undefined
+ if (!workersSources.has(next.id)) {
+ if (registeredIds.length > 0) {
+ runOptimizerWhenIdle()
+ } else {
+ getDepsOptimizer(config)?.run()
+ }
+ }
+ }
+ next
+ .done()
+ .then(() => {
+ setTimeout(
+ afterLoad,
+ registeredIds.length > 0 ? 0 : runOptimizerIfIdleAfterMs
+ )
+ })
+ .catch(afterLoad)
+ }
+ }
+ }
+
return depsOptimizer
}
+
+export async function preTransformOptimizeDepsEntries(
+ server: ViteDevServer
+): Promise {
+ const { config } = server
+ const { entries } = config.optimizeDeps
+ if (entries) {
+ const explicitEntries = await glob(entries, {
+ cwd: config.root,
+ ignore: ['**/node_modules/**', `**/${config.build.outDir}/**`],
+ absolute: true
+ })
+ // TODO: should we restrict the entries to JS and HTML like the
+ // scanner did? I think we can let the user chose any entry
+ for (const entry of explicitEntries) {
+ transformRequest(entry, server, { ssr: false }).catch((e) => {
+ config.logger.error(e.message)
+ })
+ }
+ }
+}
diff --git a/packages/vite/src/node/packages.ts b/packages/vite/src/node/packages.ts
index 1fb2e7b4a21c06..e1c0c18eb5a119 100644
--- a/packages/vite/src/node/packages.ts
+++ b/packages/vite/src/node/packages.ts
@@ -1,7 +1,6 @@
import fs from 'fs'
import path from 'path'
-import { createFilter } from '@rollup/pluginutils'
-import { createDebugger, resolveFrom } from './utils'
+import { createDebugger, createFilter, resolveFrom } from './utils'
import type { ResolvedConfig } from './config'
import type { Plugin } from './plugin'
diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts
index 4c1bcfea0fd50b..2a119808a4eb72 100644
--- a/packages/vite/src/node/plugins/asset.ts
+++ b/packages/vite/src/node/plugins/asset.ts
@@ -23,6 +23,18 @@ const assetHashToFilenameMap = new WeakMap<
// save hashes of the files that has been emitted in build watch
const emittedHashMap = new WeakMap>()
+// add own dictionary entry by directly assigning mrmime
+export function registerCustomMime(): void {
+ // https://github.com/lukeed/mrmime/issues/3
+ mrmime.mimes['ico'] = 'image/x-icon'
+ // https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Containers#flac
+ mrmime.mimes['flac'] = 'audio/flac'
+ // mrmime and mime-db is not released yet: https://github.com/jshttp/mime-db/commit/c9242a9b7d4bb25d7a0c9244adec74aeef08d8a1
+ mrmime.mimes['aac'] = 'audio/aac'
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
+ mrmime.mimes['eot'] = 'application/vnd.ms-fontobject'
+}
+
/**
* Also supports loading plain strings with import text from './foo.txt?raw'
*/
@@ -31,9 +43,8 @@ export function assetPlugin(config: ResolvedConfig): Plugin {
assetHashToFilenameMap.set(config, new Map())
const relativeBase = isRelativeBase(config.base)
- // add own dictionary entry by directly assigning mrmine
- // https://github.com/lukeed/mrmime/issues/3
- mrmime.mimes['ico'] = 'image/x-icon'
+ registerCustomMime()
+
return {
name: 'vite:asset',
@@ -338,8 +349,9 @@ async function fileToBuiltUrl(
(!file.endsWith('.svg') &&
content.length < Number(config.build.assetsInlineLimit))
) {
+ const mimeType = mrmime.lookup(file) ?? 'application/octet-stream'
// base64 inlined as a string
- url = `data:${mrmime.lookup(file)};base64,${content.toString('base64')}`
+ url = `data:${mimeType};base64,${content.toString('base64')}`
} else {
// emit as asset
// rollup supports `import.meta.ROLLUP_FILE_URL_*`, but it generates code
@@ -353,11 +365,22 @@ async function fileToBuiltUrl(
const { search, hash } = parseUrl(id)
const postfix = (search || '') + (hash || '')
const output = config.build?.rollupOptions?.output
- const assetFileNames =
+
+ const defaultAssetFileNames = path.posix.join(
+ config.build.assetsDir,
+ '[name].[hash][extname]'
+ )
+ // Steps to determine which assetFileNames will be actually used.
+ // First, if output is an object or string, use assetFileNames in it.
+ // And a default assetFileNames as fallback.
+ let assetFileNames: Exclude =
(output && !Array.isArray(output) ? output.assetFileNames : undefined) ??
- // defaults to '/[name].[hash][extname]'
- // slightly different from rollup's one ('assets/[name]-[hash][extname]')
- path.posix.join(config.build.assetsDir, '[name].[hash][extname]')
+ defaultAssetFileNames
+ if (output && Array.isArray(output)) {
+ // Second, if output is an array, adopt assetFileNames in the first object.
+ assetFileNames = output[0].assetFileNames ?? assetFileNames
+ }
+
const fileName = assetFileNamesToFileName(
assetFileNames,
file,
diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts
index 1fa30f6a272ddd..45af9233bf4560 100644
--- a/packages/vite/src/node/plugins/css.ts
+++ b/packages/vite/src/node/plugins/css.ts
@@ -40,7 +40,8 @@ import {
isRelativeBase,
normalizePath,
parseRequest,
- processSrcSet
+ processSrcSet,
+ requireResolveFromRootWithFallback
} from '../utils'
import type { Logger } from '../logger'
import { addToHTMLProxyTransformResult } from './html'
@@ -837,15 +838,19 @@ async function compileCSS(
...postcssOptions,
to: id,
from: id,
- map: {
- inline: false,
- annotation: false,
- // postcss may return virtual files
- // we cannot obtain content of them, so this needs to be enabled
- sourcesContent: true
- // when "prev: preprocessorMap", the result map may include duplicate filename in `postcssResult.map.sources`
- // prev: preprocessorMap,
- }
+ ...(devSourcemap
+ ? {
+ map: {
+ inline: false,
+ annotation: false,
+ // postcss may return virtual files
+ // we cannot obtain content of them, so this needs to be enabled
+ sourcesContent: true
+ // when "prev: preprocessorMap", the result map may include duplicate filename in `postcssResult.map.sources`
+ // prev: preprocessorMap,
+ }
+ }
+ : {})
})
// record CSS dependencies from @imports
@@ -856,7 +861,9 @@ async function compileCSS(
// https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#3-dependencies
const { dir, glob: globPattern = '**' } = message
const pattern =
- normalizePath(path.resolve(path.dirname(id), dir)) + `/` + globPattern
+ glob.escapePath(normalizePath(path.resolve(path.dirname(id), dir))) +
+ `/` +
+ globPattern
const files = glob.sync(pattern, {
ignore: ['**/node_modules/**']
})
@@ -1292,10 +1299,7 @@ function loadPreprocessor(lang: PreprocessLang, root: string): any {
return loadedPreprocessors[lang]
}
try {
- // Search for the preprocessor in the root directory first, and fall back
- // to the default require paths.
- const fallbackPaths = _require.resolve.paths?.(lang) || []
- const resolved = _require.resolve(lang, { paths: [root, ...fallbackPaths] })
+ const resolved = requireResolveFromRootWithFallback(root, lang)
return (loadedPreprocessors[lang] = _require(resolved))
} catch (e) {
if (e.code === 'MODULE_NOT_FOUND') {
diff --git a/packages/vite/src/node/plugins/define.ts b/packages/vite/src/node/plugins/define.ts
index ca0f446cc1f58e..6edb1bd8858a11 100644
--- a/packages/vite/src/node/plugins/define.ts
+++ b/packages/vite/src/node/plugins/define.ts
@@ -10,15 +10,23 @@ const isNonJsRequest = (request: string): boolean => nonJsRe.test(request)
export function definePlugin(config: ResolvedConfig): Plugin {
const isBuild = config.command === 'build'
-
- const processNodeEnv: Record = {
- 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || config.mode),
- 'global.process.env.NODE_ENV': JSON.stringify(
- process.env.NODE_ENV || config.mode
- ),
- 'globalThis.process.env.NODE_ENV': JSON.stringify(
- process.env.NODE_ENV || config.mode
- )
+ const isBuildLib = isBuild && config.build.lib
+
+ // ignore replace process.env in lib build
+ const processEnv: Record = {}
+ const processNodeEnv: Record = {}
+ if (!isBuildLib) {
+ const nodeEnv = process.env.NODE_ENV || config.mode
+ Object.assign(processEnv, {
+ 'process.env.': `({}).`,
+ 'global.process.env.': `({}).`,
+ 'globalThis.process.env.': `({}).`
+ })
+ Object.assign(processNodeEnv, {
+ 'process.env.NODE_ENV': JSON.stringify(nodeEnv),
+ 'global.process.env.NODE_ENV': JSON.stringify(nodeEnv),
+ 'globalThis.process.env.NODE_ENV': JSON.stringify(nodeEnv)
+ })
}
const userDefine: Record = {}
@@ -27,7 +35,8 @@ export function definePlugin(config: ResolvedConfig): Plugin {
userDefine[key] = typeof val === 'string' ? val : JSON.stringify(val)
}
- // during dev, import.meta properties are handled by importAnalysis plugin
+ // during dev, import.meta properties are handled by importAnalysis plugin.
+ // ignore replace import.meta.env in lib build
const importMetaKeys: Record = {}
if (isBuild) {
const env: Record = {
@@ -47,22 +56,13 @@ export function definePlugin(config: ResolvedConfig): Plugin {
function generatePattern(
ssr: boolean
): [Record, RegExp | null] {
- const processEnv: Record = {}
- const isNeedProcessEnv = !ssr || config.ssr?.target === 'webworker'
-
- if (isNeedProcessEnv) {
- Object.assign(processEnv, {
- 'process.env.': `({}).`,
- 'global.process.env.': `({}).`,
- 'globalThis.process.env.': `({}).`
- })
- }
+ const replaceProcessEnv = !ssr || config.ssr?.target === 'webworker'
const replacements: Record = {
- ...(isNeedProcessEnv ? processNodeEnv : {}),
+ ...(replaceProcessEnv ? processNodeEnv : {}),
...userDefine,
...importMetaKeys,
- ...processEnv
+ ...(replaceProcessEnv ? processEnv : {})
}
const replacementsKeys = Object.keys(replacements)
diff --git a/packages/vite/src/node/plugins/dynamicImportVars.ts b/packages/vite/src/node/plugins/dynamicImportVars.ts
index b6047aa59e138d..ff20c5725dc341 100644
--- a/packages/vite/src/node/plugins/dynamicImportVars.ts
+++ b/packages/vite/src/node/plugins/dynamicImportVars.ts
@@ -3,11 +3,11 @@ import MagicString from 'magic-string'
import { init, parse as parseImports } from 'es-module-lexer'
import type { ImportSpecifier } from 'es-module-lexer'
import { parse as parseJS } from 'acorn'
-import { createFilter } from '@rollup/pluginutils'
import { dynamicImportToGlob } from '@rollup/plugin-dynamic-import-vars'
import type { Plugin } from '../plugin'
import type { ResolvedConfig } from '../config'
import {
+ createFilter,
normalizePath,
parseRequest,
requestQuerySplitRE,
diff --git a/packages/vite/src/node/plugins/esbuild.ts b/packages/vite/src/node/plugins/esbuild.ts
index 11f5ea4dd6cec0..c423edca92f9c1 100644
--- a/packages/vite/src/node/plugins/esbuild.ts
+++ b/packages/vite/src/node/plugins/esbuild.ts
@@ -9,13 +9,13 @@ import type {
import { transform } from 'esbuild'
import type { RawSourceMap } from '@ampproject/remapping'
import type { SourceMap } from 'rollup'
-import { createFilter } from '@rollup/pluginutils'
import type { TSConfckParseOptions, TSConfckParseResult } from 'tsconfck'
import { TSConfckParseError, findAll, parse } from 'tsconfck'
import {
cleanUrl,
combineSourcemaps,
createDebugger,
+ createFilter,
ensureWatchedFile,
generateCodeFrame,
toUpperCaseDriveLetter
diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts
index 9d06d6e168f2e1..a66a6288f8e8c2 100644
--- a/packages/vite/src/node/plugins/html.ts
+++ b/packages/vite/src/node/plugins/html.ts
@@ -767,11 +767,6 @@ export async function applyHtmlTransforms(
hooks: IndexHtmlTransformHook[],
ctx: IndexHtmlTransformContext
): Promise {
- const headTags: HtmlTagDescriptor[] = []
- const headPrependTags: HtmlTagDescriptor[] = []
- const bodyTags: HtmlTagDescriptor[] = []
- const bodyPrependTags: HtmlTagDescriptor[] = []
-
for (const hook of hooks) {
const res = await hook(html, ctx)
if (!res) {
@@ -787,6 +782,12 @@ export async function applyHtmlTransforms(
html = res.html || html
tags = res.tags
}
+
+ const headTags: HtmlTagDescriptor[] = []
+ const headPrependTags: HtmlTagDescriptor[] = []
+ const bodyTags: HtmlTagDescriptor[] = []
+ const bodyPrependTags: HtmlTagDescriptor[] = []
+
for (const tag of tags) {
if (tag.injectTo === 'body') {
bodyTags.push(tag)
@@ -798,21 +799,12 @@ export async function applyHtmlTransforms(
headPrependTags.push(tag)
}
}
- }
- }
- // inject tags
- if (headPrependTags.length) {
- html = injectToHead(html, headPrependTags, true)
- }
- if (headTags.length) {
- html = injectToHead(html, headTags)
- }
- if (bodyPrependTags.length) {
- html = injectToBody(html, bodyPrependTags, true)
- }
- if (bodyTags.length) {
- html = injectToBody(html, bodyTags)
+ html = injectToHead(html, headPrependTags, true)
+ html = injectToHead(html, headTags)
+ html = injectToBody(html, bodyPrependTags, true)
+ html = injectToBody(html, bodyTags)
+ }
}
return html
@@ -859,6 +851,8 @@ function injectToHead(
tags: HtmlTagDescriptor[],
prepend = false
) {
+ if (tags.length === 0) return html
+
if (prepend) {
// inject as the first element of head
if (headPrependInjectRE.test(html)) {
@@ -893,6 +887,8 @@ function injectToBody(
tags: HtmlTagDescriptor[],
prepend = false
) {
+ if (tags.length === 0) return html
+
if (prepend) {
// inject after body open
if (bodyPrependInjectRE.test(html)) {
diff --git a/packages/vite/src/node/plugins/importAnalysis.ts b/packages/vite/src/node/plugins/importAnalysis.ts
index ba221b4b1d5283..22797c1c0d8230 100644
--- a/packages/vite/src/node/plugins/importAnalysis.ts
+++ b/packages/vite/src/node/plugins/importAnalysis.ts
@@ -36,6 +36,7 @@ import {
normalizePath,
prettifyUrl,
removeImportQuery,
+ stripBomTag,
timeFrom,
transformResult,
unwrapId
@@ -55,9 +56,10 @@ import {
import { checkPublicFile } from './asset'
import {
ERR_OUTDATED_OPTIMIZED_DEP,
- delayDepsOptimizerUntil
+ throwOutdatedRequest
} from './optimizedDeps'
import { isCSSRequest, isDirectCSSRequest } from './css'
+import { browserExternalId } from './resolve'
const isDebug = !!process.env.DEBUG
const debug = createDebugger('vite:import-analysis')
@@ -141,10 +143,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
const start = performance.now()
await init
let imports: readonly ImportSpecifier[] = []
- // strip UTF-8 BOM
- if (source.charCodeAt(0) === 0xfeff) {
- source = source.slice(1)
- }
+ source = stripBomTag(source)
try {
imports = parseImports(source)[0]
} catch (e: any) {
@@ -169,10 +168,19 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
)
}
+ const depsOptimizer = getDepsOptimizer(config)
+
const { moduleGraph } = server
// since we are already in the transform phase of the importer, it must
// have been loaded so its entry is guaranteed in the module graph.
const importerModule = moduleGraph.getModuleById(importer)!
+ if (!importerModule && depsOptimizer?.isOptimizedDepFile(importer)) {
+ // Ids of optimized deps could be invalidated and removed from the graph
+ // Return without transforming, this request is no longer valid, a full reload
+ // is going to request this id again. Throwing an outdated error so we
+ // properly finish the request with a 504 sent to the browser.
+ throwOutdatedRequest(importer)
+ }
if (!imports.length) {
importerModule.isSelfAccepting = false
@@ -199,8 +207,6 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
const toAbsoluteUrl = (url: string) =>
path.posix.resolve(path.posix.dirname(importerModule.url), url)
- const depsOptimizer = getDepsOptimizer(config)
-
const normalizeUrl = async (
url: string,
pos: number
@@ -322,11 +328,9 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
s: start,
e: end,
ss: expStart,
- se: expEnd,
d: dynamicIndex,
// #2083 User may use escape path,
// so use imports[index].n to get the unescaped string
- // @ts-ignore
n: specifier
} = imports[index]
@@ -434,29 +438,20 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
}
} else if (needsInterop) {
debug(`${url} needs interop`)
- if (isDynamicImport) {
- // rewrite `import('package')` to expose the default directly
- str().overwrite(
- expStart,
- expEnd,
- `import('${url}').then(m => m.default && m.default.__esModule ? m.default : ({ ...m.default, default: m.default }))`,
- { contentOnly: true }
- )
- } else {
- const exp = source.slice(expStart, expEnd)
- const rewritten = transformCjsImport(exp, url, rawUrl, index)
- if (rewritten) {
- str().overwrite(expStart, expEnd, rewritten, {
- contentOnly: true
- })
- } else {
- // #1439 export * from '...'
- str().overwrite(start, end, url, { contentOnly: true })
- }
- }
+ interopNamedImports(str(), imports[index], url, index)
rewriteDone = true
}
}
+ // If source code imports builtin modules via named imports, the stub proxy export
+ // would fail as it's `export default` only. Apply interop for builtin modules to
+ // correctly throw the error message.
+ else if (
+ url.includes(browserExternalId) &&
+ source.slice(expStart, start).includes('{')
+ ) {
+ interopNamedImports(str(), imports[index], url, index)
+ rewriteDone = true
+ }
if (!rewriteDone) {
str().overwrite(start, end, isDynamicImport ? `'${url}'` : url, {
contentOnly: true
@@ -609,7 +604,9 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
)
// pre-transform known direct imports
- // TODO: we should also crawl dynamic imports
+ // TODO: should we also crawl dynamic imports? or the experience is good enough to allow
+ // users to chose their tradeoffs by explicitily setting optimizeDeps.entries for the
+ // most common dynamic imports
if (config.server.preTransformRequests && staticImportedUrls.size) {
staticImportedUrls.forEach(({ url, id }) => {
url = unwrapId(removeImportQuery(url)).replace(
@@ -624,8 +621,8 @@ 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)
+ if (depsOptimizer && !config.optimizeDeps.devScan) {
+ depsOptimizer.delayDepsOptimizerUntil(id, () => request)
}
})
}
@@ -639,6 +636,41 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
}
}
+export function interopNamedImports(
+ str: MagicString,
+ importSpecifier: ImportSpecifier,
+ rewrittenUrl: string,
+ importIndex: number
+): void {
+ const source = str.original
+ const {
+ s: start,
+ e: end,
+ ss: expStart,
+ se: expEnd,
+ d: dynamicIndex
+ } = importSpecifier
+ if (dynamicIndex > -1) {
+ // rewrite `import('package')` to expose the default directly
+ str.overwrite(
+ expStart,
+ expEnd,
+ `import('${rewrittenUrl}').then(m => m.default && m.default.__esModule ? m.default : ({ ...m.default, default: m.default }))`,
+ { contentOnly: true }
+ )
+ } else {
+ const exp = source.slice(expStart, expEnd)
+ const rawUrl = source.slice(start, end)
+ const rewritten = transformCjsImport(exp, rewrittenUrl, rawUrl, importIndex)
+ if (rewritten) {
+ str.overwrite(expStart, expEnd, rewritten, { contentOnly: true })
+ } else {
+ // #1439 export * from '...'
+ str.overwrite(start, end, rewrittenUrl, { contentOnly: true })
+ }
+ }
+}
+
type ImportNameSpecifier = { importedName: string; localName: string }
/**
diff --git a/packages/vite/src/node/plugins/importAnalysisBuild.ts b/packages/vite/src/node/plugins/importAnalysisBuild.ts
index 9de2e066624e2a..0895bf5cb8f8a4 100644
--- a/packages/vite/src/node/plugins/importAnalysisBuild.ts
+++ b/packages/vite/src/node/plugins/importAnalysisBuild.ts
@@ -19,7 +19,7 @@ import type { ResolvedConfig } from '../config'
import { genSourceMapUrl } from '../server/sourcemap'
import { getDepsOptimizer, optimizedDepNeedsInterop } from '../optimizer'
import { removedPureCssFilesCache } from './css'
-import { transformCjsImport } from './importAnalysis'
+import { interopNamedImports } from './importAnalysis'
/**
* A flag for injected helpers. This flag will be set to `false` if the output
@@ -283,31 +283,7 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
}
} else if (needsInterop) {
// config.logger.info(`${url} needs interop`)
- if (isDynamicImport) {
- // rewrite `import('package')` to expose the default directly
- str().overwrite(
- expStart,
- expEnd,
- `import('${file}').then(m => m.default && m.default.__esModule ? m.default : ({ ...m.default, default: m.default }))`,
- { contentOnly: true }
- )
- } else {
- const exp = source.slice(expStart, expEnd)
- const rewritten = transformCjsImport(
- exp,
- file,
- specifier,
- index
- )
- if (rewritten) {
- str().overwrite(expStart, expEnd, rewritten, {
- contentOnly: true
- })
- } else {
- // #1439 export * from '...'
- str().overwrite(start, end, file, { contentOnly: true })
- }
- }
+ interopNamedImports(str(), imports[index], url, index)
rewriteDone = true
}
if (!rewriteDone) {
diff --git a/packages/vite/src/node/plugins/json.ts b/packages/vite/src/node/plugins/json.ts
index 9c142501ff651e..216679a22148cd 100644
--- a/packages/vite/src/node/plugins/json.ts
+++ b/packages/vite/src/node/plugins/json.ts
@@ -9,6 +9,7 @@
import { dataToEsm } from '@rollup/pluginutils'
import { SPECIAL_QUERY_RE } from '../constants'
import type { Plugin } from '../plugin'
+import { stripBomTag } from '../utils'
export interface JsonOptions {
/**
@@ -43,6 +44,8 @@ export function jsonPlugin(
if (!jsonExtRE.test(id)) return null
if (SPECIAL_QUERY_RE.test(id)) return null
+ json = stripBomTag(json)
+
try {
if (options.stringify) {
if (isBuild) {
diff --git a/packages/vite/src/node/plugins/optimizedDeps.ts b/packages/vite/src/node/plugins/optimizedDeps.ts
index 49bcc69bf6f25e..b50294f9e64b9b 100644
--- a/packages/vite/src/node/plugins/optimizedDeps.ts
+++ b/packages/vite/src/node/plugins/optimizedDeps.ts
@@ -13,100 +13,10 @@ export const ERR_OUTDATED_OPTIMIZED_DEP = 'ERR_OUTDATED_OPTIMIZED_DEP'
const isDebug = process.env.DEBUG
const debug = createDebugger('vite:optimize-deps')
-const runOptimizerIfIdleAfterMs = 100
-
-interface RunProcessingInfo {
- ids: { id: string; done: () => Promise }[]
- seenIds: Set
- workersSources: Set
- waitingOn: string | undefined
-}
-
-const runProcessingInfoMap = new WeakMap()
-
-function initRunProcessingInfo(config: ResolvedConfig) {
- config = config.mainConfig || config
- const runProcessingInfo = {
- ids: [],
- seenIds: new Set(),
- workersSources: new Set(),
- waitingOn: undefined
- }
- runProcessingInfoMap.set(config, runProcessingInfo)
- return runProcessingInfo
-}
-
-function getRunProcessingInfo(config: ResolvedConfig): RunProcessingInfo {
- return (
- runProcessingInfoMap.get(config.mainConfig || config) ??
- initRunProcessingInfo(config)
- )
-}
-
-export function registerWorkersSource(
- config: ResolvedConfig,
- id: string
-): void {
- const info = getRunProcessingInfo(config)
- info.workersSources.add(id)
- if (info.waitingOn === id) {
- info.waitingOn = undefined
- }
-}
-
-export function delayDepsOptimizerUntil(
- config: ResolvedConfig,
- id: string,
- done: () => Promise
-): void {
- const info = getRunProcessingInfo(config)
- if (
- !getDepsOptimizer(config)?.isOptimizedDepFile(id) &&
- !info.seenIds.has(id)
- ) {
- info.seenIds.add(id)
- info.ids.push({ id, done })
- runOptimizerWhenIdle(config)
- }
-}
-
-function runOptimizerWhenIdle(config: ResolvedConfig) {
- const info = getRunProcessingInfo(config)
- if (!info.waitingOn) {
- const next = info.ids.pop()
- if (next) {
- info.waitingOn = next.id
- const afterLoad = () => {
- info.waitingOn = undefined
- if (info.ids.length > 0) {
- runOptimizerWhenIdle(config)
- } else if (!info.workersSources.has(next.id)) {
- getDepsOptimizer(config)?.run()
- }
- }
- next
- .done()
- .then(() => {
- setTimeout(
- afterLoad,
- info.ids.length > 0 ? 0 : runOptimizerIfIdleAfterMs
- )
- })
- .catch(afterLoad)
- }
- }
-}
-
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
@@ -174,7 +84,7 @@ export function optimizedDepsBuildPlugin(config: ResolvedConfig): Plugin {
buildStart() {
if (!config.isWorker) {
- initRunProcessingInfo(config)
+ getDepsOptimizer(config)?.resetRegisteredIds()
}
},
@@ -185,7 +95,7 @@ export function optimizedDepsBuildPlugin(config: ResolvedConfig): Plugin {
},
transform(_code, id) {
- delayDepsOptimizerUntil(config, id, async () => {
+ getDepsOptimizer(config)?.delayDepsOptimizerUntil(id, async () => {
await this.load({ id })
})
},
@@ -229,7 +139,7 @@ export function optimizedDepsBuildPlugin(config: ResolvedConfig): Plugin {
}
}
-function throwProcessingError(id: string) {
+function throwProcessingError(id: string): never {
const err: any = new Error(
`Something unexpected happened while optimizing "${id}". ` +
`The current page should have reloaded by now`
@@ -240,7 +150,7 @@ function throwProcessingError(id: string) {
throw err
}
-function throwOutdatedRequest(id: string) {
+export function throwOutdatedRequest(id: string): never {
const err: any = new Error(
`There is a new version of the pre-bundle for "${id}", ` +
`a page reload is going to ask for it.`
diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts
index 33a5ad31efe5b4..7ccc3a7eb5cb7a 100644
--- a/packages/vite/src/node/plugins/resolve.ts
+++ b/packages/vite/src/node/plugins/resolve.ts
@@ -339,15 +339,17 @@ export function resolvePlugin(baseOptions: InternalResolveOptions): Plugin {
load(id) {
if (id.startsWith(browserExternalId)) {
- return isProduction
- ? `export default {}`
- : `export default new Proxy({}, {
- get() {
- throw new Error('Module "${id.slice(
- browserExternalId.length + 1
- )}" has been externalized for browser compatibility and cannot be accessed in client code.')
+ if (isProduction) {
+ return `export default {}`
+ } else {
+ id = id.slice(browserExternalId.length + 1)
+ return `\
+export default new Proxy({}, {
+ get(_, key) {
+ throw new Error(\`Module "${id}" has been externalized for browser compatibility. Cannot access "${id}.\${key}" in client code.\`)
}
})`
+ }
}
}
}
diff --git a/packages/vite/src/node/plugins/terser.ts b/packages/vite/src/node/plugins/terser.ts
index 4e6b7b681a2cea..6362ca0b726fbf 100644
--- a/packages/vite/src/node/plugins/terser.ts
+++ b/packages/vite/src/node/plugins/terser.ts
@@ -1,26 +1,40 @@
-import { dirname } from 'path'
-import { fileURLToPath } from 'url'
import { Worker } from 'okie'
import type { Terser } from 'types/terser'
import type { Plugin } from '../plugin'
import type { ResolvedConfig } from '..'
+import { requireResolveFromRootWithFallback } from '../utils'
-// TODO: use import()
-const _dirname = dirname(fileURLToPath(import.meta.url))
+let terserPath: string | undefined
+const loadTerserPath = (root: string) => {
+ if (terserPath) return terserPath
+ try {
+ terserPath = requireResolveFromRootWithFallback(root, 'terser')
+ } catch (e) {
+ if (e.code === 'MODULE_NOT_FOUND') {
+ throw new Error(
+ 'terser not found. Since Vite v3, terser has become an optional dependency. You need to install it.'
+ )
+ } else {
+ const message = new Error(`terser failed to load:\n${e.message}`)
+ message.stack = e.stack + '\n' + message.stack
+ throw message
+ }
+ }
+ return terserPath
+}
export function terserPlugin(config: ResolvedConfig): Plugin {
const makeWorker = () =>
new Worker(
- async (basedir: string, code: string, options: Terser.MinifyOptions) => {
- // when vite is linked, the worker thread won't share the same resolve
- // root with vite itself, so we have to pass in the basedir and resolve
- // terser first.
- // eslint-disable-next-line node/no-restricted-require, no-restricted-globals
- const terserPath = require.resolve('terser', {
- paths: [basedir]
- })
- // eslint-disable-next-line no-restricted-globals
- return require(terserPath).minify(code, options) as Terser.MinifyOutput
+ async (
+ terserPath: string,
+ code: string,
+ options: Terser.MinifyOptions
+ ) => {
+ // test fails when using `import`. maybe related: https://github.com/nodejs/node/issues/43205
+ // eslint-disable-next-line no-restricted-globals -- this function runs inside cjs
+ const terser = require(terserPath)
+ return terser.minify(code, options) as Terser.MinifyOutput
}
)
@@ -50,7 +64,8 @@ export function terserPlugin(config: ResolvedConfig): Plugin {
// Lazy load worker.
worker ||= makeWorker()
- const res = await worker.run(_dirname, code, {
+ const terserPath = loadTerserPath(config.root)
+ const res = await worker.run(terserPath, code, {
safari10: true,
...config.build.terserOptions,
sourceMap: !!outputOptions.sourcemap,
diff --git a/packages/vite/src/node/plugins/wasm.ts b/packages/vite/src/node/plugins/wasm.ts
index 56aa56402df8e2..19bb9a0e541892 100644
--- a/packages/vite/src/node/plugins/wasm.ts
+++ b/packages/vite/src/node/plugins/wasm.ts
@@ -7,11 +7,21 @@ const wasmHelperId = '/__vite-wasm-helper'
const wasmHelper = async (opts = {}, url: string) => {
let result
if (url.startsWith('data:')) {
- // @ts-ignore
- const binaryString = atob(url.replace(/^data:.*?base64,/, ''))
- const bytes = new Uint8Array(binaryString.length)
- for (let i = 0; i < binaryString.length; i++) {
- bytes[i] = binaryString.charCodeAt(i)
+ const urlContent = url.replace(/^data:.*?base64,/, '')
+ let bytes
+ if (typeof Buffer === 'function' && typeof Buffer.from === 'function') {
+ bytes = Buffer.from(urlContent, 'base64')
+ } else if (typeof atob === 'function') {
+ // @ts-ignore
+ const binaryString = atob(urlContent)
+ bytes = new Uint8Array(binaryString.length)
+ for (let i = 0; i < binaryString.length; i++) {
+ bytes[i] = binaryString.charCodeAt(i)
+ }
+ } else {
+ throw new Error(
+ 'Failed to decode base64-encoded data URL, Buffer and atob are not supported'
+ )
}
// @ts-ignore
result = await WebAssembly.instantiate(bytes, opts)
diff --git a/packages/vite/src/node/plugins/worker.ts b/packages/vite/src/node/plugins/worker.ts
index 1e38a18f3dbdbe..848d118ba0eb64 100644
--- a/packages/vite/src/node/plugins/worker.ts
+++ b/packages/vite/src/node/plugins/worker.ts
@@ -13,8 +13,8 @@ import {
parseRequest
} from '../utils'
import { onRollupWarning } from '../build'
+import { getDepsOptimizer } from '../optimizer'
import { fileToUrl } from './asset'
-import { registerWorkersSource } from './optimizedDeps'
interface WorkerCache {
// save worker all emit chunk avoid rollup make the same asset unique.
@@ -269,7 +269,7 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
: 'module'
const workerOptions = workerType === 'classic' ? '' : ',{type: "module"}'
if (isBuild) {
- registerWorkersSource(config, id)
+ getDepsOptimizer(config)?.registerWorkersSource(id)
if (query.inline != null) {
const chunk = await bundleWorkerEntry(config, id, query)
// inline as blob data url
@@ -281,7 +281,7 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
export default function WorkerWrapper() {
const objURL = blob && (window.URL || window.webkitURL).createObjectURL(blob);
try {
- return objURL ? new ${workerConstructor}(objURL${workerOptions}) : new ${workerConstructor}("data:application/javascript;base64," + encodedJs${workerOptions});
+ return objURL ? new ${workerConstructor}(objURL) : new ${workerConstructor}("data:application/javascript;base64," + encodedJs${workerOptions});
} finally {
objURL && (window.URL || window.webkitURL).revokeObjectURL(objURL);
}
diff --git a/packages/vite/src/node/plugins/workerImportMetaUrl.ts b/packages/vite/src/node/plugins/workerImportMetaUrl.ts
index cfb10fdb2e8591..510ae644a1a11b 100644
--- a/packages/vite/src/node/plugins/workerImportMetaUrl.ts
+++ b/packages/vite/src/node/plugins/workerImportMetaUrl.ts
@@ -12,10 +12,10 @@ import {
parseRequest,
transformResult
} from '../utils'
+import { getDepsOptimizer } from '../optimizer'
import type { WorkerType } from './worker'
import { WORKER_FILE_ID, workerFileToUrl } from './worker'
import { fileToUrl } from './asset'
-import { registerWorkersSource } from './optimizedDeps'
const ignoreFlagRE = /\/\*\s*@vite-ignore\s*\*\//
@@ -123,7 +123,7 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
let url: string
if (isBuild) {
- registerWorkersSource(config, id)
+ getDepsOptimizer(config)?.registerWorkersSource(id)
url = await workerFileToUrl(config, file, query)
} else {
url = await fileToUrl(cleanUrl(file), config, this)
diff --git a/packages/vite/src/node/publicUtils.ts b/packages/vite/src/node/publicUtils.ts
index e24db763814dec..664b9375275403 100644
--- a/packages/vite/src/node/publicUtils.ts
+++ b/packages/vite/src/node/publicUtils.ts
@@ -3,11 +3,12 @@
* This file will be bundled to ESM and CJS and redirected by ../index.cjs
* Please control the side-effects by checking the ./dist/node-cjs/publicUtils.cjs bundle
*/
+export { VERSION as version } from './constants'
export {
splitVendorChunkPlugin,
splitVendorChunk
} from './plugins/splitVendorChunk'
-export { normalizePath, mergeConfig, mergeAlias } from './utils'
+export { normalizePath, mergeConfig, mergeAlias, createFilter } from './utils'
export { send } from './server/send'
export { createLogger } from './logger'
export { searchForWorkspaceRoot } from './server/searchRoot'
diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts
index 68c9f261f207b0..ed14fd27f70010 100644
--- a/packages/vite/src/node/server/index.ts
+++ b/packages/vite/src/node/server/index.ts
@@ -297,7 +297,6 @@ export async function createServer(
const container = await createPluginContainer(config, moduleGraph, watcher)
const closeHttpServer = createServerCloseFn(httpServer)
- // eslint-disable-next-line prefer-const
let exitProcess: () => void
const server: ViteDevServer = {
@@ -340,10 +339,11 @@ export async function createServer(
return startServer(server, port, isRestart)
},
async close() {
- process.off('SIGTERM', exitProcess)
-
- if (!middlewareMode && process.env.CI !== 'true') {
- process.stdin.off('end', exitProcess)
+ if (!middlewareMode) {
+ process.off('SIGTERM', exitProcess)
+ if (process.env.CI !== 'true') {
+ process.stdin.off('end', exitProcess)
+ }
}
await Promise.all([
@@ -380,18 +380,18 @@ export async function createServer(
server.transformIndexHtml = createDevHtmlTransformFn(server)
- exitProcess = async () => {
- try {
- await server.close()
- } finally {
- process.exit()
+ if (!middlewareMode) {
+ exitProcess = async () => {
+ try {
+ await server.close()
+ } finally {
+ process.exit()
+ }
+ }
+ process.once('SIGTERM', exitProcess)
+ if (process.env.CI !== 'true') {
+ process.stdin.on('end', exitProcess)
}
- }
-
- process.once('SIGTERM', exitProcess)
-
- if (!middlewareMode && process.env.CI !== 'true') {
- process.stdin.on('end', exitProcess)
}
const { packageCache } = config
@@ -475,7 +475,9 @@ export async function createServer(
// this applies before the transform middleware so that these files are served
// as-is without transforms.
if (config.publicDir) {
- middlewares.use(servePublicMiddleware(config.publicDir))
+ middlewares.use(
+ servePublicMiddleware(config.publicDir, config.server.headers)
+ )
}
// main transform middleware
diff --git a/packages/vite/src/node/server/middlewares/proxy.ts b/packages/vite/src/node/server/middlewares/proxy.ts
index 5c447435911ecd..9cd529a0dbba7b 100644
--- a/packages/vite/src/node/server/middlewares/proxy.ts
+++ b/packages/vite/src/node/server/middlewares/proxy.ts
@@ -43,11 +43,16 @@ export function proxyMiddleware(
}
const proxy = httpProxy.createProxyServer(opts) as HttpProxy.Server
- proxy.on('error', (err) => {
+ proxy.on('error', (err, req, res) => {
config.logger.error(`${colors.red(`http proxy error:`)}\n${err.stack}`, {
timestamp: true,
error: err
})
+ res
+ .writeHead(500, {
+ 'Content-Type': 'text/plain'
+ })
+ .end()
})
if (opts.configure) {
diff --git a/packages/vite/src/node/server/middlewares/static.ts b/packages/vite/src/node/server/middlewares/static.ts
index 5d4a948885baa3..3d0f453971803e 100644
--- a/packages/vite/src/node/server/middlewares/static.ts
+++ b/packages/vite/src/node/server/middlewares/static.ts
@@ -1,5 +1,5 @@
import path from 'path'
-import type { ServerResponse } from 'http'
+import type { OutgoingHttpHeaders, ServerResponse } from 'http'
import type { Options } from 'sirv'
import sirv from 'sirv'
import type { Connect } from 'types/connect'
@@ -20,24 +20,34 @@ import {
const { isMatch } = micromatch
-const sirvOptions: Options = {
- dev: true,
- etag: true,
- extensions: [],
- setHeaders(res, pathname) {
- // Matches js, jsx, ts, tsx.
- // The reason this is done, is that the .ts file extension is reserved
- // for the MIME type video/mp2t. In almost all cases, we can expect
- // these files to be TypeScript files, and for Vite to serve them with
- // this Content-Type.
- if (/\.[tj]sx?$/.test(pathname)) {
- res.setHeader('Content-Type', 'application/javascript')
+const sirvOptions = (headers?: OutgoingHttpHeaders): Options => {
+ return {
+ dev: true,
+ etag: true,
+ extensions: [],
+ setHeaders(res, pathname) {
+ // Matches js, jsx, ts, tsx.
+ // The reason this is done, is that the .ts file extension is reserved
+ // for the MIME type video/mp2t. In almost all cases, we can expect
+ // these files to be TypeScript files, and for Vite to serve them with
+ // this Content-Type.
+ if (/\.[tj]sx?$/.test(pathname)) {
+ res.setHeader('Content-Type', 'application/javascript')
+ }
+ if (headers) {
+ for (const name in headers) {
+ res.setHeader(name, headers[name]!)
+ }
+ }
}
}
}
-export function servePublicMiddleware(dir: string): Connect.NextHandleFunction {
- const serve = sirv(dir, sirvOptions)
+export function servePublicMiddleware(
+ dir: string,
+ headers?: OutgoingHttpHeaders
+): Connect.NextHandleFunction {
+ const serve = sirv(dir, sirvOptions(headers))
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
return function viteServePublicMiddleware(req, res, next) {
@@ -53,7 +63,7 @@ export function serveStaticMiddleware(
dir: string,
server: ViteDevServer
): Connect.NextHandleFunction {
- const serve = sirv(dir, sirvOptions)
+ const serve = sirv(dir, sirvOptions(server.config.server.headers))
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
return function viteServeStaticMiddleware(req, res, next) {
@@ -109,7 +119,7 @@ export function serveStaticMiddleware(
export function serveRawFsMiddleware(
server: ViteDevServer
): Connect.NextHandleFunction {
- const serveFromRoot = sirv('/', sirvOptions)
+ const serveFromRoot = sirv('/', sirvOptions(server.config.server.headers))
// Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
return function viteServeRawFsMiddleware(req, res, next) {
diff --git a/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts b/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts
index f759a51e60ff58..fbf7bb7bbd22ad 100644
--- a/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts
+++ b/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts
@@ -306,7 +306,7 @@ test('should declare variable for imported super class', async () => {
class A extends Foo {}
class B extends Foo {}
Object.defineProperty(__vite_ssr_exports__, \\"B\\", { enumerable: true, configurable: true, get(){ return B }});
- Object.defineProperty(__vite_ssr_exports__, \\"default\\", { enumerable: true, value: A });"
+ Object.defineProperty(__vite_ssr_exports__, \\"default\\", { enumerable: true, configurable: true, value: A });"
`)
})
@@ -338,7 +338,7 @@ test('should handle default export variants', async () => {
).toMatchInlineSnapshot(`
"function foo() {}
foo.prototype = Object.prototype;
- Object.defineProperty(__vite_ssr_exports__, \\"default\\", { enumerable: true, value: foo });"
+ Object.defineProperty(__vite_ssr_exports__, \\"default\\", { enumerable: true, configurable: true, value: foo });"
`)
// default named classes
expect(
@@ -353,7 +353,7 @@ test('should handle default export variants', async () => {
"class A {}
class B extends A {}
Object.defineProperty(__vite_ssr_exports__, \\"B\\", { enumerable: true, configurable: true, get(){ return B }});
- Object.defineProperty(__vite_ssr_exports__, \\"default\\", { enumerable: true, value: A });"
+ Object.defineProperty(__vite_ssr_exports__, \\"default\\", { enumerable: true, configurable: true, value: A });"
`)
})
diff --git a/packages/vite/src/node/ssr/index.ts b/packages/vite/src/node/ssr/index.ts
new file mode 100644
index 00000000000000..84f050ff8e41d4
--- /dev/null
+++ b/packages/vite/src/node/ssr/index.ts
@@ -0,0 +1,39 @@
+export type SSRTarget = 'node' | 'webworker'
+export type SSRFormat = 'esm' | 'cjs'
+
+export interface SSROptions {
+ external?: string[]
+ noExternal?: string | RegExp | (string | RegExp)[] | true
+ /**
+ * Define the target for the ssr build. The browser field in package.json
+ * is ignored for node but used if webworker is the target
+ * Default: 'node'
+ */
+ target?: SSRTarget
+ /**
+ * Define the format for the ssr build. Since Vite v3 the SSR build generates ESM by default.
+ * `'cjs'` can be selected to generate a CJS build, but it isn't recommended. This option is
+ * left marked as experimental to give users more time to update to ESM. CJS builds requires
+ * complex externalization heuristics that aren't present in the ESM format.
+ * @experimental
+ */
+ format?: SSRFormat
+}
+
+export interface ResolvedSSROptions extends SSROptions {
+ target: SSRTarget
+ format: SSRFormat
+}
+
+export function resolveSSROptions(
+ ssr: SSROptions | undefined
+): ResolvedSSROptions | undefined {
+ if (ssr === undefined) {
+ return undefined
+ }
+ return {
+ format: 'esm',
+ target: 'node',
+ ...ssr
+ }
+}
diff --git a/packages/vite/src/node/ssr/ssrExternal.ts b/packages/vite/src/node/ssr/ssrExternal.ts
index fbba0e735f7df1..de0dd5bab031e4 100644
--- a/packages/vite/src/node/ssr/ssrExternal.ts
+++ b/packages/vite/src/node/ssr/ssrExternal.ts
@@ -1,12 +1,12 @@
import fs from 'fs'
import path from 'path'
import { createRequire } from 'module'
-import { createFilter } from '@rollup/pluginutils'
import type { InternalResolveOptions } from '../plugins/resolve'
import { tryNodeResolve } from '../plugins/resolve'
import {
bareImportRE,
createDebugger,
+ createFilter,
isBuiltin,
isDefined,
lookupFile,
diff --git a/packages/vite/src/node/ssr/ssrTransform.ts b/packages/vite/src/node/ssr/ssrTransform.ts
index d7dc610cb82f47..e6f0d8b3a4562c 100644
--- a/packages/vite/src/node/ssr/ssrTransform.ts
+++ b/packages/vite/src/node/ssr/ssrTransform.ts
@@ -8,6 +8,8 @@ import type {
Node as _Node
} from 'estree'
import { extract_names as extractNames } from 'periscopic'
+// `eslint-plugin-node` doesn't support package without main
+// eslint-disable-next-line node/no-missing-import
import { walk as eswalk } from 'estree-walker'
import type { RawSourceMap } from '@ampproject/remapping'
import type { TransformResult } from '../server/transformRequest'
@@ -188,7 +190,7 @@ async function ssrTransformScript(
s.remove(node.start, node.start + 15 /* 'export default '.length */)
s.append(
`\nObject.defineProperty(${ssrModuleExportsKey}, "default", ` +
- `{ enumerable: true, value: ${name} });`
+ `{ enumerable: true, configurable: true, value: ${name} });`
)
} else {
// anonymous default exports
diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts
index 121505f566f6e9..c3c58696921dc9 100644
--- a/packages/vite/src/node/utils.ts
+++ b/packages/vite/src/node/utils.ts
@@ -16,16 +16,32 @@ import type { Alias, AliasOptions } from 'types/alias'
import type MagicString from 'magic-string'
import type { TransformResult } from 'rollup'
+import { createFilter as _createFilter } from '@rollup/pluginutils'
import {
CLIENT_ENTRY,
CLIENT_PUBLIC_PATH,
DEFAULT_EXTENSIONS,
ENV_PUBLIC_PATH,
FS_PREFIX,
- VALID_ID_PREFIX
+ VALID_ID_PREFIX,
+ wildcardHosts
} from './constants'
import type { ResolvedConfig } from '.'
+/**
+ * Inlined to keep `@rollup/pluginutils` in devDependencies
+ */
+export type FilterPattern =
+ | ReadonlyArray
+ | string
+ | RegExp
+ | null
+export const createFilter = _createFilter as (
+ include?: FilterPattern,
+ exclude?: FilterPattern,
+ options?: { resolve?: string | false | null }
+) => (id: string | unknown) => boolean
+
export function slash(p: string): string {
return p.replace(/\\/g, '/')
}
@@ -37,7 +53,10 @@ export function unwrapId(id: string): string {
}
export const flattenId = (id: string): string =>
- id.replace(/(\s*>\s*)/g, '__').replace(/[\/\.:]/g, '_')
+ id
+ .replace(/[\/:]/g, '_')
+ .replace(/[\.]/g, '__')
+ .replace(/(\s*>\s*)/g, '___')
export const normalizeId = (id: string): string =>
id.replace(/(\s*>\s*)/g, ' > ')
@@ -729,7 +748,7 @@ export function resolveHostname(
let host: string | undefined
if (optionsHost === undefined || optionsHost === false) {
// Use a secure default
- host = '127.0.0.1'
+ host = 'localhost'
} else if (optionsHost === true) {
// If passed --host in the CLI without arguments
host = undefined // undefined typically means 0.0.0.0 or :: (listen on all IPs)
@@ -737,14 +756,9 @@ export function resolveHostname(
host = optionsHost
}
- // Set host name to localhost when possible, unless the user explicitly asked for '127.0.0.1'
+ // Set host name to localhost when possible
const name =
- (optionsHost !== '127.0.0.1' && host === '127.0.0.1') ||
- host === '0.0.0.0' ||
- host === '::' ||
- host === undefined
- ? 'localhost'
- : host
+ host === undefined || wildcardHosts.has(host) ? 'localhost' : host
return { host, name }
}
@@ -791,6 +805,18 @@ export function getHash(text: Buffer | string): string {
return createHash('sha256').update(text).digest('hex').substring(0, 8)
}
+export const requireResolveFromRootWithFallback = (
+ root: string,
+ id: string
+): string => {
+ // Search in the root directory first, and fallback to the default require paths.
+ const fallbackPaths = _require.resolve.paths?.(id) || []
+ const path = _require.resolve(id, {
+ paths: [root, ...fallbackPaths]
+ })
+ return path
+}
+
// Based on node-graceful-fs
// The ISC License
@@ -988,3 +1014,12 @@ export function transformResult(
map: needSourceMap ? s.generateMap({ hires: true, source: id }) : null
}
}
+
+// strip UTF-8 BOM
+export function stripBomTag(content: string): string {
+ if (content.charCodeAt(0) === 0xfeff) {
+ return content.slice(1)
+ }
+
+ return content
+}
diff --git a/playground/alias/package.json b/playground/alias/package.json
index c9883422d785d4..ee345bf1f9ce13 100644
--- a/playground/alias/package.json
+++ b/playground/alias/package.json
@@ -10,7 +10,7 @@
},
"dependencies": {
"aliased-module": "file:./dir/module",
- "vue": "^3.2.36"
+ "vue": "^3.2.37"
},
"devDependencies": {
"resolve-linked": "workspace:*"
diff --git a/playground/assets/__tests__/assets.spec.ts b/playground/assets/__tests__/assets.spec.ts
index 20040c173c7f87..fda5e4e4c83ef1 100644
--- a/playground/assets/__tests__/assets.spec.ts
+++ b/playground/assets/__tests__/assets.spec.ts
@@ -218,6 +218,12 @@ describe('svg fragments', () => {
})
})
+test('Unknown extension assets import', async () => {
+ expect(await page.textContent('.unknown-ext')).toMatch(
+ isBuild ? 'data:application/octet-stream;' : '/nested/foo.unknown'
+ )
+})
+
test('?raw import', async () => {
expect(await page.textContent('.raw')).toMatch('SVG')
})
diff --git a/playground/assets/__tests__/relative-base/relative-base-assets.spec.ts b/playground/assets/__tests__/relative-base/relative-base-assets.spec.ts
index a09116c88a7ea6..828ece5ea27c5f 100644
--- a/playground/assets/__tests__/relative-base/relative-base-assets.spec.ts
+++ b/playground/assets/__tests__/relative-base/relative-base-assets.spec.ts
@@ -5,7 +5,8 @@ import {
getBg,
getColor,
isBuild,
- page
+ page,
+ viteConfig
} from '~utils'
const absoluteAssetMatch = isBuild
@@ -137,7 +138,8 @@ describe('css url() references', () => {
describe.runIf(isBuild)('index.css URLs', () => {
let css: string
beforeAll(() => {
- css = findAssetFile(/index.*\.css$/, '', 'other-assets')
+ const base = viteConfig ? viteConfig?.testConfig?.baseRoute : ''
+ css = findAssetFile(/index.*\.css$/, base, 'other-assets')
})
test('relative asset URL', () => {
diff --git a/playground/assets/index.html b/playground/assets/index.html
index 418cc06f05bcd1..a741379e82013e 100644
--- a/playground/assets/index.html
+++ b/playground/assets/index.html
@@ -166,6 +166,9 @@ SVG Fragments via JS Import
+Unknown extension assets import
+
+
?raw import
@@ -318,6 +321,9 @@ style in svg
text('.svg-frag-import-path', svgFrag)
document.querySelector('.svg-frag-import').src = svgFrag + '#icon-heart-view'
+ import unknownExtUrl from './nested/foo.unknown'
+ text('.unknown-ext', unknownExtUrl)
+
import rawSvg from './nested/fragment.svg?raw'
text('.raw', rawSvg)
diff --git a/playground/assets/nested/foo.unknown b/playground/assets/nested/foo.unknown
new file mode 100644
index 00000000000000..e24f83b664c55c
--- /dev/null
+++ b/playground/assets/nested/foo.unknown
@@ -0,0 +1 @@
+custom file
diff --git a/playground/assets/vite.config-relative-base.js b/playground/assets/vite.config-relative-base.js
index ba624964d3e0e3..ae09766c0768ac 100644
--- a/playground/assets/vite.config-relative-base.js
+++ b/playground/assets/vite.config-relative-base.js
@@ -8,7 +8,7 @@ module.exports = {
base: './', // relative base to make dist portable
build: {
...baseConfig.build,
- outDir: 'dist',
+ outDir: 'dist/relative-base',
watch: false,
minify: false,
assetsInlineLimit: 0,
@@ -19,5 +19,8 @@ module.exports = {
assetFileNames: 'other-assets/[name].[hash][extname]'
}
}
+ },
+ testConfig: {
+ baseRoute: '/relative-base/'
}
}
diff --git a/playground/assets/vite.config.js b/playground/assets/vite.config.js
index e44ddda7995185..c9d821ae3d73ee 100644
--- a/playground/assets/vite.config.js
+++ b/playground/assets/vite.config.js
@@ -11,6 +11,7 @@ module.exports = {
'@': path.resolve(__dirname, 'nested')
}
},
+ assetsInclude: ['**/*.unknown'],
build: {
outDir: 'dist/foo',
assetsInlineLimit: 8192, // 8kb
diff --git a/playground/backend-integration/__tests__/backend-integration.spec.ts b/playground/backend-integration/__tests__/backend-integration.spec.ts
index e8059c7d20f13c..314ccfb0582680 100644
--- a/playground/backend-integration/__tests__/backend-integration.spec.ts
+++ b/playground/backend-integration/__tests__/backend-integration.spec.ts
@@ -52,7 +52,7 @@ describe.runIf(isServe)('serve', () => {
await untilUpdated(() => getColor('body'), 'red') // successful HMR
// Verify that the base (/dev/) was added during the css-update
- const link = await page.$('link[rel="stylesheet"]')
+ const link = await page.$('link[rel="stylesheet"]:last-of-type')
expect(await link.getAttribute('href')).toContain('/dev/global.css?t=')
})
diff --git a/playground/backend-integration/package.json b/playground/backend-integration/package.json
index c1419548cb3bd3..a9c2b4f2bca63d 100644
--- a/playground/backend-integration/package.json
+++ b/playground/backend-integration/package.json
@@ -9,7 +9,7 @@
"preview": "vite preview"
},
"dependencies": {
- "tailwindcss": "^2.2.19"
+ "tailwindcss": "^3.1.2"
},
"devDependencies": {
"fast-glob": "^3.2.11"
diff --git a/playground/backend-integration/tailwind.config.js b/playground/backend-integration/tailwind.config.js
index 6e72a7e5d9d87b..0c3ae11de7565e 100644
--- a/playground/backend-integration/tailwind.config.js
+++ b/playground/backend-integration/tailwind.config.js
@@ -1,7 +1,5 @@
module.exports = {
- mode: 'jit',
- purge: [__dirname + '/frontend/**/*.{css,html,ts,js}'],
- darkMode: false, // or 'media' or 'class'
+ content: [__dirname + '/frontend/**/*.{css,html,ts,js}'],
theme: {
extend: {}
},
diff --git a/playground/cli-module/__tests__/serve.ts b/playground/cli-module/__tests__/serve.ts
index 5d40149300f6a5..698cbd048851d1 100644
--- a/playground/cli-module/__tests__/serve.ts
+++ b/playground/cli-module/__tests__/serve.ts
@@ -1,7 +1,7 @@
// this is automatically detected by playground/vitestSetup.ts and will replace
// the default e2e test serve behavior
-import execa from 'execa'
+import { execaCommand } from 'execa'
import kill from 'kill-port'
import {
isBuild,
@@ -45,7 +45,7 @@ export async function serve() {
if (isBuild) {
const buildCommand = `${viteBinPath} build`
try {
- const buildProcess = execa.command(buildCommand, {
+ const buildProcess = execaCommand(buildCommand, {
cwd: rootDir,
stdio: 'pipe'
})
@@ -67,7 +67,7 @@ export async function serve() {
viteServerArgs.unshift('preview')
}
const serverCommand = `${viteBinPath} ${viteServerArgs.join(' ')}`
- const serverProcess = execa.command(serverCommand, {
+ const serverProcess = execaCommand(serverCommand, {
cwd: rootDir,
stdio: 'pipe'
})
diff --git a/playground/cli/__tests__/serve.ts b/playground/cli/__tests__/serve.ts
index 6dbc05708d9cec..66f00677169f2a 100644
--- a/playground/cli/__tests__/serve.ts
+++ b/playground/cli/__tests__/serve.ts
@@ -1,7 +1,7 @@
// this is automatically detected by playground/vitestSetup.ts and will replace
// the default e2e test serve behavior
-import execa from 'execa'
+import { execaCommand } from 'execa'
import kill from 'kill-port'
import {
isBuild,
@@ -45,7 +45,7 @@ export async function serve() {
if (isBuild) {
const buildCommand = `${viteBinPath} build`
try {
- const buildProcess = execa.command(buildCommand, {
+ const buildProcess = execaCommand(buildCommand, {
cwd: rootDir,
stdio: 'pipe'
})
@@ -67,7 +67,7 @@ export async function serve() {
viteServerArgs.unshift('preview')
}
const serverCommand = `${viteBinPath} ${viteServerArgs.join(' ')}`
- const serverProcess = execa.command(serverCommand, {
+ const serverProcess = execaCommand(serverCommand, {
cwd: rootDir,
stdio: 'pipe'
})
diff --git a/playground/css-sourcemap/package.json b/playground/css-sourcemap/package.json
index f235b613e17922..f7a7d480c8ec22 100644
--- a/playground/css-sourcemap/package.json
+++ b/playground/css-sourcemap/package.json
@@ -9,9 +9,9 @@
"preview": "vite preview"
},
"devDependencies": {
- "less": "^4.1.2",
+ "less": "^4.1.3",
"magic-string": "^0.26.2",
- "sass": "^1.52.1",
- "stylus": "^0.58.0"
+ "sass": "^1.52.3",
+ "stylus": "^0.58.1"
}
}
diff --git a/playground/css/__tests__/css.spec.ts b/playground/css/__tests__/css.spec.ts
index e9d1fccac61d6e..564f0665bf0cea 100644
--- a/playground/css/__tests__/css.spec.ts
+++ b/playground/css/__tests__/css.spec.ts
@@ -317,9 +317,11 @@ test('treeshaken async chunk', async () => {
test('PostCSS dir-dependency', async () => {
const el1 = await page.$('.dir-dep')
const el2 = await page.$('.dir-dep-2')
+ const el3 = await page.$('.dir-dep-3')
expect(await getColor(el1)).toBe('grey')
expect(await getColor(el2)).toBe('grey')
+ expect(await getColor(el3)).toBe('grey')
if (!isBuild) {
editFile('glob-dep/foo.css', (code) =>
@@ -334,6 +336,13 @@ test('PostCSS dir-dependency', async () => {
await untilUpdated(() => getColor(el2), 'red')
expect(await getColor(el1)).toBe('blue')
+ editFile('glob-dep/nested (dir)/baz.css', (code) =>
+ code.replace('color: grey', 'color: green')
+ )
+ await untilUpdated(() => getColor(el3), 'green')
+ expect(await getColor(el1)).toBe('blue')
+ expect(await getColor(el2)).toBe('red')
+
// test add/remove
removeFile('glob-dep/bar.css')
await untilUpdated(() => getColor(el2), 'black')
diff --git a/playground/css/glob-dep/nested (dir)/baz.css b/playground/css/glob-dep/nested (dir)/baz.css
new file mode 100644
index 00000000000000..9a8b0f0ba47dc5
--- /dev/null
+++ b/playground/css/glob-dep/nested (dir)/baz.css
@@ -0,0 +1,3 @@
+.dir-dep-3 {
+ color: grey;
+}
diff --git a/playground/css/index.html b/playground/css/index.html
index 15e81192cec7f1..4310967b6ca65b 100644
--- a/playground/css/index.html
+++ b/playground/css/index.html
@@ -113,6 +113,9 @@ CSS
PostCSS dir-dependency (file 2): this should be grey too
+
+ PostCSS dir-dependency (file 3): this should be grey too
+
URL separation preservation: should have valid background-image
diff --git a/playground/css/package.json b/playground/css/package.json
index b83dcf384ad7e6..d78baa07c8d752 100644
--- a/playground/css/package.json
+++ b/playground/css/package.json
@@ -11,9 +11,9 @@
"devDependencies": {
"css-dep": "link:./css-dep",
"fast-glob": "^3.2.11",
- "less": "^4.1.2",
+ "less": "^4.1.3",
"postcss-nested": "^5.0.6",
- "sass": "^1.52.1",
- "stylus": "^0.58.0"
+ "sass": "^1.52.3",
+ "stylus": "^0.58.1"
}
}
diff --git a/playground/css/postcss-caching/css.spec.ts b/playground/css/postcss-caching/css.spec.ts
index bbffdb618280e4..45e8aadaa5489c 100644
--- a/playground/css/postcss-caching/css.spec.ts
+++ b/playground/css/postcss-caching/css.spec.ts
@@ -36,7 +36,7 @@ test('postcss config', async () => {
blueApp = null
greenApp = await startServer(greenAppDir)
- await page.goto(`http://localhost:${port}`)
+ await page.reload() // hmr reloads it automatically but reload here for consistency
const greenA = await page.$('.postcss-a')
expect(await getColor(greenA)).toBe('black')
const greenB = await page.$('.postcss-b')
diff --git a/playground/css/postcss.config.js b/playground/css/postcss.config.js
index 33058023541515..b30209bff42097 100644
--- a/playground/css/postcss.config.js
+++ b/playground/css/postcss.config.js
@@ -16,7 +16,7 @@ function testDirDep() {
AtRule(atRule, { result, Comment }) {
if (atRule.name === 'test') {
const pattern = normalizePath(
- path.resolve(path.dirname(result.opts.from), './glob-dep/*.css')
+ path.resolve(path.dirname(result.opts.from), './glob-dep/**/*.css')
)
const files = glob.sync(pattern)
const text = files.map((f) => fs.readFileSync(f, 'utf-8')).join('\n')
@@ -30,6 +30,14 @@ function testDirDep() {
glob: '*.css',
parent: result.opts.from
})
+
+ result.messages.push({
+ type: 'dir-dependency',
+ plugin: 'dir-dep',
+ dir: './glob-dep/nested (dir)', // includes special characters in glob
+ glob: '*.css',
+ parent: result.opts.from
+ })
}
}
}
diff --git a/playground/define/__tests__/define.spec.ts b/playground/define/__tests__/define.spec.ts
index 695d210a822ed6..76b1dfef5feb39 100644
--- a/playground/define/__tests__/define.spec.ts
+++ b/playground/define/__tests__/define.spec.ts
@@ -40,4 +40,7 @@ test('string', async () => {
// html would't need to define replacement
expect(await page.textContent('.exp-define')).toBe('__EXP__')
expect(await page.textContent('.import-json')).toBe('__EXP__')
+ expect(await page.textContent('.define-in-dep')).toBe(
+ defines.__STRINGIFIED_OBJ__
+ )
})
diff --git a/playground/define/commonjs-dep/index.js b/playground/define/commonjs-dep/index.js
new file mode 100644
index 00000000000000..23e0bf1b32e32f
--- /dev/null
+++ b/playground/define/commonjs-dep/index.js
@@ -0,0 +1 @@
+module.exports = { defined: __STRINGIFIED_OBJ__ }
diff --git a/playground/define/commonjs-dep/package.json b/playground/define/commonjs-dep/package.json
new file mode 100644
index 00000000000000..3047ae68c9f75a
--- /dev/null
+++ b/playground/define/commonjs-dep/package.json
@@ -0,0 +1,6 @@
+{
+ "name": "commonjs-dep",
+ "private": true,
+ "version": "1.0.0",
+ "type": "commonjs"
+}
diff --git a/playground/define/index.html b/playground/define/index.html
index 1260b119149d28..c4f4c598aba563 100644
--- a/playground/define/index.html
+++ b/playground/define/index.html
@@ -16,6 +16,7 @@
Define
no identifier substring:
define variable in html: __EXP__
import json:
+define in dep: