Skip to content

Commit

Permalink
Merge branch 'vitejs:main' into feat/ssr-import
Browse files Browse the repository at this point in the history
  • Loading branch information
natemoo-re authored Oct 15, 2021
2 parents 756f77c + 8ce2ea1 commit 9c6ab45
Show file tree
Hide file tree
Showing 37 changed files with 463 additions and 62 deletions.
30 changes: 29 additions & 1 deletion docs/config/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,23 @@ export default defineConfig(async ({ command, mode }) => {

When running Vite on Windows Subsystem for Linux (WSL) 2, if the project folder resides in a Windows filesystem, you'll need to set this option to `{ usePolling: true }`. This is due to [a WSL2 limitation](https://github.com/microsoft/WSL/issues/4739) with the Windows filesystem.

The Vite server watcher skips `.git/` and `node_modules/` directories by default. If you want to watch a package inside `node_modules/`, you can pass a negated glob pattern to `server.watch.ignored`. That is:

```js
export default defineConfig({
server: {
watch: {
ignored: ['!**/node_modules/your-package-name/**']
}
},
// The watched package must be excluded from optimization,
// so that it can appear in the dependency graph and trigger hot reload.
optimizeDeps: {
exclude: ['your-package-name']
}
})
```

### server.middlewareMode

- **Type:** `'ssr' | 'html'`
Expand Down Expand Up @@ -657,6 +674,17 @@ export default defineConfig({

If disabled, all CSS in the entire project will be extracted into a single CSS file.

### build.cssTarget

- **Type:** `string | string[]`
- **Default:** the same as [`build.target`](/config/#build-target)

This options allows users to set a different browser target for CSS minification from the one used for JavaScript transpilation.

It should only be used when you are targeting a non-mainstream browser.
One example is Android WeChat WebView, which supports most modern JavaScript features but not the [`#RGBA` hexadecimal color notation in CSS](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#rgb_colors).
In this case, you need to set `build.cssTarget` to `chrome61` to prevent vite from transform `rgba()` colors into `#RGBA` hexadecimal notations.

### build.sourcemap

- **Type:** `boolean | 'inline' | 'hidden'`
Expand Down Expand Up @@ -730,7 +758,7 @@ export default defineConfig({
- **Type:** `boolean`
- **Default:** `true` if `outDir` is inside `root`

By default, Vite will empty the `outDir` on build if it is inside project root. It will emit a warning if `outDir` is outside of root to avoid accidentially removing important files. You can explicitly set this option to suppress the warning. This is also available via command line as `--emptyOutDir`.
By default, Vite will empty the `outDir` on build if it is inside project root. It will emit a warning if `outDir` is outside of root to avoid accidentally removing important files. You can explicitly set this option to suppress the warning. This is also available via command line as `--emptyOutDir`.

### build.brotliSize

Expand Down
32 changes: 16 additions & 16 deletions docs/guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@ You can learn more about the rationale behind the project in the [Why Vite](./wh

- The default build targets browsers that support both [native ESM via script tags](https://caniuse.com/es6-module) and [native ESM dynamic import](https://caniuse.com/es6-module-dynamic-import). Legacy browsers can be supported via the official [@vitejs/plugin-legacy](https://github.com/vitejs/vite/tree/main/packages/plugin-legacy) - see the [Building for Production](./build) section for more details.

## Trying Vite Online

You can try Vite online on [StackBlitz](https://vite.new/). It runs the Vite-based build setup directly in the browser, so it is almost identical to the local setup but doesn't require installing anything on your machine. You can navigate to `vite.new/{template}` to select which framework to use.

The supported template presets are:

| JavaScript | TypeScript |
| :---: | :---: |
| [vanilla](https://vite.new/vanilla) | [vanilla-ts](https://vite.new/vanilla-ts) |
| [vue](https://vite.new/vue) | [vue-ts](https://vite.new/vue-ts) |
| [react](https://vite.new/react) | [react-ts](https://vite.new/react-ts) |
| [preact](https://vite.new/preact) | [preact-ts](https://vite.new/preact-ts) |
| [lit](https://vite.new/lit) | [lit-ts](https://vite.new/lit-ts) |
| [svelte](https://vite.new/svelte) | [svelte-ts](https://vite.new/svelte-ts) |

## Scaffolding Your First Vite Project

::: tip Compatibility Note
Expand Down Expand Up @@ -59,22 +74,7 @@ npm init vite@latest my-vue-app -- --template vue
yarn create vite my-vue-app --template vue
```

Supported template presets include:

- `vanilla`
- `vanilla-ts`
- `vue`
- `vue-ts`
- `react`
- `react-ts`
- `preact`
- `preact-ts`
- `lit`
- `lit-ts`
- `svelte`
- `svelte-ts`

See [create-vite](https://github.com/vitejs/vite/tree/main/packages/create-vite) for more details on each template.
See [create-vite](https://github.com/vitejs/vite/tree/main/packages/create-vite) for more details on each supported template: `vanilla`, `vanilla-ts`, `vue`, `vue-ts`, `react`, `react-ts`, `preact`, `preact-ts`, `lit`, `lit-ts`, `svelte`, `svelte-ts`.

## Community Templates

Expand Down
11 changes: 11 additions & 0 deletions packages/playground/css/__tests__/css.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,3 +338,14 @@ test('inlined', async () => {
// should not insert css
expect(await getColor('.inlined')).toBe('black')
})

test('minify css', async () => {
if (!isBuild) {
return
}

// should keep the rgba() syntax
const cssFile = findAssetFile(/index\.\w+\.css$/)
expect(cssFile).toMatch('rgba(')
expect(cssFile).not.toMatch('#ffff00b3')
})
2 changes: 2 additions & 0 deletions packages/playground/css/main.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import './minify.css'

import css from './imported.css'
text('.imported-css', css)

Expand Down
3 changes: 3 additions & 0 deletions packages/playground/css/minify.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.test-minify {
color: rgba(255, 255, 0, 0.7);
}
3 changes: 3 additions & 0 deletions packages/playground/css/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ const path = require('path')
* @type {import('vite').UserConfig}
*/
module.exports = {
build: {
cssTarget: 'chrome61'
},
resolve: {
alias: {
'@': __dirname
Expand Down
36 changes: 36 additions & 0 deletions packages/playground/ssr-html/__tests__/serve.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// @ts-check
// this is automtically detected by scripts/jestPerTestSetup.ts and will replace
// the default e2e test serve behavior

const path = require('path')

const port = (exports.port = 9530)

/**
* @param {string} root
* @param {boolean} isProd
*/
exports.serve = async function serve(root, isProd) {
const { createServer } = require(path.resolve(root, 'server.js'))
const { app, vite } = await createServer(root, isProd)

return new Promise((resolve, reject) => {
try {
const server = app.listen(port, () => {
resolve({
// for test teardown
async close() {
await new Promise((resolve) => {
server.close(resolve)
})
if (vite) {
await vite.close()
}
}
})
})
} catch (e) {
reject(e)
}
})
}
39 changes: 39 additions & 0 deletions packages/playground/ssr-html/__tests__/ssr-html.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { port } from './serve'
import fetch from 'node-fetch'

const url = `http://localhost:${port}`

describe('injected inline scripts', () => {
test('no injected inline scripts are present', async () => {
await page.goto(url)
const inlineScripts = await page.$$eval('script', (nodes) =>
nodes.filter((n) => !n.getAttribute('src') && n.innerHTML)
)
expect(inlineScripts).toHaveLength(0)
})

test('injected script proxied correctly', async () => {
await page.goto(url)
const proxiedScripts = await page.$$eval('script', (nodes) =>
nodes
.filter((n) => {
const src = n.getAttribute('src')
if (!src) return false
return src.includes('?html-proxy&index')
})
.map((n) => n.getAttribute('src'))
)

// assert at least 1 proxied script exists
expect(proxiedScripts).not.toHaveLength(0)

const scriptContents = await Promise.all(
proxiedScripts.map((src) => fetch(url + src).then((res) => res.text()))
)

// all proxied scripts return code
for (const code of scriptContents) {
expect(code).toBeTruthy()
}
})
})
11 changes: 11 additions & 0 deletions packages/playground/ssr-html/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SSR HTML</title>
</head>
<body>
<h1>SSR Dynamic HTML</h1>
</body>
</html>
15 changes: 15 additions & 0 deletions packages/playground/ssr-html/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "test-ssr-html",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "node server",
"serve": "cross-env NODE_ENV=production node server",
"debug": "node --inspect-brk server"
},
"dependencies": {},
"devDependencies": {
"cross-env": "^7.0.3",
"express": "^4.17.1"
}
}
75 changes: 75 additions & 0 deletions packages/playground/ssr-html/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// @ts-check
const fs = require('fs')
const path = require('path')
const express = require('express')

const isTest = process.env.NODE_ENV === 'test' || !!process.env.VITE_TEST_BUILD

const DYNAMIC_SCRIPTS = `
<script type="module">
const p = document.createElement('p');
p.innerHTML = '✅ Dynamically injected inline script';
document.body.appendChild(p);
</script>
<script type="module" src="/src/app.js"></script>
`

async function createServer(
root = process.cwd(),
isProd = process.env.NODE_ENV === 'production'
) {
const resolve = (p) => path.resolve(__dirname, p)

const app = express()

/**
* @type {import('vite').ViteDevServer}
*/
let vite
vite = await require('vite').createServer({
root,
logLevel: isTest ? 'error' : 'info',
server: {
middlewareMode: 'ssr',
watch: {
// During tests we edit the files too fast and sometimes chokidar
// misses change events, so enforce polling for consistency
usePolling: true,
interval: 100
}
}
})
// use vite's connect instance as middleware
app.use(vite.middlewares)

app.use('*', async (req, res) => {
try {
let [url] = req.originalUrl.split('?')
if (url.endsWith('/')) url += 'index.html'

const htmlLoc = resolve(`.${url}`)
let html = fs.readFileSync(htmlLoc, 'utf8')
html = html.replace('</body>', `${DYNAMIC_SCRIPTS}</body>`)
html = await vite.transformIndexHtml(url, html)

res.status(200).set({ 'Content-Type': 'text/html' }).end(html)
} catch (e) {
vite && vite.ssrFixStacktrace(e)
console.log(e.stack)
res.status(500).end(e.stack)
}
})

return { app, vite }
}

if (!isTest) {
createServer().then(({ app }) =>
app.listen(3000, () => {
console.log('http://localhost:3000')
})
)
}

// for test use
exports.createServer = createServer
3 changes: 3 additions & 0 deletions packages/playground/ssr-html/src/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const p = document.createElement('p')
p.innerHTML = '✅ Dynamically injected script from file'
document.body.appendChild(p)
5 changes: 5 additions & 0 deletions packages/playground/ssr-vue/__tests__/ssr-vue.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,8 @@ test('client navigation', async () => {
editFile('src/pages/About.vue', (code) => code.replace('About', 'changed'))
await untilUpdated(() => page.textContent('h1'), 'changed')
})

test('import.meta.url', async () => {
await page.goto(url)
expect(await page.textContent('.protocol')).toEqual('file:')
})
10 changes: 9 additions & 1 deletion packages/playground/ssr-vue/src/pages/Home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
<Foo />
<p class="virtual">msg from virtual module: {{ foo.msg }}</p>
<p class="inter">this will be styled with a font-face</p>
<p class="import-meta-url">{{ state.url }}</p>
<p class="protocol">{{ state.protocol }}</p>

<ImportType />
</template>
Expand All @@ -21,7 +23,13 @@ const Foo = defineAsyncComponent(() =>
function load(file) {
return defineAsyncComponent(() => import(`../components/${file}.vue`))
}
const state = reactive({ count: 0 })
const url = import.meta.env.SSR ? import.meta.url : document.querySelector('.import-meta-url').textContent
const protocol = new URL(url).protocol
const state = reactive({
count: 0,
protocol,
url
})
</script>

<style scoped>
Expand Down
9 changes: 9 additions & 0 deletions packages/plugin-legacy/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## [1.6.2](https://github.com/vitejs/vite/compare/plugin-legacy@1.6.1...plugin-legacy@1.6.2) (2021-10-11)


### Features

* add `build.cssTarget` option ([#5132](https://github.com/vitejs/vite/issues/5132)) ([b17444f](https://github.com/vitejs/vite/commit/b17444fd97b02bc54410c8575e7d3cb25e4058c2)), closes [#4746](https://github.com/vitejs/vite/issues/4746) [#5070](https://github.com/vitejs/vite/issues/5070) [#4930](https://github.com/vitejs/vite/issues/4930)



## [1.6.1](https://github.com/vitejs/vite/compare/plugin-legacy@1.6.0...plugin-legacy@1.6.1) (2021-10-05)


Expand Down
9 changes: 9 additions & 0 deletions packages/plugin-legacy/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ function viteLegacyPlugin(options = {}) {
if (!config.build) {
config.build = {}
}

if (!config.build.cssTarget) {
// Hint for esbuild that we are targeting legacy browsers when minifying CSS.
// Full CSS compat table available at https://github.com/evanw/esbuild/blob/78e04680228cf989bdd7d471e02bbc2c8d345dc9/internal/compat/css_table.go
// But note that only the `HexRGBA` feature affects the minify outcome.
// HSL & rebeccapurple values will be minified away regardless the target.
// So targeting `chrome61` suffices to fix the compatiblity issue.
config.build.cssTarget = 'chrome61'
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/plugin-legacy/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vitejs/plugin-legacy",
"version": "1.6.1",
"version": "1.6.2",
"license": "MIT",
"author": "Evan You",
"files": [
Expand Down
Loading

0 comments on commit 9c6ab45

Please sign in to comment.