diff --git a/.circleci/config.yml b/.circleci/config.yml
index 9335ce3054f0d8..74cb374c1c1640 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -7,8 +7,8 @@ defaults: &defaults
step_restore_cache: &restore_cache
restore_cache:
keys:
- - v1-dependencies-{{ checksum "yarn.lock" }}-1
- - v1-dependencies-
+ - v1-dependencies-{{ checksum "yarn.lock" }}-1
+ - v1-dependencies-
step_install_deps: &install_deps
run:
diff --git a/.eslintrc.js b/.eslintrc.js
index edf6be5da94729..f19c57faa15bbc 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,4 +1,7 @@
-module.exports = {
+// @ts-check
+const { defineConfig } = require('eslint-define-config')
+
+module.exports = defineConfig({
root: true,
extends: ['plugin:node/recommended'],
parser: '@typescript-eslint/parser',
@@ -51,7 +54,13 @@ module.exports = {
'node/no-unpublished-import': 'off',
'node/no-unpublished-require': 'off',
'node/no-unsupported-features/es-syntax': 'off',
- 'no-process-exit': 'off'
+ 'no-process-exit': 'off',
+ 'prefer-const': [
+ 'warn',
+ {
+ destructuring: 'all'
+ }
+ ]
},
overrides: [
{
@@ -74,4 +83,4 @@ module.exports = {
}
}
]
-}
+})
diff --git a/.github.amrom.workers.devmit-convention.md b/.github.amrom.workers.devmit-convention.md
index c66c7b9676ab3a..baa447479e9c39 100644
--- a/.github.amrom.workers.devmit-convention.md
+++ b/.github.amrom.workers.devmit-convention.md
@@ -6,7 +6,8 @@
Messages must be matched by the following regex:
-``` js
+
+```js
/^(revert: )?(feat|fix|docs|dx|refactor|perf|test|workflow|build|ci|chore|types|wip|release|deps)(\(.+\))?: .{1,50}/
```
@@ -44,7 +45,7 @@ This reverts commit 667ecc1654a317a13331b17617d973392f415f02.
### Full Message Format
-A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**:
+A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**:
```
():
@@ -74,9 +75,9 @@ The scope could be anything specifying the place of the commit change. For examp
The subject contains a succinct description of the change:
-* use the imperative, present tense: "change" not "changed" nor "changes"
-* don't capitalize the first letter
-* no dot (.) at the end
+- use the imperative, present tense: "change" not "changed" nor "changes"
+- don't capitalize the first letter
+- no dot (.) at the end
### Body
diff --git a/.github/contributing.md b/.github/contributing.md
index 60c348cd49c36c..49f528295e4e1d 100644
--- a/.github/contributing.md
+++ b/.github/contributing.md
@@ -12,8 +12,8 @@ To development and test the core `vite` package:
2. Run `yarn link` in `packages/vite`. This links `vite` globally so that you can:
- - Run `yarn link vite` in another Vite project to use the locally built Vite;
- - Use the `vite` binary anywhere.
+ - Run `yarn link vite` in another Vite project to use the locally built Vite;
+ - Use the `vite` binary anywhere.
## Running Tests
@@ -29,7 +29,7 @@ Each test can be run under either dev server mode or build mode.
- You can also use `yarn test-serve [match]` or `yarn test-build [match]` to run tests in a specific playground package, e.g. `yarn test-serve css` will run tests for both `playground/css` and `playground/css-codesplit` under serve mode.
- Note package matching is not aviable for the `yarn test` script, which always runs all tests.
+ Note package matching is not available for the `yarn test` script, which always runs all tests.
### Test Env and Helpers
@@ -43,6 +43,38 @@ test('should work', async () => {
Some common test helpers, e.g. `testDir`, `isBuild` or `editFile` are available in `packages/playground/testUtils.ts`.
+### Extending the Test Suite
+
+To add new tests, you should find a related playground to the fix or feature (or create a new one). As an example, static assets loading are tested in the [assets playground](https://github.com/vitejs/vite/tree/main/packages/playground/assets). In this Vite App, there is a test for `?raw` imports, with [a section is defined in the `index.html` for it](https://github.com/vitejs/vite/blob/71215533ac60e8ff566dc3467feabfc2c71a01e2/packages/playground/assets/index.html#L121):
+
+```html
+
?raw import
+
+```
+
+This will be modified [with the result of a file import](https://github.com/vitejs/vite/blob/71215533ac60e8ff566dc3467feabfc2c71a01e2/packages/playground/assets/index.html#L151):
+
+```js
+import rawSvg from './nested/fragment.svg?raw'
+text('.raw', rawSvg)
+```
+
+Where the `text` util is defined as:
+
+```js
+function text(el, text) {
+ document.querySelector(el).textContent = text
+}
+```
+
+In the [spec tests](https://github.com/vitejs/vite/blob/71215533ac60e8ff566dc3467feabfc2c71a01e2/packages/playground/assets/__tests__/assets.spec.ts#L180), the modifications to the DOM listed above are used to test this feature:
+
+```js
+test('?raw import', async () => {
+ expect(await page.textContent('.raw')).toMatch('SVG')
+})
+```
+
## Pull Request Guidelines
- Checkout a topic branch from a base branch, e.g. `main`, and merge back against that branch.
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000000000..d4d50aa18c34c9
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,93 @@
+name: CI
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+
+jobs:
+ build:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-latest]
+ node_version: [12, 14, 15]
+ include:
+ - os: macos-latest
+ node_version: 14
+ - os: windows-latest
+ node_version: 14
+ fail-fast: false
+
+ name: 'Build&Test: node-${{ matrix.node_version }}, ${{ matrix.os }}'
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Set node version to ${{ matrix.node_version }}
+ uses: actions/setup-node@v2
+ with:
+ node-version: ${{ matrix.node_version }}
+
+ - name: Get yarn cache directory
+ id: yarn-cache
+ run: echo "::set-output name=dir::$(yarn cache dir)"
+
+ - name: Set dependencies cache
+ uses: actions/cache@v2
+ with:
+ path: ${{ steps.yarn-cache.outputs.dir }}
+ key: ${{ runner.os }}-${{ matrix.node_version }}-${{ hashFiles('yarn.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-${{ matrix.node_version }}-${{ hashFiles('yarn.lock') }}
+ ${{ runner.os }}-${{ matrix.node_version }}-
+
+ - name: Versions
+ run: yarn versions
+
+ - name: Install dependencies
+ run: yarn install --frozen-lockfile
+
+ - name: Build vite
+ run: yarn build-vite
+
+ - name: Build plugin-vue
+ run: yarn build-plugin-vue
+
+ - name: Test serve
+ run: yarn test-serve --runInBand
+
+ - name: Test build
+ run: yarn test-build --runInBand
+
+ lint:
+ runs-on: ubuntu-latest
+ name: 'Lint: node-14, ubuntu-latest'
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+
+ - name: Set node version to 14
+ uses: actions/setup-node@v2
+ with:
+ node-version: 14
+
+ - name: Set dependencies cache
+ uses: actions/cache@v2
+ with:
+ path: ~/.cache/yarn
+ key: lint-dependencies-${{ hashFiles('yarn.lock') }}
+ restore-keys: |
+ lint-dependencies-${{ hashFiles('yarn.lock') }}
+ lint-dependencies-
+
+ - name: Prepare
+ run: |
+ yarn install --frozen-lockfile
+ yarn build-vite
+ yarn build-plugin-vue
+
+ - name: Lint
+ run: yarn lint
diff --git a/.github/workflows/issue-close-require.yml b/.github/workflows/issue-close-require.yml
index 058d89bbc26b98..244ae4e6297f01 100644
--- a/.github/workflows/issue-close-require.yml
+++ b/.github/workflows/issue-close-require.yml
@@ -2,7 +2,7 @@ name: Issue Close Require
on:
schedule:
- - cron: "0 0 * * *"
+ - cron: '0 0 * * *'
jobs:
close-issues:
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 00000000000000..ba0c80d22e344b
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,6 @@
+docs/.vitepress/dist/
+packages/vite/dist/
+packages/plugin-vue/dist/
+packages/*/CHANGELOG.md
+LICENSE.md
+.prettierrc
\ No newline at end of file
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index 3c78f4082d7a64..8c0ecf5ab85f8c 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe
## Enforcement
-Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team by DM at [Vite Land](chat.vitejs.dev). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team by DM at [Vite Land](https://chat.vitejs.dev). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
@@ -42,4 +42,4 @@ Project maintainers who do not follow or enforce the Code of Conduct in good fai
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
-[homepage]: https://www.contributor-covenant.org
\ No newline at end of file
+[homepage]: https://www.contributor-covenant.org
diff --git a/docs/.vitepress/theme/sponsors.css b/docs/.vitepress/theme/sponsors.css
index 2f30c1a888c540..bc0e9e1ca406ac 100644
--- a/docs/.vitepress/theme/sponsors.css
+++ b/docs/.vitepress/theme/sponsors.css
@@ -25,4 +25,4 @@
color: #999;
font-size: 1.2rem;
border: none;
-}
\ No newline at end of file
+}
diff --git a/docs/config/index.md b/docs/config/index.md
index e6526efb34af53..631c461b9c9c50 100644
--- a/docs/config/index.md
+++ b/docs/config/index.md
@@ -68,6 +68,19 @@ export default ({ command, mode }) => {
}
```
+### Async Config
+
+If the config needs to call async function, it can export a async function instead:
+
+```js
+export default async ({ command, mode }) => {
+ const data = await asyncFunction();
+ return {
+ // build specific config
+ }
+}
+```
+
## Shared Options
### root
@@ -105,12 +118,16 @@ export default ({ command, mode }) => {
- **Type:** `Record`
- Define global variable replacements. Entries will be defined as globals during dev and statically replaced during build.
+ Define global constant replacements. Entries will be defined as globals during dev and statically replaced during build.
- Starting from `2.0.0-beta.70`, string values will be used as raw expressions, so if defining a string constant, it needs to be explicitly quoted (e.g. with `JSON.stringify`).
- Replacements are performed only when the match is surrounded by word boundaries (`\b`).
+ Because it's implemented as straightforward text replacements without any syntax analyzation, we recommend using `define` for CONSTANTS only.
+
+ For example, `process.env.FOO` and `__APP_VERSION__` are good fits. But `process` or `global` should not be put into this option. Variables can be shimmed or polyfilled instead.
+
### plugins
- **Type:** ` (Plugin | Plugin[])[]`
@@ -364,7 +381,7 @@ export default ({ command, mode }) => {
target: 'http://jsonplaceholder.typicode.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
- }
+ },
// with RegEx
'^/fallback/.*': {
target: 'http://jsonplaceholder.typicode.com',
@@ -485,10 +502,10 @@ export default ({ command, mode }) => {
### build.lib
-- **Type:** `{ entry: string, name?: string, formats?: ('es' | 'cjs' | 'umd' | 'iife')[] }`
+- **Type:** `{ entry: string, name?: string, formats?: ('es' | 'cjs' | 'umd' | 'iife')[], fileName?: string }`
- **Related:** [Library Mode](/guide/build#library-mode)
- Build as a library. `entry` is required since the library cannot use HTML as entry. `name` is the exposed global variable and is required when `formats` includes `'umd'` or `'iife'`. Default `formats` are `['es', 'umd']`.
+ Build as a library. `entry` is required since the library cannot use HTML as entry. `name` is the exposed global variable and is required when `formats` includes `'umd'` or `'iife'`. Default `formats` are `['es', 'umd']`. `fileName` is the name of the package file output, default `fileName` is the name option of package.json
### build.manifest
@@ -544,6 +561,13 @@ export default ({ command, mode }) => {
- **Default:** `500`
Limit for chunk size warnings (in kbs).
+
+### build.watch
+
+- **Type:** [`WatcherOptions`](https://rollupjs.org/guide/en/#watch-options)`| null`
+- **Default:** `null`
+
+ Set to `{}` to enable rollup watcher. This is mostly used in cases that involve build-only plugins or integrations processes.
## Dep Optimization Options
diff --git a/docs/guide/api-hmr.md b/docs/guide/api-hmr.md
index cc58ebce612999..829c53a7f1ccc3 100644
--- a/docs/guide/api-hmr.md
+++ b/docs/guide/api-hmr.md
@@ -112,4 +112,4 @@ For now, calling `import.meta.hot.invalidate()` simply reloads the page.
## `hot.on(event, cb)`
-Listen to a custom HMR event. Custom HMR events can be sent from plugins. See [handleHotUpdate](./api-plugin#handlehotupdate) for more details.
\ No newline at end of file
+Listen to a custom HMR event. Custom HMR events can be sent from plugins. See [handleHotUpdate](./api-plugin#handlehotupdate) for more details.
diff --git a/docs/guide/api-javascript.md b/docs/guide/api-javascript.md
index 5673da95c7859f..f67f0592255865 100644
--- a/docs/guide/api-javascript.md
+++ b/docs/guide/api-javascript.md
@@ -33,40 +33,41 @@ const { createServer } = require('vite')
The `InlineConfig` interface extends `UserConfig` with additional properties:
- `configFile`: specify config file to use. If not set, Vite will try to automatically resolve one from project root. Set to `false` to disable auto resolving.
+- `envFile`: Set to `false` to disable `.env` files.
## `ViteDevServer`
```ts
interface ViteDevServer {
/**
- * The resolved vite config object
+ * The resolved vite config object.
*/
config: ResolvedConfig
/**
* A connect app instance
* - Can be used to attach custom middlewares to the dev server.
* - Can also be used as the handler function of a custom http server
- * or as a middleware in any connect-style Node.js frameworks
+ * or as a middleware in any connect-style Node.js frameworks.
*
* https://github.com/senchalabs/connect#use-middleware
*/
middlewares: Connect.Server
/**
- * native Node http server instance
- * will be null in middleware mode
+ * Native Node http server instance.
+ * Will be null in middleware mode.
*/
httpServer: http.Server | null
/**
- * chokidar watcher instance
+ * Chokidar watcher instance.
* https://github.com/paulmillr/chokidar#api
*/
watcher: FSWatcher
/**
- * web socket server with `send(payload)` method
+ * Web socket server with `send(payload)` method.
*/
ws: WebSocketServer
/**
- * Rollup plugin container that can run plugin hooks on a given file
+ * Rollup plugin container that can run plugin hooks on a given file.
*/
pluginContainer: PluginContainer
/**
@@ -104,7 +105,7 @@ interface ViteDevServer {
options?: { isolated?: boolean }
): Promise>
/**
- * Fix ssr error stacktrace
+ * Fix ssr error stacktrace.
*/
ssrFixStacktrace(e: Error): void
/**
diff --git a/docs/guide/api-plugin.md b/docs/guide/api-plugin.md
index 241031ef0a224e..dd96508d5307b8 100644
--- a/docs/guide/api-plugin.md
+++ b/docs/guide/api-plugin.md
@@ -189,8 +189,8 @@ Vite plugins can also provide hooks that serve Vite-specific purposes. These hoo
### `configResolved`
-- **Type:** `(config: ResolvedConfig) => void`
-- **Kind:** `sync`, `sequential`
+- **Type:** `(config: ResolvedConfig) => void | Promise`
+- **Kind:** `async`, `parallel`
Called after the Vite config is resolved. Use this hook to read and store the final resolved config. It is also useful when the plugin needs to do something different based the command is being run.
diff --git a/docs/guide/assets.md b/docs/guide/assets.md
index e76b642d08657f..a932c08dd6bc48 100644
--- a/docs/guide/assets.md
+++ b/docs/guide/assets.md
@@ -45,7 +45,7 @@ import shaderString from './shader.glsl?raw'
### Importing Script as a Worker
-Scripts can be imported as web workers with the `?worker` suffix.
+Scripts can be imported as web workers with the `?worker` suffix.
```js
// Separate chunk in the production build
diff --git a/docs/guide/backend-integration.md b/docs/guide/backend-integration.md
index 27d17ab1b05bb0..4669bd6c818dec 100644
--- a/docs/guide/backend-integration.md
+++ b/docs/guide/backend-integration.md
@@ -41,8 +41,8 @@ Or you can follow these steps to configure it manually:
```html
```
-
diff --git a/docs/guide/build.md b/docs/guide/build.md
index 0f8ea3f681f25e..5c6f45c46eb1b1 100644
--- a/docs/guide/build.md
+++ b/docs/guide/build.md
@@ -46,6 +46,21 @@ module.exports = {
For example, you can specify multiple Rollup outputs with plugins that are only applied during build.
+## Rebuild on files changes
+
+You can enable rollup watcher with `vite build --watch`. Or, you can directly adjust the underlying [`WatcherOptions`](https://rollupjs.org/guide/en/#watch-options) via `build.watch`:
+
+```js
+// vite.config.js
+module.exports = {
+ build: {
+ watch: {
+ // https://rollupjs.org/guide/en/#watch-options
+ }
+ }
+}
+```
+
## Multi-Page App
Suppose you have the following source code structure:
@@ -80,6 +95,8 @@ module.exports = {
}
```
+If you specify a different root, remember that `__dirname` will still be the folder of your vite.config.js file when resolving the input paths. Therfore, you will need to add your `root` entry to the arguments for `resolve`.
+
## Library Mode
When you are developing a browser-oriented library, you are likely spending most of the time on a test/demo page that imports your actual library. With Vite, you can use your `index.html` for that purpose to get the smooth development experience.
diff --git a/docs/guide/features.md b/docs/guide/features.md
index 70489d0e0115de..b9b343bad1ad1b 100644
--- a/docs/guide/features.md
+++ b/docs/guide/features.md
@@ -251,7 +251,7 @@ const modules = {
Note that:
- This is a Vite-only feature and is not a web or ES standard.
-- The glob patterns are treated like import specifiers: they must be either relative (start with `./`) or absolute (start with `/`, resolved relative to project root). Globbing from dependencies is not supported.
+- The glob patterns are treated like import specifiers: they must be either relative (start with `./`) or absolute (start with `/`, resolved relative to project root).
- The glob matching is done via `fast-glob` - check out its documentation for [supported glob patterns](https://github.com/mrmlnc/fast-glob#pattern-syntax).
## Web Assembly
diff --git a/docs/guide/static-deploy.md b/docs/guide/static-deploy.md
index 48dc91fe1a8b53..c5c53efda936a5 100644
--- a/docs/guide/static-deploy.md
+++ b/docs/guide/static-deploy.md
@@ -64,33 +64,33 @@ Now the `preview` method will launch the server at http://localhost:8080.
2. Inside your project, create `deploy.sh` with the following content (with highlighted lines uncommented appropriately), and run it to deploy:
-```bash{13,20,23}
-#!/usr/bin/env sh
+ ```bash{13,20,23}
+ #!/usr/bin/env sh
-# abort on errors
-set -e
+ # abort on errors
+ set -e
-# build
-npm run build
+ # build
+ npm run build
-# navigate into the build output directory
-cd dist
+ # navigate into the build output directory
+ cd dist
-# if you are deploying to a custom domain
-# echo 'www.example.com' > CNAME
+ # if you are deploying to a custom domain
+ # echo 'www.example.com' > CNAME
-git init
-git add -A
-git commit -m 'deploy'
+ git init
+ git add -A
+ git commit -m 'deploy'
-# if you are deploying to https://.github.io
-# git push -f git@github.com:/.github.io.git master
+ # if you are deploying to https://.github.io
+ # git push -f git@github.com:/.github.io.git master
-# if you are deploying to https://.github.io/
-# git push -f git@github.com:/.git master:gh-pages
+ # if you are deploying to https://.github.io/
+ # git push -f git@github.com:/.git master:gh-pages
-cd -
-```
+ cd -
+ ```
::: tip
You can also run the above script in your CI setup to enable automatic deployment on each push.
@@ -110,60 +110,60 @@ You can also run the above script in your CI setup to enable automatic deploymen
4. Use the GitHub Pages deploy provider template, and follow the [Travis CI documentation](https://docs.travis-ci.com/user/deployment/pages/).
-```yaml
-language: node_js
-node_js:
- - lts/*
-install:
- - npm ci
-script:
- - npm run build
-deploy:
- provider: pages
- skip_cleanup: true
- local_dir: dist
- # A token generated on GitHub allowing Travis to push code on you repository.
- # Set in the Travis settings page of your repository, as a secure variable.
- github_token: $GITHUB_TOKEN
- keep_history: true
- on:
- branch: master
-```
+ ```yaml
+ language: node_js
+ node_js:
+ - lts/*
+ install:
+ - npm ci
+ script:
+ - npm run build
+ deploy:
+ provider: pages
+ skip_cleanup: true
+ local_dir: dist
+ # A token generated on GitHub allowing Travis to push code on you repository.
+ # Set in the Travis settings page of your repository, as a secure variable.
+ github_token: $GITHUB_TOKEN
+ keep_history: true
+ on:
+ branch: master
+ ```
## GitLab Pages and GitLab CI
1. Set the correct `base` in `vite.config.js`.
- If you are deploying to `https://.gitlab.io/`, you can omit `base` as it defaults to `'/'`.
+ If you are deploying to `https://.gitlab.io/`, you can omit `base` as it defaults to `'/'`.
- If you are deploying to `https://.gitlab.io//`, for example your repository is at `https://gitlab.com//`, then set `base` to `'//'`.
+ If you are deploying to `https://.gitlab.io//`, for example your repository is at `https://gitlab.com//`, then set `base` to `'//'`.
2. Set `build.outDir` in `vite.config.js` to `public`.
3. Create a file called `.gitlab-ci.yml` in the root of your project with the content below. This will build and deploy your site whenever you make changes to your content:
-```yaml
-image: node:10.22.0
-pages:
- cache:
- paths:
- - node_modules/
- script:
- - npm install
- - npm run build
- artifacts:
- paths:
- - public
- only:
- - master
-```
+ ```yaml
+ image: node:10.22.0
+ pages:
+ cache:
+ paths:
+ - node_modules/
+ script:
+ - npm install
+ - npm run build
+ artifacts:
+ paths:
+ - public
+ only:
+ - master
+ ```
## Netlify
1. On [Netlify](https://netlify.com), setup up a new project from GitHub with the following settings:
-- **Build Command:** `vite build` or `npm run build`
-- **Publish directory:** `dist`
+ - **Build Command:** `vite build` or `npm run build`
+ - **Publish directory:** `dist`
2. Hit the deploy button.
@@ -173,26 +173,26 @@ pages:
2. Create `firebase.json` and `.firebaserc` at the root of your project with the following content:
- `firebase.json`:
+ `firebase.json`:
- ```json
- {
- "hosting": {
- "public": "dist",
- "ignore": []
- }
- }
- ```
+ ```json
+ {
+ "hosting": {
+ "public": "dist",
+ "ignore": []
+ }
+ }
+ ```
- `.firebaserc`:
+ `.firebaserc`:
- ```js
- {
- "projects": {
- "default": ""
+ ```js
+ {
+ "projects": {
+ "default": ""
+ }
}
- }
- ```
+ ```
3. After running `npm run build`, deploy using the command `firebase deploy`.
@@ -214,46 +214,46 @@ You can also deploy to a [custom domain](http://surge.sh/help/adding-a-custom-do
3. Run `heroku login` and fill in your Heroku credentials:
-```bash
-$ heroku login
-```
+ ```bash
+ $ heroku login
+ ```
4. Create a file called `static.json` in the root of your project with the below content:
-`static.json`:
+ `static.json`:
-```json
-{
- "root": "./dist"
-}
-```
+ ```json
+ {
+ "root": "./dist"
+ }
+ ```
-This is the configuration of your site; read more at [heroku-buildpack-static](https://github.com/heroku/heroku-buildpack-static).
+ This is the configuration of your site; read more at [heroku-buildpack-static](https://github.com/heroku/heroku-buildpack-static).
5. Set up your Heroku git remote:
-```bash
-# version change
-$ git init
-$ git add .
-$ git commit -m "My site ready for deployment."
+ ```bash
+ # version change
+ $ git init
+ $ git add .
+ $ git commit -m "My site ready for deployment."
-# creates a new app with a specified name
-$ heroku apps:create example
+ # creates a new app with a specified name
+ $ heroku apps:create example
-# set buildpack for static sites
-$ heroku buildpacks:set https://github.com/heroku/heroku-buildpack-static.git
-```
+ # set buildpack for static sites
+ $ heroku buildpacks:set https://github.com/heroku/heroku-buildpack-static.git
+ ```
6. Deploy your site:
-```bash
-# publish site
-$ git push heroku master
+ ```bash
+ # publish site
+ $ git push heroku master
-# opens a browser to view the Dashboard version of Heroku CI
-$ heroku open
-```
+ # opens a browser to view the Dashboard version of Heroku CI
+ $ heroku open
+ ```
## Vercel
diff --git a/docs/plugins/index.md b/docs/plugins/index.md
index 4a7c6e46df1819..647c9706e313de 100644
--- a/docs/plugins/index.md
+++ b/docs/plugins/index.md
@@ -28,4 +28,4 @@ Check out [awesome-vite](https://github.com/vitejs/awesome-vite#plugins) - you c
## Rollup Plugins
-[Vite plugins](../guide/api-plugin) are an extension of Rollup's plugin interface. Check out the [Rollup Plugin Compatibility section](../guide/api-plugin#rollup-plugin-compatibility) for more information.
\ No newline at end of file
+[Vite plugins](../guide/api-plugin) are an extension of Rollup's plugin interface. Check out the [Rollup Plugin Compatibility section](../guide/api-plugin#rollup-plugin-compatibility) for more information.
diff --git a/package.json b/package.json
index aabfb68ab88c71..9dd439477eb0a4 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
"cross-env": "^7.0.3",
"enquirer": "^2.3.6",
"eslint": "^7.15.0",
+ "eslint-define-config": "^1.0.3",
"eslint-plugin-node": "^11.1.0",
"execa": "^5.0.0",
"fs-extra": "^9.0.1",
diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md
index 89c02e044146d7..be51b5d1c42d49 100644
--- a/packages/create-app/CHANGELOG.md
+++ b/packages/create-app/CHANGELOG.md
@@ -1,3 +1,19 @@
+## [2.2.4](https://github.com/vitejs/vite/compare/create-app@2.2.3...create-app@2.2.4) (2021-04-15)
+
+
+### Bug Fixes
+
+* **create-app:** change index.html templates' favicon.svg href to absolute URL ([#2620](https://github.com/vitejs/vite/issues/2620)) ([3816f6e](https://github.com/vitejs/vite/commit/3816f6edb67e6bdf94db98e82e8acff4029bfe48))
+* **create-app:** the node in the svelte template is incorrectly mounted ([#2947](https://github.com/vitejs/vite/issues/2947)) ([0825f7e](https://github.com/vitejs/vite/commit/0825f7ee3574ae3f28f566da27835fbf3b210fac))
+
+
+### Features
+
+* **create-app:** add template vanilla-ts ([#2023](https://github.com/vitejs/vite/issues/2023)) ([89898d3](https://github.com/vitejs/vite/commit/89898d36cbe03bce9b6a7ab80a1c45de9989e56e))
+* **create-app:** two-level prompt for framework and variants ([#2941](https://github.com/vitejs/vite/issues/2941)) ([176e55d](https://github.com/vitejs/vite/commit/176e55dd1bf0232f483697d35b95f6e29a47fd74))
+
+
+
## [2.2.3](https://github.com/vitejs/vite/compare/create-app@2.2.2...create-app@2.2.3) (2021-03-31)
diff --git a/packages/create-app/README.md b/packages/create-app/README.md
index f3b4b76b598121..47e94c4c7c0d3e 100644
--- a/packages/create-app/README.md
+++ b/packages/create-app/README.md
@@ -35,6 +35,7 @@ yarn create @vitejs/app my-vue-app --template vue
Currently supported template presets include:
- `vanilla`
+- `vanilla-ts`
- `vue`
- `vue-ts`
- `react`
diff --git a/packages/create-app/index.js b/packages/create-app/index.js
index 4d5b7df838248a..e0548bec6b9949 100755
--- a/packages/create-app/index.js
+++ b/packages/create-app/index.js
@@ -4,33 +4,123 @@
const fs = require('fs')
const path = require('path')
const argv = require('minimist')(process.argv.slice(2))
+// eslint-disable-next-line node/no-restricted-require
const { prompt } = require('enquirer')
const {
yellow,
green,
cyan,
+ blue,
magenta,
lightRed,
- red,
- stripColors
+ red
} = require('kolorist')
const cwd = process.cwd()
-const TEMPLATES = [
- yellow('vanilla'),
- green('vue'),
- green('vue-ts'),
- cyan('react'),
- cyan('react-ts'),
- magenta('preact'),
- magenta('preact-ts'),
- lightRed('lit-element'),
- lightRed('lit-element-ts'),
- red('svelte'),
- red('svelte-ts')
+const FRAMEWORKS = [
+ {
+ name: 'vanilla',
+ color: yellow,
+ variants: [
+ {
+ name: 'vanilla',
+ display: 'JavaScript',
+ color: yellow
+ },
+ {
+ name: 'vanilla-ts',
+ display: 'TypeScript',
+ color: blue
+ }
+ ]
+ },
+ {
+ name: 'vue',
+ color: green,
+ variants: [
+ {
+ name: 'vue',
+ display: 'JavaScript',
+ color: yellow
+ },
+ {
+ name: 'vue-ts',
+ display: 'TypeScript',
+ color: blue
+ }
+ ]
+ },
+ {
+ name: 'react',
+ color: cyan,
+ variants: [
+ {
+ name: 'react',
+ display: 'JavaScript',
+ color: yellow
+ },
+ {
+ name: 'react-ts',
+ display: 'TypeScript',
+ color: blue
+ }
+ ]
+ },
+ {
+ name: 'preact',
+ color: magenta,
+ variants: [
+ {
+ name: 'preact',
+ display: 'JavaScript',
+ color: yellow
+ },
+ {
+ name: 'preact-ts',
+ display: 'TypeScript',
+ color: blue
+ }
+ ]
+ },
+ {
+ name: 'lit-element',
+ color: lightRed,
+ variants: [
+ {
+ name: 'lit-element',
+ display: 'JavaScript',
+ color: yellow
+ },
+ {
+ name: 'lit-element-ts',
+ display: 'TypeScript',
+ color: blue
+ }
+ ]
+ },
+ {
+ name: 'svelte',
+ color: red,
+ variants: [
+ {
+ name: 'svelte',
+ display: 'JavaScript',
+ color: yellow
+ },
+ {
+ name: 'svelte-ts',
+ display: 'TypeScript',
+ color: blue
+ }
+ ]
+ }
]
+const TEMPLATES = FRAMEWORKS.map(
+ (f) => (f.variants && f.variants.map((v) => v.name)) || [f.name]
+).reduce((a, b) => a.concat(b), [])
+
const renameFiles = {
_gitignore: '.gitignore'
}
@@ -51,7 +141,6 @@ async function init() {
}
const packageName = await getValidPackageName(targetDir)
const root = path.join(cwd, targetDir)
- console.log(`\nScaffolding project in ${root}...`)
if (!fs.existsSync(root)) {
fs.mkdirSync(root, { recursive: true })
@@ -79,29 +168,63 @@ async function init() {
// determine template
let template = argv.t || argv.template
- let message = 'Select a template:'
+ let message = 'Select a framework:'
let isValidTemplate = false
// --template expects a value
if (typeof template === 'string') {
- const availableTemplates = TEMPLATES.map(stripColors)
- isValidTemplate = availableTemplates.includes(template)
+ isValidTemplate = TEMPLATES.includes(template)
message = `${template} isn't a valid template. Please choose from below:`
}
if (!template || !isValidTemplate) {
/**
- * @type {{ t: string }}
+ * @type {{ framework: string }}
*/
- const { t } = await prompt({
+ const { framework } = await prompt({
type: 'select',
- name: 't',
+ name: 'framework',
message,
- choices: TEMPLATES
+ format(name) {
+ const framework = FRAMEWORKS.find((v) => v.name === name)
+ return framework
+ ? framework.color(framework.display || framework.name)
+ : name
+ },
+ choices: FRAMEWORKS.map((f) => ({
+ name: f.name,
+ value: f.name,
+ message: f.color(f.display || f.name)
+ }))
})
- template = stripColors(t)
+ const frameworkInfo = FRAMEWORKS.find((f) => f.name === framework)
+
+ if (frameworkInfo.variants) {
+ /**
+ * @type {{ name: string }}
+ */
+ const { name } = await prompt({
+ type: 'select',
+ name: 'name',
+ format(name) {
+ const variant = frameworkInfo.variants.find((v) => v.name === name)
+ return variant ? variant.color(variant.display || variant.name) : name
+ },
+ message: 'Select a variant:',
+ choices: frameworkInfo.variants.map((v) => ({
+ name: v.name,
+ value: v.name,
+ message: v.color(v.display || v.name)
+ }))
+ })
+ template = name
+ } else {
+ template = frameworkInfo.name
+ }
}
+ console.log(`\nScaffolding project in ${root}...`)
+
const templateDir = path.join(__dirname, `template-${template}`)
const write = (file, content) => {
diff --git a/packages/create-app/package.json b/packages/create-app/package.json
index 0436bf6c239b12..b1a84223ad8b1e 100644
--- a/packages/create-app/package.json
+++ b/packages/create-app/package.json
@@ -1,6 +1,6 @@
{
"name": "@vitejs/create-app",
- "version": "2.2.3",
+ "version": "2.2.4",
"license": "MIT",
"author": "Evan You",
"bin": {
diff --git a/packages/create-app/template-lit-element-ts/index.html b/packages/create-app/template-lit-element-ts/index.html
index 887b8ee9ad4c27..30bf7f9c81694e 100644
--- a/packages/create-app/template-lit-element-ts/index.html
+++ b/packages/create-app/template-lit-element-ts/index.html
@@ -2,7 +2,7 @@
-
+
Vite + Lit-Element App
diff --git a/packages/create-app/template-lit-element/index.html b/packages/create-app/template-lit-element/index.html
index 96eb1f95c57393..ad2c3e9ac596f8 100644
--- a/packages/create-app/template-lit-element/index.html
+++ b/packages/create-app/template-lit-element/index.html
@@ -2,7 +2,7 @@
-
+
Vite + Lit-Element App
diff --git a/packages/create-app/template-preact-ts/index.html b/packages/create-app/template-preact-ts/index.html
index a917605727d172..5dd45a1e2ab404 100644
--- a/packages/create-app/template-preact-ts/index.html
+++ b/packages/create-app/template-preact-ts/index.html
@@ -2,7 +2,7 @@
-
+
Vite App
diff --git a/packages/create-app/template-preact-ts/src/index.css b/packages/create-app/template-preact-ts/src/index.css
index b8c94dfb55e8d0..3d36f1648343ec 100644
--- a/packages/create-app/template-preact-ts/src/index.css
+++ b/packages/create-app/template-preact-ts/src/index.css
@@ -1,18 +1,19 @@
-html, body {
- height: 100%;
- width: 100%;
- padding: 0;
- margin: 0;
- background: #FAFAFA;
- font-family: 'Helvetica Neue', arial, sans-serif;
- font-weight: 400;
- color: #444;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
+html,
+body {
+ height: 100%;
+ width: 100%;
+ padding: 0;
+ margin: 0;
+ background: #fafafa;
+ font-family: 'Helvetica Neue', arial, sans-serif;
+ font-weight: 400;
+ color: #444;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
}
* {
- box-sizing: border-box;
+ box-sizing: border-box;
}
#app {
diff --git a/packages/create-app/template-preact/index.html b/packages/create-app/template-preact/index.html
index 87d9f988dde878..c06e9fce67a28f 100644
--- a/packages/create-app/template-preact/index.html
+++ b/packages/create-app/template-preact/index.html
@@ -2,7 +2,7 @@
-
+
Vite App
diff --git a/packages/create-app/template-preact/src/app.jsx b/packages/create-app/template-preact/src/app.jsx
index ae31e704597d4b..9d649444f686d9 100644
--- a/packages/create-app/template-preact/src/app.jsx
+++ b/packages/create-app/template-preact/src/app.jsx
@@ -17,4 +17,4 @@ export function App(props) {
+ @import from Stylus: This should be darkslateblue and have bg image which
+ url contains alias
+
+
+ Stylus import (relative path) via vite config preprocessor options: This
+ should be green
+
+
+ Stylus import (absolute path) via vite config preprocessor options: This
+ should be red
+
+
Imported Stylus string:
+
+
CSS modules: this should be turquoise
Imported CSS module:
@@ -54,6 +74,9 @@
CSS
@import dependency w/ sass enrtrypoints: this should be orange
+
+ @import dependency w/ styl enrtrypoints: this should be red
+
diff --git a/packages/playground/css/main.js b/packages/playground/css/main.js
index 0026e6305a2eb9..31b44b5552a8e5 100644
--- a/packages/playground/css/main.js
+++ b/packages/playground/css/main.js
@@ -7,6 +7,9 @@ text('.imported-sass', sass)
import less from './less.less'
text('.imported-less', less)
+import stylus from './stylus.styl'
+text('.imported-stylus', stylus)
+
import mod from './mod.module.css'
document.querySelector('.modules').classList.add(mod['apply-color'])
text('.modules-code', JSON.stringify(mod, null, 2))
diff --git a/packages/playground/css/nested/nested.styl b/packages/playground/css/nested/nested.styl
new file mode 100644
index 00000000000000..72e6f7a5074685
--- /dev/null
+++ b/packages/playground/css/nested/nested.styl
@@ -0,0 +1,6 @@
+.stylus-import
+ color darkslateblue
+
+.stylus-import-alias
+ color darkslateblue
+ background url('@/nested/icon.png') 10px no-repeat
diff --git a/packages/playground/css/options/absolute-import.styl b/packages/playground/css/options/absolute-import.styl
new file mode 100644
index 00000000000000..a057258d56c0c6
--- /dev/null
+++ b/packages/playground/css/options/absolute-import.styl
@@ -0,0 +1,3 @@
+.stylus-options-absolute-import
+ /* imported via vite.config.js */
+ color red
diff --git a/packages/playground/css/options/relative-import.styl b/packages/playground/css/options/relative-import.styl
new file mode 100644
index 00000000000000..157e0ea8d500eb
--- /dev/null
+++ b/packages/playground/css/options/relative-import.styl
@@ -0,0 +1,3 @@
+.stylus-options-relative-import
+ /* imported via vite.config.js */
+ color green
diff --git a/packages/playground/css/package.json b/packages/playground/css/package.json
index dedf35b5834fd0..e5cc96c39fe40d 100644
--- a/packages/playground/css/package.json
+++ b/packages/playground/css/package.json
@@ -9,9 +9,10 @@
"serve": "vite preview"
},
"devDependencies": {
+ "css-dep": "link:./css-dep",
"less": "^4.1.0",
"postcss-nested": "^5.0.3",
"sass": "^1.32.5",
- "css-dep": "link:./css-dep"
+ "stylus": "^0.54.8"
}
}
diff --git a/packages/playground/css/stylus.styl b/packages/playground/css/stylus.styl
new file mode 100644
index 00000000000000..7b77ca36531be8
--- /dev/null
+++ b/packages/playground/css/stylus.styl
@@ -0,0 +1,11 @@
+@import './nested/nested'
+@import 'css-dep'; // package w/ styl entry points
+
+$color ?= blue
+
+.stylus
+ color $color
+
+.stylus-additional-data
+ /* injected via vite.config.js */
+ color $injectedColor
diff --git a/packages/playground/css/vite.config.js b/packages/playground/css/vite.config.js
index 08b9eca9768a3f..5484342e3966a5 100644
--- a/packages/playground/css/vite.config.js
+++ b/packages/playground/css/vite.config.js
@@ -1,3 +1,4 @@
+const path = require('path')
/**
* @type {import('vite').UserConfig}
*/
@@ -32,6 +33,13 @@ module.exports = {
preprocessorOptions: {
scss: {
additionalData: `$injectedColor: orange;`
+ },
+ styl: {
+ additionalData: `$injectedColor ?= orange`,
+ imports: [
+ './options/relative-import.styl',
+ path.join(__dirname, 'options/absolute-import.styl')
+ ]
}
}
}
diff --git a/packages/playground/data-uri/package.json b/packages/playground/data-uri/package.json
index 54912c035d44e7..7f5cabc688332e 100644
--- a/packages/playground/data-uri/package.json
+++ b/packages/playground/data-uri/package.json
@@ -8,4 +8,4 @@
"debug": "node --inspect-brk ../../vite/bin/vite",
"serve": "vite preview"
}
-}
\ No newline at end of file
+}
diff --git a/packages/playground/dynamic-import/__tests__/dynamic-import.spec.ts b/packages/playground/dynamic-import/__tests__/dynamic-import.spec.ts
index 32333059ad7381..292cdb2e861b4b 100644
--- a/packages/playground/dynamic-import/__tests__/dynamic-import.spec.ts
+++ b/packages/playground/dynamic-import/__tests__/dynamic-import.spec.ts
@@ -20,6 +20,22 @@ test('should load data URL of `data:`', async () => {
await untilUpdated(() => page.textContent('.view'), 'data', true)
})
+test('should have same reference on static and dynamic js import', async () => {
+ await page.click('.mxd')
+ await untilUpdated(() => page.textContent('.view'), 'true', true)
+})
+
+// in this case, it is not possible to detect the correct module
+test('should have same reference on static and dynamic js import', async () => {
+ await page.click('.mxd2')
+ await untilUpdated(() => page.textContent('.view'), 'false', true)
+})
+
+test('should have same reference on static and dynamic js import', async () => {
+ await page.click('.mxdjson')
+ await untilUpdated(() => page.textContent('.view'), 'true', true)
+})
+
// since this test has a timeout, it should be put last so that it
// does not bleed on the last
test('should load dynamic import with vars', async () => {
diff --git a/packages/playground/dynamic-import/index.html b/packages/playground/dynamic-import/index.html
index 87bb6ebdaa37e8..3039d9eadf3c00 100644
--- a/packages/playground/dynamic-import/index.html
+++ b/packages/playground/dynamic-import/index.html
@@ -2,6 +2,9 @@
+
+
+
diff --git a/packages/playground/dynamic-import/mxd.js b/packages/playground/dynamic-import/mxd.js
new file mode 100644
index 00000000000000..ea9b101e1c2259
--- /dev/null
+++ b/packages/playground/dynamic-import/mxd.js
@@ -0,0 +1 @@
+export default function () {}
diff --git a/packages/playground/dynamic-import/mxd.json b/packages/playground/dynamic-import/mxd.json
new file mode 100644
index 00000000000000..9e26dfeeb6e641
--- /dev/null
+++ b/packages/playground/dynamic-import/mxd.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/packages/playground/dynamic-import/nested/index.js b/packages/playground/dynamic-import/nested/index.js
index cc6522016fc1d8..48a7cb7f924c38 100644
--- a/packages/playground/dynamic-import/nested/index.js
+++ b/packages/playground/dynamic-import/nested/index.js
@@ -1,3 +1,6 @@
+import mxdStatic from '../mxd'
+import mxdStaticJSON from '../mxd.json'
+
async function setView(view) {
const { msg } = await import(`../views/${view}.js`)
text('.view', msg)
@@ -21,6 +24,27 @@ document.querySelector('.qux').addEventListener('click', async () => {
text('.view', msg)
})
+// mixed static and dynamic
+document.querySelector('.mxd').addEventListener('click', async () => {
+ const view = 'mxd'
+ const { default: mxdDynamic } = await import(`../${view}.js`)
+ text('.view', mxdStatic === mxdDynamic)
+})
+
+document.querySelector('.mxd2').addEventListener('click', async () => {
+ const test = { jss: '../mxd.js' }
+ const ttest = test
+ const view = 'mxd'
+ const { default: mxdDynamic } = await import(test.jss)
+ text('.view', mxdStatic === mxdDynamic)
+})
+
+document.querySelector('.mxdjson').addEventListener('click', async () => {
+ const view = 'mxd'
+ const { default: mxdDynamicJSON } = await import(`../${view}.json`)
+ text('.view', mxdStaticJSON === mxdDynamicJSON)
+})
+
// data URLs (`blob:`)
const code1 = 'export const msg = "blob"'
const blob = new Blob([code1], { type: 'text/javascript;charset=UTF-8' })
diff --git a/packages/playground/dynamic-import/vite.config.js b/packages/playground/dynamic-import/vite.config.js
index e0fb1f662fd3d0..010e47d6308d30 100644
--- a/packages/playground/dynamic-import/vite.config.js
+++ b/packages/playground/dynamic-import/vite.config.js
@@ -10,6 +10,14 @@ module.exports = {
path.resolve(__dirname, 'qux.js'),
path.resolve(__dirname, 'dist/qux.js')
)
+ fs.copyFileSync(
+ path.resolve(__dirname, 'mxd.js'),
+ path.resolve(__dirname, 'dist/mxd.js')
+ )
+ fs.copyFileSync(
+ path.resolve(__dirname, 'mxd.json'),
+ path.resolve(__dirname, 'dist/mxd.json')
+ )
}
}
]
diff --git a/packages/playground/glob-import/dir/baz.json b/packages/playground/glob-import/dir/baz.json
index ef46606326191e..e8677dc6e2dae3 100644
--- a/packages/playground/glob-import/dir/baz.json
+++ b/packages/playground/glob-import/dir/baz.json
@@ -1,3 +1,3 @@
{
"msg": "baz"
-}
\ No newline at end of file
+}
diff --git a/packages/playground/optimize-deps/dep-linked-include/Test.vue b/packages/playground/optimize-deps/dep-linked-include/Test.vue
index ca11049b3e883b..0f5052cb6a8853 100644
--- a/packages/playground/optimize-deps/dep-linked-include/Test.vue
+++ b/packages/playground/optimize-deps/dep-linked-include/Test.vue
@@ -1 +1 @@
-[success] rendered from Vue
\ No newline at end of file
+[success] rendered from Vue
diff --git a/packages/playground/optimize-deps/dep-linked-include/test.css b/packages/playground/optimize-deps/dep-linked-include/test.css
index b719c608467fdd..60f1eab97137f7 100644
--- a/packages/playground/optimize-deps/dep-linked-include/test.css
+++ b/packages/playground/optimize-deps/dep-linked-include/test.css
@@ -1,3 +1,3 @@
body {
color: red;
-}
\ No newline at end of file
+}
diff --git a/packages/playground/react/App.jsx b/packages/playground/react/App.jsx
index ef0ee76f43fcc5..1de7461b163776 100644
--- a/packages/playground/react/App.jsx
+++ b/packages/playground/react/App.jsx
@@ -7,7 +7,9 @@ function App() {
Hello Vite + React
-
+
Edit App.jsx and save to test HMR updates.
diff --git a/packages/playground/resolve-linked/package.json b/packages/playground/resolve-linked/package.json
index 68263fb725c4c8..8042ce78119b8f 100644
--- a/packages/playground/resolve-linked/package.json
+++ b/packages/playground/resolve-linked/package.json
@@ -3,4 +3,4 @@
"version": "0.0.0",
"private": true,
"main": "src/index.js"
-}
\ No newline at end of file
+}
diff --git a/packages/playground/resolve/custom-ext.es b/packages/playground/resolve/custom-ext.es
index 000f3d188d0dea..b7f7c98793dc2b 100644
--- a/packages/playground/resolve/custom-ext.es
+++ b/packages/playground/resolve/custom-ext.es
@@ -1 +1 @@
-export const msg = `[success] custom ext`
\ No newline at end of file
+export const msg = `[success] custom ext`
diff --git a/packages/playground/resolve/exports-env/browser.mjs b/packages/playground/resolve/exports-env/browser.mjs
index 6d8ec78613bd18..e4cb61295b1086 100644
--- a/packages/playground/resolve/exports-env/browser.mjs
+++ b/packages/playground/resolve/exports-env/browser.mjs
@@ -1 +1 @@
-export const msg = '[success] exports env (browser.mjs)'
\ No newline at end of file
+export const msg = '[success] exports env (browser.mjs)'
diff --git a/packages/playground/resolve/exports-env/browser.prod.mjs b/packages/playground/resolve/exports-env/browser.prod.mjs
index 8265343ed6220f..bace0b9cd0dfa7 100644
--- a/packages/playground/resolve/exports-env/browser.prod.mjs
+++ b/packages/playground/resolve/exports-env/browser.prod.mjs
@@ -1 +1 @@
-export const msg = '[success] exports env (browser.prod.mjs)'
\ No newline at end of file
+export const msg = '[success] exports env (browser.prod.mjs)'
diff --git a/packages/playground/resolve/inline-package/package.json b/packages/playground/resolve/inline-package/package.json
index d84c0c9332104d..335e35a9236d5b 100644
--- a/packages/playground/resolve/inline-package/package.json
+++ b/packages/playground/resolve/inline-package/package.json
@@ -3,4 +3,4 @@
"private": true,
"sideEffects": false,
"main": "./inline"
-}
\ No newline at end of file
+}
diff --git a/packages/playground/ssr-react/__tests__/ssr-react.spec.ts b/packages/playground/ssr-react/__tests__/ssr-react.spec.ts
index 12660c81e4be14..bf161e03e5143c 100644
--- a/packages/playground/ssr-react/__tests__/ssr-react.spec.ts
+++ b/packages/playground/ssr-react/__tests__/ssr-react.spec.ts
@@ -38,9 +38,9 @@ test('hmr', async () => {
})
test('client navigation', async () => {
+ await untilUpdated(() => page.textContent('a[href="/about"]'), 'About')
await page.click('a[href="/about"]')
- await page.waitForTimeout(10)
- expect(await page.textContent('h1')).toMatch('About')
+ await untilUpdated(() => page.textContent('h1'), 'About')
editFile('src/pages/About.jsx', (code) =>
code.replace('
About', '
changed')
)
diff --git a/packages/playground/ssr-react/server.js b/packages/playground/ssr-react/server.js
index 4a6a653a3a781b..7c0c1a81152445 100644
--- a/packages/playground/ssr-react/server.js
+++ b/packages/playground/ssr-react/server.js
@@ -26,7 +26,13 @@ async function createServer(
root,
logLevel: isTest ? 'error' : 'info',
server: {
- middlewareMode: true
+ middlewareMode: true,
+ 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
diff --git a/packages/playground/ssr-vue/__tests__/ssr-vue.spec.ts b/packages/playground/ssr-vue/__tests__/ssr-vue.spec.ts
index 63a6034cc7b36d..a86916b1ad7594 100644
--- a/packages/playground/ssr-vue/__tests__/ssr-vue.spec.ts
+++ b/packages/playground/ssr-vue/__tests__/ssr-vue.spec.ts
@@ -109,9 +109,9 @@ test('hmr', async () => {
})
test('client navigation', async () => {
+ await untilUpdated(() => page.textContent('a[href="/about"]'), 'About')
await page.click('a[href="/about"]')
- await page.waitForTimeout(10)
- expect(await page.textContent('h1')).toMatch('About')
+ await untilUpdated(() => page.textContent('h1'), 'About')
editFile('src/pages/About.vue', (code) => code.replace('About', 'changed'))
await untilUpdated(() => page.textContent('h1'), 'changed')
})
diff --git a/packages/playground/ssr-vue/dep-import-type/deep/index.d.ts b/packages/playground/ssr-vue/dep-import-type/deep/index.d.ts
new file mode 100644
index 00000000000000..39df3b83f7e9b8
--- /dev/null
+++ b/packages/playground/ssr-vue/dep-import-type/deep/index.d.ts
@@ -0,0 +1 @@
+export interface Foo {}
diff --git a/packages/playground/ssr-vue/dep-import-type/package.json b/packages/playground/ssr-vue/dep-import-type/package.json
new file mode 100644
index 00000000000000..b58c873340ebe2
--- /dev/null
+++ b/packages/playground/ssr-vue/dep-import-type/package.json
@@ -0,0 +1,5 @@
+{
+ "name": "dep-import-type",
+ "version": "0.0.0",
+ "main": "index.js"
+}
diff --git a/packages/playground/ssr-vue/package.json b/packages/playground/ssr-vue/package.json
index 6bf759471d3a93..77f02fedc6260e 100644
--- a/packages/playground/ssr-vue/package.json
+++ b/packages/playground/ssr-vue/package.json
@@ -20,6 +20,7 @@
"@vitejs/plugin-vue-jsx": "^1.1.2",
"@vue/compiler-sfc": "^3.0.8",
"@vue/server-renderer": "^3.0.6",
+ "dep-import-type": "link:./dep-import-type",
"compression": "^1.7.4",
"cross-env": "^7.0.3",
"express": "^4.17.1",
diff --git a/packages/playground/ssr-vue/server.js b/packages/playground/ssr-vue/server.js
index 969ab6dacee01a..4ccbc21a4816ab 100644
--- a/packages/playground/ssr-vue/server.js
+++ b/packages/playground/ssr-vue/server.js
@@ -31,7 +31,13 @@ async function createServer(
root,
logLevel: isTest ? 'error' : 'info',
server: {
- middlewareMode: true
+ middlewareMode: true,
+ 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
diff --git a/packages/playground/ssr-vue/src/App.vue b/packages/playground/ssr-vue/src/App.vue
index 06f31569726915..8edc0dbf369b32 100644
--- a/packages/playground/ssr-vue/src/App.vue
+++ b/packages/playground/ssr-vue/src/App.vue
@@ -19,4 +19,4 @@
color: #2c3e50;
margin-top: 60px;
}
-
\ No newline at end of file
+
diff --git a/packages/playground/ssr-vue/src/components/Foo.jsx b/packages/playground/ssr-vue/src/components/Foo.jsx
index c1670c6a13758f..427815b2d252d2 100644
--- a/packages/playground/ssr-vue/src/components/Foo.jsx
+++ b/packages/playground/ssr-vue/src/components/Foo.jsx
@@ -7,4 +7,4 @@ export const Foo = defineComponent({
setup() {
return () =>
from JSX
}
-})
\ No newline at end of file
+})
diff --git a/packages/playground/ssr-vue/src/components/ImportType.vue b/packages/playground/ssr-vue/src/components/ImportType.vue
new file mode 100644
index 00000000000000..7fa77170ff7d61
--- /dev/null
+++ b/packages/playground/ssr-vue/src/components/ImportType.vue
@@ -0,0 +1,9 @@
+
+
import type should be removed without side-effect
+
+
+
diff --git a/packages/playground/ssr-vue/src/components/foo.css b/packages/playground/ssr-vue/src/components/foo.css
index bfaacd33a2f805..f8baa0d15b90d3 100644
--- a/packages/playground/ssr-vue/src/components/foo.css
+++ b/packages/playground/ssr-vue/src/components/foo.css
@@ -1,3 +1,3 @@
.jsx {
color: blue;
-}
\ No newline at end of file
+}
diff --git a/packages/playground/ssr-vue/src/pages/About.vue b/packages/playground/ssr-vue/src/pages/About.vue
index 6ce83448eea6ec..5fe0930c7abc4f 100644
--- a/packages/playground/ssr-vue/src/pages/About.vue
+++ b/packages/playground/ssr-vue/src/pages/About.vue
@@ -16,4 +16,4 @@ export default {
h1 {
color: red;
}
-
\ No newline at end of file
+
diff --git a/packages/playground/ssr-vue/src/pages/Home.vue b/packages/playground/ssr-vue/src/pages/Home.vue
index 35260df7dae30f..f96fb6b4d5a66a 100644
--- a/packages/playground/ssr-vue/src/pages/Home.vue
+++ b/packages/playground/ssr-vue/src/pages/Home.vue
@@ -6,12 +6,17 @@
msg from virtual module: {{ foo.msg }}
+
+
@@ -21,4 +26,4 @@ h1,
a {
color: green;
}
-
\ No newline at end of file
+
diff --git a/packages/playground/vue/Assets.vue b/packages/playground/vue/Assets.vue
index 9663d239faf8c4..875ac1b243b393 100644
--- a/packages/playground/vue/Assets.vue
+++ b/packages/playground/vue/Assets.vue
@@ -20,7 +20,7 @@
SVG Fragment reference
@@ -39,4 +39,4 @@ img {
background-image: url('./assets/asset.png');
background-size: 30px;
}
-
\ No newline at end of file
+
diff --git a/packages/playground/vue/CustomBlock.vue b/packages/playground/vue/CustomBlock.vue
index 2fae9f05441b47..cc49cd07242fdd 100644
--- a/packages/playground/vue/CustomBlock.vue
+++ b/packages/playground/vue/CustomBlock.vue
@@ -25,7 +25,7 @@ export default {
en:
- hello: "hello,vite!"
+ hello: 'hello,vite!'
ja:
- hello: "こんにちは、vite!"
+ hello: 'こんにちは、vite!'
diff --git a/packages/playground/vue/Hmr.vue b/packages/playground/vue/Hmr.vue
index 0be84398fddde8..89dade2c4f5879 100644
--- a/packages/playground/vue/Hmr.vue
+++ b/packages/playground/vue/Hmr.vue
@@ -16,4 +16,4 @@ const count = ref(foo)
.hmr-inc {
color: red;
}
-
\ No newline at end of file
+
diff --git a/packages/playground/vue/Main.vue b/packages/playground/vue/Main.vue
index 8ed3ba4de5f301..62cd2016730ee8 100644
--- a/packages/playground/vue/Main.vue
+++ b/packages/playground/vue/Main.vue
@@ -34,7 +34,7 @@ const time = ref('loading...')
window.addEventListener('load', () => {
setTimeout(() => {
- const [entry] = performance.getEntriesByType("navigation")
+ const [entry] = performance.getEntriesByType('navigation')
time.value = `loaded in ${entry.duration.toFixed(2)}ms.`
}, 0)
})
diff --git a/packages/playground/vue/Slotted.vue b/packages/playground/vue/Slotted.vue
index 5d38a63762e05b..fb25a9c5100215 100644
--- a/packages/playground/vue/Slotted.vue
+++ b/packages/playground/vue/Slotted.vue
@@ -3,10 +3,10 @@
:slotted
->
+
\ No newline at end of file
+
diff --git a/packages/plugin-legacy/index.js b/packages/plugin-legacy/index.js
index 56ba4c10122161..0ecf2bd67b2ad5 100644
--- a/packages/plugin-legacy/index.js
+++ b/packages/plugin-legacy/index.js
@@ -226,6 +226,7 @@ function viteLegacyPlugin(options = {}) {
// transform the legacy chunk with @babel/preset-env
const sourceMaps = !!config.build.sourcemap
const { code, map } = loadBabel().transform(raw, {
+ babelrc: false,
configFile: false,
compact: true,
sourceMaps,
@@ -408,6 +409,7 @@ function viteLegacyPlugin(options = {}) {
function detectPolyfills(code, targets, list) {
const { ast } = loadBabel().transform(code, {
ast: true,
+ babelrc: false,
configFile: false,
presets: [
[
diff --git a/packages/plugin-react-refresh/README.md b/packages/plugin-react-refresh/README.md
index cb73bfbf86d217..9f2abf5a5c54f6 100644
--- a/packages/plugin-react-refresh/README.md
+++ b/packages/plugin-react-refresh/README.md
@@ -45,14 +45,11 @@ To mitigate this issue, you can explicitly transform your `index.html` like this
```ts
app.get('/', async (req, res, next) => {
try {
- let html = fs.readFileSync(
- path.resolve(root, 'index.html'),
- 'utf-8'
- );
- html = await viteServer.transformIndexHtml(req.url, html);
- res.send(html);
+ let html = fs.readFileSync(path.resolve(root, 'index.html'), 'utf-8')
+ html = await viteServer.transformIndexHtml(req.url, html)
+ res.send(html)
} catch (e) {
- return next(e);
+ return next(e)
}
-});
+})
```
diff --git a/packages/plugin-react-refresh/index.js b/packages/plugin-react-refresh/index.js
index a68875e5df2b83..fc4f47da6a0d30 100644
--- a/packages/plugin-react-refresh/index.js
+++ b/packages/plugin-react-refresh/index.js
@@ -110,6 +110,9 @@ function reactRefreshPlugin(opts) {
allowAwaitOutsideFunction: true,
plugins: parserPlugins
},
+ generatorOpts: {
+ decoratorsBeforeExport: true
+ },
plugins: [
require('@babel/plugin-transform-react-jsx-self'),
require('@babel/plugin-transform-react-jsx-source'),
diff --git a/packages/plugin-vue-jsx/README.md b/packages/plugin-vue-jsx/README.md
index 098c7559a811b7..d1825db5fc0c36 100644
--- a/packages/plugin-vue-jsx/README.md
+++ b/packages/plugin-vue-jsx/README.md
@@ -18,6 +18,7 @@ export default {
## Options
See [@vue/babel-plugin-jsx](https://github.com/vuejs/jsx-next).
+
## HMR Detection
This plugin supports HMR of Vue JSX components. The detection requirements are:
@@ -53,4 +54,4 @@ export const Bar = { ... }
// not exported
const Foo = defineComponent(...)
-```
\ No newline at end of file
+```
diff --git a/packages/plugin-vue/src/handleHotUpdate.ts b/packages/plugin-vue/src/handleHotUpdate.ts
index 3b3ec974d1638c..ae07de16e19c93 100644
--- a/packages/plugin-vue/src/handleHotUpdate.ts
+++ b/packages/plugin-vue/src/handleHotUpdate.ts
@@ -127,7 +127,7 @@ export async function handleHotUpdate({
}
}
- let updateType = []
+ const updateType = []
if (needRerender) {
updateType.push(`template`)
// template is inlined into main, add main module instead
@@ -144,7 +144,7 @@ export async function handleHotUpdate({
return [...affectedModules].filter(Boolean) as ModuleNode[]
}
-export function isEqualBlock(a: SFCBlock | null, b: SFCBlock | null) {
+export function isEqualBlock(a: SFCBlock | null, b: SFCBlock | null): boolean {
if (!a && !b) return true
if (!a || !b) return false
// src imports will trigger their own updates
@@ -161,7 +161,7 @@ export function isEqualBlock(a: SFCBlock | null, b: SFCBlock | null) {
export function isOnlyTemplateChanged(
prev: SFCDescriptor,
next: SFCDescriptor
-) {
+): boolean {
return (
isEqualBlock(prev.script, next.script) &&
isEqualBlock(prev.scriptSetup, next.scriptSetup) &&
diff --git a/packages/plugin-vue/src/main.ts b/packages/plugin-vue/src/main.ts
index 1d2f896e79cb2a..655d0db83e871b 100644
--- a/packages/plugin-vue/src/main.ts
+++ b/packages/plugin-vue/src/main.ts
@@ -249,7 +249,7 @@ async function genScriptCode(
const classMatch = script.content.match(exportDefaultClassRE)
if (classMatch) {
scriptCode =
- script.content.replace(exportDefaultClassRE, `class $1`) +
+ script.content.replace(exportDefaultClassRE, `\nclass $1`) +
`\nconst _sfc_main = ${classMatch[1]}`
if (/export\s+default/.test(scriptCode)) {
// fallback if there are still export default
diff --git a/packages/plugin-vue/src/script.ts b/packages/plugin-vue/src/script.ts
index a80341c7255f7e..4857ad8c10e1ce 100644
--- a/packages/plugin-vue/src/script.ts
+++ b/packages/plugin-vue/src/script.ts
@@ -17,7 +17,7 @@ export function setResolvedScript(
descriptor: SFCDescriptor,
script: SFCScriptBlock,
ssr: boolean
-) {
+): void {
;(ssr ? ssrCache : clientCache).set(descriptor, script)
}
@@ -25,7 +25,7 @@ export function resolveScript(
descriptor: SFCDescriptor,
options: ResolvedOptions,
ssr: boolean
-) {
+): SFCScriptBlock | null {
if (!descriptor.script && !descriptor.scriptSetup) {
return null
}
diff --git a/packages/plugin-vue/src/utils/descriptorCache.ts b/packages/plugin-vue/src/utils/descriptorCache.ts
index dc1cc7fc69d3f7..d03643dc8bc026 100644
--- a/packages/plugin-vue/src/utils/descriptorCache.ts
+++ b/packages/plugin-vue/src/utils/descriptorCache.ts
@@ -1,7 +1,13 @@
import path from 'path'
import slash from 'slash'
import hash from 'hash-sum'
-import { parse, SFCDescriptor } from '@vue/compiler-sfc'
+import { CompilerError, parse, SFCDescriptor } from '@vue/compiler-sfc'
+
+// node_modules/@vue/compiler-sfc/dist/compiler-sfc.d.ts SFCParseResult should be exported so it can be re-used
+export interface SFCParseResult {
+ descriptor: SFCDescriptor
+ errors: Array
+}
const cache = new Map()
const prevCache = new Map()
@@ -11,7 +17,7 @@ export function createDescriptor(
source: string,
root: string,
isProduction: boolean | undefined
-) {
+): SFCParseResult {
const { descriptor, errors } = parse(source, {
filename,
sourceMap: true
@@ -26,15 +32,21 @@ export function createDescriptor(
return { descriptor, errors }
}
-export function getPrevDescriptor(filename: string) {
+export function getPrevDescriptor(filename: string): SFCDescriptor | undefined {
return prevCache.get(filename)
}
-export function setPrevDescriptor(filename: string, entry: SFCDescriptor) {
+export function setPrevDescriptor(
+ filename: string,
+ entry: SFCDescriptor
+): void {
prevCache.set(filename, entry)
}
-export function getDescriptor(filename: string, errorOnMissing = true) {
+export function getDescriptor(
+ filename: string,
+ errorOnMissing = true
+): SFCDescriptor | undefined {
if (cache.has(filename)) {
return cache.get(filename)!
}
@@ -46,6 +58,6 @@ export function getDescriptor(filename: string, errorOnMissing = true) {
}
}
-export function setDescriptor(filename: string, entry: SFCDescriptor) {
+export function setDescriptor(filename: string, entry: SFCDescriptor): void {
cache.set(filename, entry)
}
diff --git a/packages/plugin-vue/src/utils/query.ts b/packages/plugin-vue/src/utils/query.ts
index c0bafedcbd6a0d..bd1c6394940be9 100644
--- a/packages/plugin-vue/src/utils/query.ts
+++ b/packages/plugin-vue/src/utils/query.ts
@@ -9,7 +9,9 @@ export interface VueQuery {
raw?: boolean
}
-export function parseVueRequest(id: string) {
+export function parseVueRequest(
+ id: string
+): { filename: string; query: VueQuery } {
const [filename, rawQuery] = id.split(`?`, 2)
const query = qs.parse(rawQuery) as VueQuery
if (query.vue != null) {
diff --git a/packages/vite/README.md b/packages/vite/README.md
index b04e97cb308db4..89490d7b480a8e 100644
--- a/packages/vite/README.md
+++ b/packages/vite/README.md
@@ -17,4 +17,4 @@ Vite (French word for "fast", pronounced `/vit/`) is a new breed of frontend bui
In addition, Vite is highly extensible via its [Plugin API](https://vitejs.dev/guide/api-plugin.html) and [JavaScript API](https://vitejs.dev/guide/api-javascript.html) with full typing support.
-[Read the Docs to Learn More](https://vitejs.dev).
\ No newline at end of file
+[Read the Docs to Learn More](https://vitejs.dev).
diff --git a/packages/vite/package.json b/packages/vite/package.json
index 3ff6c45a6f3fe1..d005451f6bdd62 100644
--- a/packages/vite/package.json
+++ b/packages/vite/package.json
@@ -60,7 +60,7 @@
"@rollup/plugin-dynamic-import-vars": "^1.1.1",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^11.0.1",
- "@rollup/plugin-typescript": "^8.0.0",
+ "@rollup/plugin-typescript": "^8.2.1",
"@rollup/pluginutils": "^4.1.0",
"@types/clean-css": "^4.2.3",
"@types/convert-source-map": "^1.5.1",
diff --git a/packages/vite/rollup.config.js b/packages/vite/rollup.config.js
index 378242bfb6657e..6814db9f9e437b 100644
--- a/packages/vite/rollup.config.js
+++ b/packages/vite/rollup.config.js
@@ -26,7 +26,8 @@ const envConfig = {
})
],
output: {
- dir: path.resolve(__dirname, 'dist/client')
+ dir: path.resolve(__dirname, 'dist/client'),
+ sourcemap: true
}
}
@@ -47,7 +48,8 @@ const clientConfig = {
})
],
output: {
- dir: path.resolve(__dirname, 'dist/client')
+ dir: path.resolve(__dirname, 'dist/client'),
+ sourcemap: true
}
}
@@ -67,7 +69,8 @@ const sharedNodeOptions = {
exports: 'named',
format: 'cjs',
externalLiveBindings: false,
- freeze: false
+ freeze: false,
+ sourcemap: true
},
onwarn(warning, warn) {
// node-resolve complains a lot about this but seems to still work?
diff --git a/packages/vite/src/client/client.ts b/packages/vite/src/client/client.ts
index 366896293b0490..6a089e10f45d5a 100644
--- a/packages/vite/src/client/client.ts
+++ b/packages/vite/src/client/client.ts
@@ -201,7 +201,7 @@ const supportsConstructedSheet = (() => {
const sheetsMap = new Map()
-export function updateStyle(id: string, content: string) {
+export function updateStyle(id: string, content: string): void {
let style = sheetsMap.get(id)
if (supportsConstructedSheet && !content.includes('@import')) {
if (style && !(style instanceof CSSStyleSheet)) {
@@ -235,8 +235,8 @@ export function updateStyle(id: string, content: string) {
sheetsMap.set(id, style)
}
-export function removeStyle(id: string) {
- let style = sheetsMap.get(id)
+export function removeStyle(id: string): void {
+ const style = sheetsMap.get(id)
if (style) {
if (style instanceof CSSStyleSheet) {
// @ts-ignore
@@ -334,6 +334,8 @@ const ctxToListenersMap = new Map<
Map void)[]>
>()
+// Just infer the return type for now
+// _This would have to be activated when used `plugin:@typescript-eslint/recommended`_ eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export const createHotContext = (ownerPath: string) => {
if (!dataMap.has(ownerPath)) {
dataMap.set(ownerPath, {})
@@ -436,7 +438,7 @@ export const createHotContext = (ownerPath: string) => {
/**
* urls here are dynamic import() urls that couldn't be statically analyzed
*/
-export function injectQuery(url: string, queryToInject: string) {
+export function injectQuery(url: string, queryToInject: string): string {
// skip urls that won't be handled by vite
if (!url.startsWith('.') && !url.startsWith('/')) {
return url
diff --git a/packages/vite/src/client/overlay.ts b/packages/vite/src/client/overlay.ts
index 41c44505aa65c4..47a7dacad85a1b 100644
--- a/packages/vite/src/client/overlay.ts
+++ b/packages/vite/src/client/overlay.ts
@@ -151,7 +151,7 @@ export class ErrorOverlay extends HTMLElement {
})
}
- text(selector: string, text: string, linkFiles = false) {
+ text(selector: string, text: string, linkFiles = false): void {
const el = this.root.querySelector(selector)!
if (!linkFiles) {
el.textContent = text
@@ -176,7 +176,7 @@ export class ErrorOverlay extends HTMLElement {
}
}
- close() {
+ close(): void {
this.parentNode?.removeChild(this)
}
}
diff --git a/packages/vite/src/node/__tests__/config.spec.ts b/packages/vite/src/node/__tests__/config.spec.ts
new file mode 100644
index 00000000000000..1e2dc6fce8124e
--- /dev/null
+++ b/packages/vite/src/node/__tests__/config.spec.ts
@@ -0,0 +1,94 @@
+import { mergeConfig, UserConfigExport } from '../config'
+
+describe('mergeConfig', () => {
+ test('handles configs with different alias schemas', () => {
+ const baseConfig: UserConfigExport = {
+ resolve: {
+ alias: [
+ {
+ find: 'foo',
+ replacement: 'foo-value'
+ }
+ ]
+ }
+ }
+
+ const newConfig: UserConfigExport = {
+ resolve: {
+ alias: {
+ bar: 'bar-value',
+ baz: 'baz-value'
+ }
+ }
+ }
+
+ const mergedConfig: UserConfigExport = {
+ resolve: {
+ alias: [
+ {
+ find: 'foo',
+ replacement: 'foo-value'
+ },
+ {
+ find: 'bar',
+ replacement: 'bar-value'
+ },
+ {
+ find: 'baz',
+ replacement: 'baz-value'
+ }
+ ]
+ }
+ }
+
+ expect(mergeConfig(baseConfig, newConfig)).toEqual(mergedConfig)
+ })
+
+ test('handles assetsInclude', () => {
+ const baseConfig: UserConfigExport = {
+ assetsInclude: 'some-string'
+ }
+
+ const newConfig: UserConfigExport = {
+ assetsInclude: ['some-other-string', /regexp?/]
+ }
+
+ const mergedConfig: UserConfigExport = {
+ assetsInclude: ['some-string', 'some-other-string', /regexp?/]
+ }
+
+ expect(mergeConfig(baseConfig, newConfig)).toEqual(mergedConfig)
+ })
+
+ test('not handles alias not under `resolve`', () => {
+ const baseConfig = {
+ custom: {
+ alias: {
+ bar: 'bar-value',
+ baz: 'baz-value'
+ }
+ }
+ }
+
+ const newConfig = {
+ custom: {
+ alias: {
+ bar: 'bar-value-2',
+ foo: 'foo-value'
+ }
+ }
+ }
+
+ const mergedConfig = {
+ custom: {
+ alias: {
+ bar: 'bar-value-2',
+ baz: 'baz-value',
+ foo: 'foo-value'
+ }
+ }
+ }
+
+ expect(mergeConfig(baseConfig, newConfig)).toEqual(mergedConfig)
+ })
+})
diff --git a/packages/vite/src/node/build.ts b/packages/vite/src/node/build.ts
index 958f32dd83066a..0ee1ccf9d28428 100644
--- a/packages/vite/src/node/build.ts
+++ b/packages/vite/src/node/build.ts
@@ -12,7 +12,10 @@ import Rollup, {
RollupOutput,
ExternalOption,
GetManualChunk,
- GetModuleInfo
+ GetModuleInfo,
+ WatcherOptions,
+ RollupWatcher,
+ RollupError
} from 'rollup'
import { buildReporterPlugin } from './plugins/reporter'
import { buildHtmlPlugin } from './plugins/html'
@@ -176,12 +179,18 @@ export interface BuildOptions {
* @default 500
*/
chunkSizeWarningLimit?: number
+ /**
+ * Rollup watch options
+ * https://rollupjs.org/guide/en/#watchoptions
+ */
+ watch?: WatcherOptions | null
}
export interface LibraryOptions {
entry: string
name?: string
formats?: LibraryFormats[]
+ fileName?: string
}
export type LibraryFormats = 'es' | 'cjs' | 'umd' | 'iife'
@@ -214,6 +223,7 @@ export function resolveBuildOptions(raw?: BuildOptions): ResolvedBuildOptions {
ssrManifest: false,
brotliSize: true,
chunkSizeWarningLimit: 500,
+ watch: null,
...raw
}
@@ -279,7 +289,7 @@ const parallelBuilds: RollupBuild[] = []
*/
export async function build(
inlineConfig: InlineConfig = {}
-): Promise {
+): Promise {
parallelCallCounts++
try {
return await doBuild(inlineConfig)
@@ -294,7 +304,7 @@ export async function build(
async function doBuild(
inlineConfig: InlineConfig = {}
-): Promise {
+): Promise {
const config = await resolveConfig(inlineConfig, 'build', 'production')
const options = config.build
const ssr = !!options.ssr
@@ -355,29 +365,39 @@ async function doBuild(
}
const rollup = require('rollup') as typeof Rollup
+ const rollupOptions: RollupOptions = {
+ input,
+ preserveEntrySignatures: ssr
+ ? 'allow-extension'
+ : libOptions
+ ? 'strict'
+ : false,
+ ...options.rollupOptions,
+ plugins,
+ external,
+ onwarn(warning, warn) {
+ onRollupWarning(warning, warn, config)
+ }
+ }
- try {
- const bundle = await rollup.rollup({
- input,
- preserveEntrySignatures: ssr
- ? 'allow-extension'
- : libOptions
- ? 'strict'
- : false,
- ...options.rollupOptions,
- plugins,
- external,
- onwarn(warning, warn) {
- onRollupWarning(warning, warn, config)
- }
- })
-
- parallelBuilds.push(bundle)
+ const outputBuildError = (e: RollupError) => {
+ config.logger.error(
+ chalk.red(`${e.plugin ? `[${e.plugin}] ` : ''}${e.message}`)
+ )
+ if (e.id) {
+ const loc = e.loc ? `:${e.loc.line}:${e.loc.column}` : ''
+ config.logger.error(`file: ${chalk.cyan(`${e.id}${loc}`)}`)
+ }
+ if (e.frame) {
+ config.logger.error(chalk.yellow(e.frame))
+ }
+ }
+ try {
const pkgName = libOptions && getPkgName(config.root)
- const generate = (output: OutputOptions = {}) => {
- return bundle[options.write ? 'write' : 'generate']({
+ const buildOuputOptions = (output: OutputOptions = {}): OutputOptions => {
+ return {
dir: outDir,
format: ssr ? 'cjs' : 'es',
exports: ssr ? 'named' : 'auto',
@@ -386,7 +406,7 @@ async function doBuild(
entryFileNames: ssr
? `[name].js`
: libOptions
- ? `${pkgName}.${output.format || `es`}.js`
+ ? `${libOptions.fileName || pkgName}.${output.format || `es`}.js`
: path.posix.join(options.assetsDir, `[name].[hash].js`),
chunkFileNames: libOptions
? `[name].js`
@@ -406,7 +426,81 @@ async function doBuild(
? createMoveToVendorChunkFn(config)
: undefined,
...output
+ }
+ }
+
+ // resolve lib mode outputs
+ const outputs = resolveBuildOutputs(
+ options.rollupOptions?.output,
+ libOptions,
+ config.logger
+ )
+
+ // watch file changes with rollup
+ if (config.build.watch) {
+ config.logger.info(chalk.cyanBright(`\nwatching for file changes...`))
+
+ const output: OutputOptions[] = []
+ if (Array.isArray(outputs)) {
+ for (const resolvedOutput of outputs) {
+ output.push(buildOuputOptions(resolvedOutput))
+ }
+ } else {
+ output.push(buildOuputOptions(outputs))
+ }
+
+ const watcherOptions = config.build.watch
+ const watcher = rollup.watch({
+ ...rollupOptions,
+ output,
+ watch: {
+ ...watcherOptions,
+ chokidar: {
+ ignored: [
+ '**/node_modules/**',
+ '**/.git/**',
+ ...(watcherOptions?.chokidar?.ignored || [])
+ ],
+ ignoreInitial: true,
+ ignorePermissionErrors: true,
+ ...watcherOptions.chokidar
+ }
+ }
+ })
+
+ watcher.on('event', (event) => {
+ if (event.code === 'BUNDLE_START') {
+ config.logger.info(chalk.cyanBright(`\nbuild started...`))
+
+ // clean previous files
+ if (options.write) {
+ emptyDir(outDir)
+ if (fs.existsSync(config.publicDir)) {
+ copyDir(config.publicDir, outDir)
+ }
+ }
+ } else if (event.code === 'BUNDLE_END') {
+ event.result.close()
+ config.logger.info(chalk.cyanBright(`built in ${event.duration}ms.`))
+ } else if (event.code === 'ERROR') {
+ outputBuildError(event.error)
+ }
})
+
+ // stop watching
+ watcher.close()
+
+ return watcher
+ }
+
+ // write or generate files with rollup
+ const bundle = await rollup.rollup(rollupOptions)
+ parallelBuilds.push(bundle)
+
+ const generate = (output: OutputOptions = {}) => {
+ return bundle[options.write ? 'write' : 'generate'](
+ buildOuputOptions(output)
+ )
}
if (options.write) {
@@ -434,12 +528,6 @@ async function doBuild(
}
}
- // resolve lib mode outputs
- const outputs = resolveBuildOutputs(
- options.rollupOptions?.output,
- libOptions,
- config.logger
- )
if (Array.isArray(outputs)) {
const res = []
for (const output of outputs) {
@@ -450,16 +538,7 @@ async function doBuild(
return await generate(outputs)
}
} catch (e) {
- config.logger.error(
- chalk.red(`${e.plugin ? `[${e.plugin}] ` : ``}${e.message}`)
- )
- if (e.id) {
- const loc = e.loc ? `:${e.loc.line}:${e.loc.column}` : ``
- config.logger.error(`file: ${chalk.cyan(`${e.id}${loc}`)}`)
- }
- if (e.frame) {
- config.logger.error(chalk.yellow(e.frame))
- }
+ outputBuildError(e)
throw e
}
}
@@ -558,7 +637,7 @@ export function onRollupWarning(
warning: RollupWarning,
warn: WarningHandler,
config: ResolvedConfig
-) {
+): void {
if (warning.code === 'UNRESOLVED_IMPORT') {
const id = warning.source
const importer = warning.importer
diff --git a/packages/vite/src/node/cli.ts b/packages/vite/src/node/cli.ts
index 26384fd6b2511e..41ed363388d7a7 100644
--- a/packages/vite/src/node/cli.ts
+++ b/packages/vite/src/node/cli.ts
@@ -130,6 +130,7 @@ cli
`[boolean] force empty outDir when it's outside of root`
)
.option('-m, --mode ', `[string] set env mode`)
+ .option('-w, --watch', `[boolean] rebuilds when modules have changed on disk`)
.action(async (root: string, options: BuildOptions & GlobalCLIOptions) => {
const { build } = await import('./build')
const buildOptions = cleanOptions(options) as BuildOptions
diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts
index 68787fa3369a66..a0cf1e8ef971cd 100644
--- a/packages/vite/src/node/config.ts
+++ b/packages/vite/src/node/config.ts
@@ -45,8 +45,8 @@ export interface ConfigEnv {
mode: string
}
-export type UserConfigFn = (env: ConfigEnv) => UserConfig
-export type UserConfigExport = UserConfig | UserConfigFn
+export type UserConfigFn = (env: ConfigEnv) => UserConfig | Promise
+export type UserConfigExport = UserConfig | Promise | UserConfigFn
/**
* Type helper to make it easier to use vite.config.ts
@@ -160,12 +160,13 @@ export interface SSROptions {
export interface InlineConfig extends UserConfig {
configFile?: string | false
+ envFile?: false
}
export type ResolvedConfig = Readonly<
Omit & {
configFile: string | undefined
- inlineConfig: UserConfig
+ inlineConfig: InlineConfig
root: string
base: string
publicDir: string
@@ -242,14 +243,14 @@ export async function resolveConfig(
// run config hooks
const userPlugins = [...prePlugins, ...normalPlugins, ...postPlugins]
- userPlugins.forEach((p) => {
+ for (const p of userPlugins) {
if (p.config) {
- const res = p.config(config, configEnv)
+ const res = await p.config(config, configEnv)
if (res) {
config = mergeConfig(config, res)
}
}
- })
+ }
// resolve root
const resolvedRoot = normalizePath(
@@ -273,7 +274,7 @@ export async function resolveConfig(
}
// load .env files
- const userEnv = loadEnv(mode, resolvedRoot)
+ const userEnv = inlineConfig.envFile !== false && loadEnv(mode, resolvedRoot)
// Note it is possible for user to have a custom mode, e.g. `staging` where
// production-like behavior is expected. This is indicated by NODE_ENV=production
@@ -376,11 +377,7 @@ export async function resolveConfig(
)
// call configResolved hooks
- userPlugins.forEach((p) => {
- if (p.configResolved) {
- p.configResolved(resolved)
- }
- })
+ await Promise.all(userPlugins.map((p) => p.configResolved?.(resolved)))
if (process.env.DEBUG) {
debug(`using resolved config: %O`, {
@@ -505,11 +502,11 @@ function resolveBaseUrl(
return base
}
-export function mergeConfig(
+function mergeConfigRecursively(
a: Record,
b: Record,
- isRoot = true
-): Record {
+ rootPath: string
+) {
const merged: Record = { ...a }
for (const key in b) {
const value = b[key]
@@ -523,16 +520,20 @@ export function mergeConfig(
continue
}
if (isObject(existing) && isObject(value)) {
- merged[key] = mergeConfig(existing, value, false)
+ merged[key] = mergeConfigRecursively(
+ existing,
+ value,
+ rootPath ? `${rootPath}.${key}` : key
+ )
continue
}
- // root fields that require special handling
- if (existing != null && isRoot) {
- if (key === 'alias') {
+ // fields that require special handling
+ if (existing != null) {
+ if (key === 'alias' && (rootPath === 'resolve' || rootPath === '')) {
merged[key] = mergeAlias(existing, value)
continue
- } else if (key === 'assetsInclude') {
+ } else if (key === 'assetsInclude' && rootPath === '') {
merged[key] = [].concat(existing, value)
continue
}
@@ -543,6 +544,14 @@ export function mergeConfig(
return merged
}
+export function mergeConfig(
+ a: Record,
+ b: Record,
+ isRoot = true
+): Record {
+ return mergeConfigRecursively(a, b, isRoot ? '' : '.')
+}
+
function mergeAlias(a: AliasOptions = [], b: AliasOptions = []): Alias[] {
return [...normalizeAlias(a), ...normalizeAlias(b)]
}
@@ -707,8 +716,9 @@ export async function loadConfigFromFile(
debug(`bundled config file loaded in ${Date.now() - start}ms`)
}
- const config =
- typeof userConfig === 'function' ? userConfig(configEnv) : userConfig
+ const config = await (typeof userConfig === 'function'
+ ? userConfig(configEnv)
+ : userConfig)
if (!isObject(config)) {
throw new Error(`config must export or return an object.`)
}
@@ -801,7 +811,11 @@ async function loadConfigFromBundledFile(
return config
}
-export function loadEnv(mode: string, root: string, prefix = 'VITE_') {
+export function loadEnv(
+ mode: string,
+ root: string,
+ prefix = 'VITE_'
+): Record {
if (mode === 'local') {
throw new Error(
`"local" cannot be used as a mode name because it conflicts with ` +
diff --git a/packages/vite/src/node/importGlob.ts b/packages/vite/src/node/importGlob.ts
index f14d7bd8bfddda..75a57953894e36 100644
--- a/packages/vite/src/node/importGlob.ts
+++ b/packages/vite/src/node/importGlob.ts
@@ -42,7 +42,7 @@ export async function transformImportGlob(
}
let base
let parentDepth = 0
- let isAbsolute = pattern.startsWith('/')
+ const isAbsolute = pattern.startsWith('/')
if (isAbsolute) {
base = path.resolve(root)
pattern = pattern.slice(1)
diff --git a/packages/vite/src/node/index.ts b/packages/vite/src/node/index.ts
index e75611ad66f475..e020f10ad7f0a2 100644
--- a/packages/vite/src/node/index.ts
+++ b/packages/vite/src/node/index.ts
@@ -43,6 +43,7 @@ export type {
export type { CSSOptions, CSSModulesOptions } from './plugins/css'
export type { JsonOptions } from './plugins/json'
export type { ESBuildOptions, ESBuildTransformResult } from './plugins/esbuild'
+export type { Manifest, ManifestChunk } from './plugins/manifest'
export type {
PackageData,
ResolveOptions,
diff --git a/packages/vite/src/node/optimizer/registerMissing.ts b/packages/vite/src/node/optimizer/registerMissing.ts
index d65481bc5283d1..32fdce1526d1ba 100644
--- a/packages/vite/src/node/optimizer/registerMissing.ts
+++ b/packages/vite/src/node/optimizer/registerMissing.ts
@@ -9,7 +9,9 @@ import { resolveSSRExternal } from '../ssr/ssrExternal'
*/
const debounceMs = 100
-export function createMissingImporterRegisterFn(server: ViteDevServer) {
+export function createMissingImporterRegisterFn(
+ server: ViteDevServer
+): (id: string, resolved: string) => void {
const { logger } = server.config
let knownOptimized = server._optimizeDepsMetadata!.optimized
let currentMissing: Record = {}
diff --git a/packages/vite/src/node/optimizer/scan.ts b/packages/vite/src/node/optimizer/scan.ts
index 030164345e1469..e40a1b1dea7acc 100644
--- a/packages/vite/src/node/optimizer/scan.ts
+++ b/packages/vite/src/node/optimizer/scan.ts
@@ -38,7 +38,7 @@ const htmlTypesRE = /\.(html|vue|svelte)$/
// use Acorn because it's slow. Luckily this doesn't have to be bullet proof
// since even missed imports can be caught at runtime, and false positives will
// simply be ignored.
-const importsRE = /\bimport(?:[\w*{}\n\r\t, ]+from\s*)?\s*("[^"]+"|'[^']+')/gm
+const importsRE = /\bimport(?!\s+type)(?:[\w*{}\n\r\t, ]+from\s*)?\s*("[^"]+"|'[^']+')/gm
export async function scanImports(
config: ResolvedConfig
@@ -417,7 +417,10 @@ async function transformGlob(
return s.toString()
}
-export function shouldExternalizeDep(resolvedId: string, rawId: string) {
+export function shouldExternalizeDep(
+ resolvedId: string,
+ rawId: string
+): boolean {
// not a valid file path
if (!path.isAbsolute(resolvedId)) {
return true
@@ -430,4 +433,5 @@ export function shouldExternalizeDep(resolvedId: string, rawId: string) {
if (!JS_TYPES_RE.test(resolvedId) && !htmlTypesRE.test(resolvedId)) {
return true
}
+ return false
}
diff --git a/packages/vite/src/node/plugin.ts b/packages/vite/src/node/plugin.ts
index 7bef2402de4729..012c32e0fa6dfb 100644
--- a/packages/vite/src/node/plugin.ts
+++ b/packages/vite/src/node/plugin.ts
@@ -61,11 +61,14 @@ export interface Plugin extends RollupPlugin {
* Note: User plugins are resolved before running this hook so injecting other
* plugins inside the `config` hook will have no effect.
*/
- config?: (config: UserConfig, env: ConfigEnv) => UserConfig | null | void
+ config?: (
+ config: UserConfig,
+ env: ConfigEnv
+ ) => UserConfig | null | void | Promise
/**
* Use this hook to read and store the final resolved vite config.
*/
- configResolved?: (config: ResolvedConfig) => void
+ configResolved?: (config: ResolvedConfig) => void | Promise
/**
* Configure the vite server. The hook receives the {@link ViteDevServer}
* instance. This can also be used to store a reference to the server
diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts
index 0e426fd6e5d934..950f7e86c59696 100644
--- a/packages/vite/src/node/plugins/asset.ts
+++ b/packages/vite/src/node/plugins/asset.ts
@@ -102,7 +102,7 @@ export function assetPlugin(config: ResolvedConfig): Plugin {
}
}
-export function registerAssetToChunk(chunk: RenderedChunk, file: string) {
+export function registerAssetToChunk(chunk: RenderedChunk, file: string): void {
let emitted = chunkToEmittedAssetsMap.get(chunk)
if (!emitted) {
emitted = new Set()
@@ -132,7 +132,7 @@ export function fileToUrl(
id: string,
config: ResolvedConfig,
ctx: PluginContext
-) {
+): string | Promise {
if (config.command === 'serve') {
return fileToDevUrl(id, config)
} else {
@@ -163,7 +163,10 @@ const assetHashToFilenameMap = new WeakMap<
Map
>()
-export function getAssetFilename(hash: string, config: ResolvedConfig) {
+export function getAssetFilename(
+ hash: string,
+ config: ResolvedConfig
+): string | undefined {
return assetHashToFilenameMap.get(config)?.get(hash)
}
diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts
index 8dfcb2a15faf14..9d17b245767fc1 100644
--- a/packages/vite/src/node/plugins/css.ts
+++ b/packages/vite/src/node/plugins/css.ts
@@ -35,7 +35,9 @@ import {
import MagicString from 'magic-string'
import * as Postcss from 'postcss'
import type Sass from 'sass'
-import type Stylus from 'stylus'
+// We need to disable check of extraneous import which is buggy for stylus,
+// and causes the CI tests fail, see: https://github.com/vitejs/vite/pull/2860
+import type Stylus from 'stylus' // eslint-disable-line node/no-extraneous-import
import type Less from 'less'
import { Alias } from 'types/alias'
@@ -95,10 +97,10 @@ const enum PureCssLang {
}
type CssLang = keyof typeof PureCssLang | keyof typeof PreprocessLang
-export const isCSSRequest = (request: string) =>
+export const isCSSRequest = (request: string): boolean =>
cssLangRE.test(request) && !directRequestRE.test(request)
-export const isDirectCSSRequest = (request: string) =>
+export const isDirectCSSRequest = (request: string): boolean =>
cssLangRE.test(request) && directRequestRE.test(request)
const cssModulesCache = new WeakMap<
@@ -338,7 +340,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
// this is a shared CSS-only chunk that is empty.
pureCssChunks.add(chunk.fileName)
}
- if (opts.format === 'es') {
+ if (opts.format === 'es' || opts.format === 'cjs') {
chunkCSS = await processChunkCSS(chunkCSS, {
inlined: false,
minify: true
@@ -397,7 +399,9 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
.join('|')
.replace(/\./g, '\\.')
const emptyChunkRE = new RegExp(
- `\\bimport\\s*"[^"]*(?:${emptyChunkFiles})";\n?`,
+ opts.format === 'es'
+ ? `\\bimport\\s*"[^"]*(?:${emptyChunkFiles})";\n?`
+ : `\\brequire\\(\\s*"[^"]*(?:${emptyChunkFiles})"\\);\n?`,
'g'
)
for (const file in bundle) {
@@ -764,7 +768,7 @@ function rewriteCssUrls(
replacer: CssUrlReplacer
): Promise {
return asyncReplace(css, cssUrlRE, async (match) => {
- let [matched, rawUrl] = match
+ const [matched, rawUrl] = match
return await doUrlReplace(rawUrl, matched, replacer)
})
}
@@ -774,7 +778,7 @@ function rewriteCssImageSet(
replacer: CssUrlReplacer
): Promise {
return asyncReplace(css, cssImageSetRE, async (match) => {
- let [matched, rawUrl] = match
+ const [matched, rawUrl] = match
const url = await processSrcSet(rawUrl, ({ url }) =>
doUrlReplace(url, matched, replacer)
)
@@ -1102,18 +1106,31 @@ function createViteLessPlugin(
}
// .styl
-const styl: StylePreprocessor = (source, root, options) => {
+const styl: StylePreprocessor = async (source, root, options) => {
const nodeStylus = loadPreprocessor(PreprocessLang.stylus, root)
+ // Get source with preprocessor options.additionalData. Make sure a new line separator
+ // is added to avoid any render error, as added stylus content may not have semi-colon separators
+ source = await getSource(
+ source,
+ options.filename,
+ options.additionalData,
+ '\n'
+ )
+ // Get preprocessor options.imports dependencies as stylus
+ // does not return them with its builtin `.deps()` method
+ const importsDeps = (options.imports ?? []).map((dep: string) =>
+ path.resolve(dep)
+ )
try {
- const ref = nodeStylus(source)
+ const ref = nodeStylus(source, options)
- Object.keys(options).forEach((key) => ref.set(key, options[key]))
// if (map) ref.set('sourcemap', { inline: false, comment: false })
const result = ref.render()
// @ts-expect-error: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/51919
- const deps = ref.deps()
+ // Concat imports deps with computed deps
+ const deps = [...ref.deps(), ...importsDeps]
return { code: result, errors: [], deps }
} catch (e) {
@@ -1124,13 +1141,14 @@ const styl: StylePreprocessor = (source, root, options) => {
function getSource(
source: string,
filename: string,
- additionalData?: PreprocessorAdditionalData
+ additionalData?: PreprocessorAdditionalData,
+ sep: string = ''
): string | Promise {
if (!additionalData) return source
if (typeof additionalData === 'function') {
return additionalData(source, filename)
}
- return additionalData + source
+ return additionalData + sep + source
}
const preProcessors = Object.freeze({
diff --git a/packages/vite/src/node/plugins/define.ts b/packages/vite/src/node/plugins/define.ts
index 069e41417902aa..573c0d362c46c7 100644
--- a/packages/vite/src/node/plugins/define.ts
+++ b/packages/vite/src/node/plugins/define.ts
@@ -31,7 +31,7 @@ export function definePlugin(config: ResolvedConfig): Plugin {
}
const replacements: Record = {
- 'process.env.NODE_ENV': JSON.stringify(config.mode),
+ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || config.mode),
...userDefine,
...importMetaKeys,
'process.env.': `({}).`
diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts
index cd147519332bce..66991fe93e6215 100644
--- a/packages/vite/src/node/plugins/html.ts
+++ b/packages/vite/src/node/plugins/html.ts
@@ -29,7 +29,7 @@ import {
} from '@vue/compiler-dom'
const htmlProxyRE = /\?html-proxy&index=(\d+)\.js$/
-export const isHTMLProxy = (id: string) => htmlProxyRE.test(id)
+export const isHTMLProxy = (id: string): boolean => htmlProxyRE.test(id)
const htmlCommentRE = //g
const scriptModuleRE = /(