Skip to content

Commit

Permalink
feat: build-in dev server proxy support
Browse files Browse the repository at this point in the history
close #147
  • Loading branch information
yyx990803 committed May 19, 2020
1 parent 3355bc8 commit dafaccb
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 20 deletions.
46 changes: 34 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ Vite assumes you are targeting modern browsers and therefore does not perform an
- [CSS Modules](#css-modules)
- [CSS Pre-processors](#css-pre-processors)
- [JSX](#jsx)
- [Config File](#config-file)
- [Dev Server Proxy](#dev-server-proxy)
- [Production Build](#production-build)

Vite tries to mirror the default configuration in [vue-cli](http://cli.vuejs.org/) as much as possible. If you've used `vue-cli` or other webpack-based boilerplates before, you should feel right at home. That said, do expect things to be different here and there.
Expand Down Expand Up @@ -222,6 +224,38 @@ ReactDOM.render(<h1>Hello, what!</h1>, document.getElementById('app'))

If you need a custom JSX pragma, JSX can also be customized via `--jsx-factory` and `--jsx-fragment` flags from the CLI or `jsx: { factory, fragment }` from the API. For example, you can run `vite --jsx-factory=h` to use `h` for JSX element creation calls.

### Config File

You can create a `vite.config.js` or `vite.config.ts` file in your project. Vite will automatically use it if one is found in the current working directory. You can also explicitly specify a config file via `vite --config my-config.js`.

In addition to options mapped from CLI flags, it also supports `alias`, `transforms`, and plugins (which is a subset of the config interface). For now, see [config.ts](https://github.com/vuejs/vite/blob/master/src/node/config.ts) for full details before more thorough documentation is available.

### Dev Server Proxy

> 0.15.6+
You can use the `proxy` option in the config file to configure custom proxies for the dev server. Vite uses [`koa-proxies`](https://github.com/vagusX/koa-proxies) which in turn uses [`http-proxy`](https://github.com/http-party/node-http-proxy). Each key can be a path Full options [here](https://github.com/http-party/node-http-proxy#options).

Example:

``` js
// vite.config.js
module.exports = {
proxy: {
proxy: {
// string shorthand
'/foo': 'http://localhost:4567/foo',
// with options
'/api': {
target: 'http://jsonplaceholder.typicode.com',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
}
}
}
}
```

### Production Build

Vite does utilize bundling for production builds, because native ES module imports result in waterfall network requests that are simply too punishing for page load time in production.
Expand All @@ -230,12 +264,6 @@ You can run `vite build` to bundle the app.

Internally, we use a highly opinionated Rollup config to generate the build. The build is configurable by passing on most options to Rollup - and most non-rollup string/boolean options have mapping flags in the CLI (see [build/index.ts](https://github.com/vuejs/vite/blob/master/src/node/build/index.ts) for full details).

## Config File

You can create a `vite.config.js` or `vite.config.ts` file in your project. Vite will automatically use it if one is found in the current working directory. You can also explicitly specify a config file via `vite --config my-config.js`.

In addition to options mapped from CLI flags, it also supports `alias`, `transforms`, and plugins (which is a subset of the config interface). For now, see [config.ts](https://github.com/vuejs/vite/blob/master/src/node/config.ts) for full details before more thorough documentation is available.

## API

### Dev Server
Expand Down Expand Up @@ -345,12 +373,6 @@ Snowpack 2 is closer to Vite in scope - both offer bundle-free dev servers and c

- While Vite can technically be used to develop apps with any framework, its main focus is to provide the best Vue development experience possible. 3rd party frameworks are supported, but not as the utmost priority.

## TODOs

- Config file support
- Define config options
- Define plugin format

## Trivia

[vite](https://en.wiktionary.org/wiki/vite) is the french word for "fast" and is pronounced `/vit/`.
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
"koa": "^2.11.0",
"koa-conditional-get": "^2.0.0",
"koa-etag": "^3.0.0",
"koa-proxies": "^0.11.0",
"koa-send": "^5.0.0",
"koa-static": "^5.0.0",
"lru-cache": "^5.1.1",
Expand Down
63 changes: 57 additions & 6 deletions src/node/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Rollup, {
} from 'rollup'
import { Transform } from './transform'
import { DepOptimizationOptions } from './depOptimizer'
import { IKoaProxiesOptions } from 'koa-proxies'

export { Resolver, Transform }

Expand All @@ -28,6 +29,16 @@ export interface SharedConfig {
root?: string
/**
* Import alias. Can only be exact mapping, does not support wildcard syntax.
*
* Example `vite.config.js`:
* ``` js
* module.exports = {
* alias: {
* 'react': '@pika/react',
* 'react-dom': '@pika/react-dom'
* }
* }
* ```
*/
alias?: Record<string, string>
/**
Expand All @@ -41,19 +52,26 @@ export interface SharedConfig {
resolvers?: Resolver[]
/**
* Configure dep optimization behavior.
*
* Example `vite.config.js`:
* ``` js
* module.exports = {
* optimizeDeps: {
* exclude: ['dep-a', 'dep-b']
* }
* }
* ```
*/
optimizeDeps?: DepOptimizationOptions
/**
* Options to pass to @vue/compiler-dom
* Options to pass to `@vue/compiler-dom`
*
* https://github.com/vuejs/vue-next/blob/master/packages/compiler-core/src/options.ts
*/
vueCompilerOptions?: CompilerOptions
/**
* Configure what to use for jsx factory and fragment.
* @default
* {
* factory: 'React.createElement',
* fragment: 'React.Fragment'
* }
* @default 'vue'
*/
jsx?:
| 'vue'
Expand All @@ -66,6 +84,32 @@ export interface SharedConfig {
}

export interface ServerConfig extends SharedConfig {
/**
* Configure custom proxy rules for the dev server. Uses
* [`koa-proxies`](https://github.com/vagusX/koa-proxies) which in turn uses
* [`http-proxy`](https://github.com/http-party/node-http-proxy). Each key can
* be a path Full options
* [here](https://github.com/http-party/node-http-proxy#options).
*
* Example `vite.config.js`:
* ``` js
* module.exports = {
* proxy: {
* proxy: {
* // string shorthand
* '/foo': 'http://localhost:4567/foo',
* // with options
* '/api': {
* target: 'http://jsonplaceholder.typicode.com',
* changeOrigin: true,
* rewrite: path => path.replace(/^\/api/, '')
* }
* }
* }
* }
* ```
*/
proxy?: Record<string, string | IKoaProxiesOptions>
/**
* Whether to use a Service Worker to cache served code. This can greatly
* improve full page reload performance, but requires a Service Worker
Expand All @@ -74,6 +118,10 @@ export interface ServerConfig extends SharedConfig {
* @default false
*/
serviceWorker?: boolean
/**
* Resolved server plugins.
* @internal
*/
plugins?: ServerPlugin[]
}

Expand Down Expand Up @@ -121,16 +169,19 @@ export interface BuildConfig extends SharedConfig {
// The following are API only and not documented in the CLI. -----------------
/**
* Will be passed to rollup.rollup()
*
* https://rollupjs.org/guide/en/#big-list-of-options
*/
rollupInputOptions?: RollupInputOptions
/**
* Will be passed to bundle.generate()
*
* https://rollupjs.org/guide/en/#big-list-of-options
*/
rollupOutputOptions?: RollupOutputOptions
/**
* Will be passed to rollup-plugin-vue
*
* https://github.com/vuejs/rollup-plugin-vue/blob/next/src/index.ts
*/
rollupPluginVueOptions?: Partial<RollupPluginVueOptions>
Expand Down
2 changes: 2 additions & 0 deletions src/node/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { esbuildPlugin } from './serverPluginEsbuild'
import { ServerConfig } from '../config'
import { createServerTransformPlugin } from '../transform'
import { serviceWorkerPlugin } from './serverPluginServiceWorker'
import { proxyPlugin } from './serverPluginProxy'

export { rewriteImports } from './serverPluginModuleRewrite'

Expand Down Expand Up @@ -56,6 +57,7 @@ export function createServer(config: ServerConfig = {}): Server {

const resolvedPlugins = [
...plugins,
proxyPlugin,
serviceWorkerPlugin,
hmrPlugin,
moduleRewritePlugin,
Expand Down
27 changes: 27 additions & 0 deletions src/node/server/serverPluginProxy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ServerPlugin } from '.'
import { URL } from 'url'

export const proxyPlugin: ServerPlugin = ({ app, config }) => {
if (!config.proxy) {
return
}

const debug = require('debug')('vite:proxy')
const proxy = require('koa-proxies')
const options = config.proxy
Object.keys(options).forEach((path) => {
let opts = options[path]
if (typeof opts === 'string') {
opts = { target: opts }
}
opts.logs = (ctx, target) => {
debug(
`${ctx.req.method} ${(ctx.req as any).oldPath} proxy to -> ${new URL(
ctx.req.url!,
target
)}`
)
}
app.use(proxy(path, opts))
})
}
Loading

0 comments on commit dafaccb

Please sign in to comment.