Skip to content

Commit 0780b41

Browse files
committed
v0.1.0
1 parent 1387d72 commit 0780b41

18 files changed

Lines changed: 473 additions & 0 deletions

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,13 @@ dist
102102

103103
# TernJS port file
104104
.tern-port
105+
106+
.DS_Store
107+
108+
package-lock.json
109+
pnpm-lock.yaml
110+
yarn.lock
111+
112+
/types
113+
/index.cjs
114+
/index.js

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
## 0.1.0 (2023-01-17)

README.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,68 @@
11
# vite-plugin-multiple
2+
23
Allow multiple Vite to run simultaneously.
4+
5+
[![NPM version](https://img.shields.io/npm/v/vite-plugin-multiple.svg)](https://npmjs.com/package/vite-plugin-multiple)
6+
[![NPM Downloads](https://img.shields.io/npm/dm/vite-plugin-multiple.svg)](https://npmjs.com/package/vite-plugin-multiple)
7+
8+
## Install
9+
10+
```sh
11+
npm i -D vite-plugin-multiple
12+
```
13+
14+
## Usage
15+
16+
```js
17+
import multiple from 'vite-plugin-multiple'
18+
19+
export default {
20+
plugins: [
21+
multiple([
22+
{
23+
name: 'foo',
24+
config: 'vite.foo.config.mjs',
25+
},
26+
{
27+
name: 'bar',
28+
config: 'vite.bar.config.mjs',
29+
},
30+
]),
31+
],
32+
}
33+
```
34+
35+
**`vite serve`**
36+
37+
- `http://localhost:5173` access to the **main** app
38+
- `http://localhost:5174` access to the **foo** app
39+
- `http://localhost:5175` access to the **bar** app
40+
41+
**`vite build`**
42+
43+
- `dist` **main** app
44+
- `dist/foo` **foo** app
45+
- `dist/bar` **bar** app
46+
47+
## API <sub><sup>(Define)</sup></sub>
48+
49+
```ts
50+
multiple(
51+
options: {
52+
/**
53+
* Human friendly name of your entry point.
54+
*/
55+
name: string
56+
/**
57+
* Vite config file path.
58+
*/
59+
config: string
60+
}[],
61+
args?: {
62+
/**
63+
* Called when all builds are complete.
64+
*/
65+
callback?: (command: 'build' | 'serve') => void
66+
},
67+
)
68+
```

package.json

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"name": "vite-plugin-multiple",
3+
"version": "0.1.0",
4+
"description": "Allow multiple Vite to run simultaneously",
5+
"type": "module",
6+
"main": "index.js",
7+
"types": "src",
8+
"exports": {
9+
".": {
10+
"import": "./index.js",
11+
"require": "./index.cjs"
12+
}
13+
},
14+
"repository": "https://github.com/vite-plugin/vite-plugin-multiple.git",
15+
"author": "草鞋没号 <308487730@qq.com>",
16+
"license": "MIT",
17+
"scripts": {
18+
"dev": "vite build --watch",
19+
"build": "vite build",
20+
"types": "tsc",
21+
"test": "vitest run",
22+
"prepublishOnly": "npm run test && npm run build"
23+
},
24+
"devDependencies": {
25+
"@types/node": "^18.11.18",
26+
"node-fetch": "^3.3.0",
27+
"typescript": "^4.9.4",
28+
"vite": "^4.0.4",
29+
"vitest": "^0.27.1"
30+
},
31+
"files": [
32+
"types",
33+
"index.cjs",
34+
"index.js"
35+
],
36+
"keywords": [
37+
"vite",
38+
"config",
39+
"multiple"
40+
]
41+
}

src/index.ts

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import path from 'node:path'
2+
import {
3+
type Plugin,
4+
type ResolvedConfig,
5+
type UserConfig,
6+
build as viteBuild,
7+
createServer,
8+
loadConfigFromFile,
9+
mergeConfig,
10+
} from 'vite'
11+
12+
export interface OptionItem {
13+
/**
14+
* Human friendly name of your entry point.
15+
*/
16+
name: string
17+
/**
18+
* Vite config file path.
19+
*/
20+
config: string
21+
}
22+
23+
export default function multiple(
24+
options: OptionItem[],
25+
args: {
26+
/**
27+
* Called when all builds are complete.
28+
*/
29+
callback?: (command: ResolvedConfig['command']) => void,
30+
} = {},
31+
): Plugin {
32+
let config: ResolvedConfig
33+
34+
return {
35+
name: 'vite-plugin-multiple',
36+
config(config) {
37+
config.clearScreen ??= false
38+
},
39+
async configResolved(_config) {
40+
config = _config
41+
},
42+
configureServer(server) {
43+
if (server.httpServer) {
44+
server.httpServer.once('listening', () => serve(config, options).then(() => args.callback?.('serve')))
45+
} else {
46+
serve(config, options).then(() => args.callback?.('serve'))
47+
}
48+
},
49+
async closeBundle() {
50+
if (config.command === 'build') {
51+
await build(config, options)
52+
args.callback?.(config.command)
53+
}
54+
},
55+
}
56+
}
57+
58+
export async function resolveConfig(config: ResolvedConfig, option: OptionItem): Promise<UserConfig> {
59+
const { config: userConfig } = (await loadConfigFromFile({
60+
command: config.command,
61+
mode: config.mode,
62+
ssrBuild: !!config.build?.ssr,
63+
}, option.config)) ?? { path: '', config: {}, dependencies: [] };
64+
const defaultConfig: UserConfig = {
65+
root: config.root,
66+
mode: config.mode,
67+
build: {
68+
outDir: !userConfig.root || config.root === userConfig.root
69+
? path.posix.join(config.build.outDir, option.name)
70+
: undefined,
71+
},
72+
clearScreen: false,
73+
}
74+
return mergeConfig(defaultConfig, userConfig);
75+
}
76+
77+
export async function build(config: ResolvedConfig, options: OptionItem[]) {
78+
for (const option of options) {
79+
const userConfig = await resolveConfig(config, option)
80+
await viteBuild({
81+
// 🚧 Avoid recursive build caused by load default config file.
82+
configFile: false,
83+
...userConfig,
84+
})
85+
}
86+
}
87+
88+
export async function serve(config: ResolvedConfig, options: OptionItem[]) {
89+
let port = 5174 // The port of main App is 5173
90+
for (const option of options) {
91+
const userConfig = await resolveConfig(config, option)
92+
93+
userConfig.server ??= {}
94+
userConfig.server.port ??= port++
95+
96+
const viteDevServer = await createServer({
97+
configFile: false,
98+
...userConfig,
99+
})
100+
await viteDevServer.listen()
101+
viteDevServer.printUrls()
102+
}
103+
}

test/build.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import fs from 'node:fs'
2+
import path from 'node:path'
3+
import { build as viteBuild } from 'vite'
4+
import {
5+
beforeAll,
6+
afterAll,
7+
expect,
8+
test,
9+
} from 'vitest'
10+
import multiple from '../src'
11+
12+
const root = path.join(__dirname, 'fixtures')
13+
14+
beforeAll(async () => {
15+
await viteBuild({
16+
configFile: path.join(root, 'vite.config.mjs'),
17+
plugins: [multiple([
18+
{
19+
name: 'foo',
20+
config: path.join(root, 'foo/vite.config.mjs'),
21+
},
22+
{
23+
name: 'bar',
24+
config: path.join(root, 'bar/vite.config.mjs'),
25+
},
26+
])],
27+
})
28+
})
29+
30+
test('build', async () => {
31+
const { message: main } = await import('./fixtures/dist/main'!)
32+
const { message: foo } = await import('./fixtures/foo/dist/main'!)
33+
const { message: bar } = await import('./fixtures/bar/dist/main'!)
34+
expect(main).eq('main')
35+
expect(foo).eq('foo')
36+
expect(bar).eq('bar')
37+
})
38+
39+
afterAll(() => {
40+
fs.rmSync(path.join(root, 'dist'), { recursive: true, force: true })
41+
fs.rmSync(path.join(root, 'foo/dist'), { recursive: true, force: true })
42+
fs.rmSync(path.join(root, 'bar/dist'), { recursive: true, force: true })
43+
})

test/fixtures/bar/index.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
</head>
6+
<body>
7+
<h1>bar</h1>
8+
</body>
9+
</html>

test/fixtures/bar/main.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const message = 'bar'

test/fixtures/bar/vite.config.mjs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { defineConfig } from 'vite'
2+
3+
export default defineConfig(({ command }) => {
4+
return command === 'build'
5+
? {
6+
build: {
7+
lib: {
8+
entry: 'main.ts',
9+
formats: ['es'],
10+
fileName: () => '[name].js',
11+
}
12+
},
13+
root: __dirname,
14+
}
15+
: {
16+
root: __dirname,
17+
}
18+
})

test/fixtures/foo/index.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
</head>
6+
<body>
7+
<h1>foo</h1>
8+
</body>
9+
</html>

0 commit comments

Comments
 (0)