diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 7411edbf846b98..ba8d46f3c26f97 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -137,13 +137,13 @@ module.exports = defineConfig({ 'node/no-unsupported-features/es-builtins': [ 'error', { - version: '>=14.18.0' + version: '^14.18.0 || >=16.0.0' } ], 'node/no-unsupported-features/node-builtins': [ 'error', { - version: '>=14.18.0' + version: '^14.18.0 || >=16.0.0' } ] } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 65fb07f88fad9d..350f36b0f25351 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Vite Contributing Guide -Hi! We are really excited that you are interested in contributing to Vite. Before submitting your contribution, please make sure to take a moment and read through the following guide: +Hi! We're really excited that you're interested in contributing to Vite! Before submitting your contribution, please read through the following guide. ## Repo Setup @@ -8,7 +8,7 @@ The Vite repo is a monorepo using pnpm workspaces. The package manager used to i To develop and test the core `vite` package: -1. Run `pnpm i` in Vite's root folder +1. Run `pnpm i` in Vite's root folder. 2. Run `pnpm run build` in Vite's root folder. @@ -16,41 +16,41 @@ To develop and test the core `vite` package: You can alternatively use [Vite.js Docker Dev](https://github.com/nystudio107/vitejs-docker-dev) for a containerized Docker setup for Vite.js development. -> Vite uses pnpm v7. If you are working on multiple projects with different versions of pnpm, it's recommend to enable [Corepack](https://github.com/nodejs/corepack) by running `corepack enable`. +> Vite uses pnpm v7. If you are working on multiple projects with different versions of pnpm, it's recommended to enable [Corepack](https://github.com/nodejs/corepack) by running `corepack enable`. ## Debugging -If you want to use break point and explore code execution you can use the ["Run and debug"](https://code.visualstudio.com/docs/editor/debugging) feature from vscode. +To use breakpoints and explore code execution, you can use the ["Run and Debug"](https://code.visualstudio.com/docs/editor/debugging) feature from VS Code. 1. Add a `debugger` statement where you want to stop the code execution. -2. Click on the "Run and Debug" icon in the activity bar of the editor. +2. Click the "Run and Debug" icon in the activity bar of the editor, which opens the [_Run and Debug view_](https://code.visualstudio.com/docs/editor/debugging#_run-and-debug-view). -3. Click on the "JavaScript Debug Terminal" button. +3. Click the "JavaScript Debug Termimal" button in the _Run and Debug view_, which opens a terminal in VS Code. -4. It will open a terminal, then go to `playground/xxx` and run `pnpm run dev`. +4. From that terminal, go to `playground/xxx`, and run `pnpm run dev`. -5. The execution will stop and you'll use the [Debug toolbar](https://code.visualstudio.com/docs/editor/debugging#_debug-actions) to continue, step over, restart the process... +5. The execution will stop at the `debugger` statement, and you can use the [Debug toolbar](https://code.visualstudio.com/docs/editor/debugging#_debug-actions) to continue, step over, and restart the process... -### Debugging errors in Vitest tests using Playwright (Chromium) +### Debugging Errors in Vitest Tests Using Playwright (Chromium) Some errors are masked and hidden away because of the layers of abstraction and sandboxed nature added by Vitest, Playwright, and Chromium. In order to see what's actually going wrong and the contents of the devtools console in those instances, follow this setup: 1. Add a `debugger` statement to the `playground/vitestSetup.ts` -> `afterAll` hook. This will pause execution before the tests quit and the Playwright browser instance exits. -1. Run the tests with the `debug-serve` script command which will enable remote debugging: `pnpm run debug-serve resolve`. +2. Run the tests with the `debug-serve` script command, which will enable remote debugging: `pnpm run debug-serve resolve`. -1. Wait for inspector devtools to open in your browser and the debugger to attach. +3. Wait for inspector devtools to open in your browser and the debugger to attach. -1. In the sources panel in the right column, click the play button to resume execution and allow the tests to run which will open a Chromium instance. +4. In the sources panel in the right column, click the play button to resume execution, and allow the tests to run, which will open a Chromium instance. -1. Focusing the Chromium instance, you can open the browser devtools and inspect the console there to find the underlying problems. +5. Focusing the Chromium instance, you can open the browser devtools and inspect the console there to find the underlying problems. -1. To close everything, just stop the test process back in your terminal. +6. To close everything, just stop the test process back in your terminal. ## Testing Vite against external packages -You may wish to test your locally-modified copy of Vite against another package that is built with Vite. For pnpm, after building Vite, you can use [`pnpm.overrides`](https://pnpm.io/package_json#pnpmoverrides). Please note that `pnpm.overrides` must be specified in the root `package.json` and you must first list the package as a dependency in the root `package.json`: +You may wish to test your locally modified copy of Vite against another package that is built with Vite. For pnpm, after building Vite, you can use [`pnpm.overrides`](https://pnpm.io/package_json#pnpmoverrides) to do this. Note that `pnpm.overrides` must be specified in the root `package.json`, and you must list the package as a dependency in the root `package.json`: ```json { @@ -73,7 +73,7 @@ And re-run `pnpm install` to link the package. Each package under `playground/` contains a `__tests__` directory. The tests are run using [Vitest](https://vitest.dev/) + [Playwright](https://playwright.dev/) with custom integrations to make writing tests simple. The detailed setup is inside `vitest.config.e2e.js` and `playground/vitest*` files. -Before running the tests, make sure that [Vite has been built](#repo-setup). On Windows, you may want to [activate Developer Mode](https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development) to solve [issues with symlink creation for non-admins](https://github.com/vitejs/vite/issues/7390). Also you may want to [set git `core.symlinks` to `true` to solve issues with symlinks in git](https://github.com/vitejs/vite/issues/5242). +Before running the tests, make sure that [Vite has been built](#repo-setup). On Windows, you may want to [activate Developer Mode](https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development) to resolve [issues with symlink creation for non-admins](https://github.com/vitejs/vite/issues/7390). Also, you may want to [set git `core.symlinks` to `true` to resolve issues with symlinks in git](https://github.com/vitejs/vite/issues/5242). Each integration test can be run under either dev server mode or build mode. @@ -83,21 +83,21 @@ Each integration test can be run under either dev server mode or build mode. - `pnpm run test-build` runs tests only under build mode. -- You can also use `pnpm run test-serve [match]` or `pnpm run test-build [match]` to run tests in a specific playground package, e.g. `pnpm run test-serve asset` will run tests for both `playground/asset` and `vite/src/node/__tests__/asset` under serve mode and `vite/src/node/__tests__/**/*` just run in serve mode. +- `pnpm run test-serve [match]` or `pnpm run test-build [match]` runs tests in specific packages that match the given filter. e.g. `pnpm run test-serve asset` runs tests for both `playground/asset` and `vite/src/node/__tests__/asset` under serve mode. Note package matching is not available for the `pnpm test` script, which always runs all tests. ### Unit Tests -Other than tests under `playground/` for integration tests, packages might contains unit tests under their `__tests__` directory. Unit tests are powered by [Vitest](https://vitest.dev/). The detailed config is inside `vitest.config.ts` files. +Other than tests under `playground/` for integration tests, packages might contain unit tests under their `__tests__` directory. Unit tests are powered by [Vitest](https://vitest.dev/). The detailed config is inside `vitest.config.ts` files. - `pnpm run test-unit` runs unit tests under each package. -- You can also use `pnpm run test-unit [match]` to run related tests. +- `pnpm run test-unit [match]` runs tests in specific packages that match the given filter. ### Test Env and Helpers -Inside playground tests, you can import the `page` object from `~utils`, which is a Playwright [`Page`](https://playwright.dev/docs/api/class-page) instance that has already navigated to the served page of the current playground. So writing a test is as simple as: +Inside playground tests, you can import the `page` object from `~utils`, which is a Playwright [`Page`](https://playwright.dev/docs/api/class-page) instance that has already navigated to the served page of the current playground. So, writing a test is as simple as: ```js import { page } from '~utils' @@ -107,13 +107,13 @@ test('should work', async () => { }) ``` -Some common test helpers, e.g. `testDir`, `isBuild` or `editFile` are also available in the utils. Source code is located at `playground/test-utils.ts`. +Some common test helpers (e.g. `testDir`, `isBuild`, or `editFile`) are also available in the utils. Source code is located at `playground/test-utils.ts`. Note: The test build environment uses a [different default set of Vite config](https://github.com/vitejs/vite/blob/main/playground/vitestSetup.ts#L102-L122) to skip transpilation during tests to make it faster. This may produce a different result compared to the default production build. ### 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/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/main/playground/assets/index.html#L121): +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 is tested in the [assets playground](https://github.com/vitejs/vite/tree/main/playground/assets). In this Vite app, there is a test for `?raw` imports with [a section defined in the `index.html` for it](https://github.com/vitejs/vite/blob/main/playground/assets/index.html#L121): ```html

?raw import

@@ -127,7 +127,7 @@ import rawSvg from './nested/fragment.svg?raw' text('.raw', rawSvg) ``` -Where the `text` util is defined as: +...where the `text` util is defined as: ```js function text(el, text) { @@ -145,34 +145,34 @@ test('?raw import', async () => { ## Note on Test Dependencies -In many test cases we need to mock dependencies using `link:` and `file:` protocols. `pnpm` treats `link:` as symlinks and `file:` as hardlinks. To test dependencies as if they are copied into `node_modules`, use the `file:` protocol, other cases should use the `link:` protocol. +In many test cases, we need to mock dependencies using `link:` and `file:` protocols. `pnpm` treats `link:` as symlinks and `file:` as hardlinks. To test dependencies as if they were copied into `node_modules`, use the `file:` protocol. Otherwise, use the `link:` protocol. ## Debug Logging -You can set the `DEBUG` environment variable to turn on debugging logs. E.g. `DEBUG="vite:resolve"`. To see all debug logs you can set `DEBUG="vite:*"`, but be warned that it will be quite noisy. You can run `grep -r "createDebugger('vite:" packages/vite/src/` to see a list of available debug scopes. +You can set the `DEBUG` environment variable to turn on debugging logs (e.g. `DEBUG="vite:resolve"`). To see all debug logs, you can set `DEBUG="vite:*"`, but be warned that it will be quite noisy. You can run `grep -r "createDebugger('vite:" packages/vite/src/` to see a list of available debug scopes. ## Pull Request Guidelines -- Checkout a topic branch from a base branch, e.g. `main`, and merge back against that branch. +- Checkout a topic branch from a base branch (e.g. `main`), and merge back against that branch. - If adding a new feature: - Add accompanying test case. - - Provide a convincing reason to add this feature. Ideally, you should open a suggestion issue first and have it approved before working on it. + - Provide a convincing reason to add this feature. Ideally, you should open a suggestion issue first, and have it approved before working on it. -- If fixing bug: +- If fixing a bug: - - If you are resolving a special issue, add `(fix #xxxx[,#xxxx])` (#xxxx is the issue id) in your PR title for a better release log, e.g. `fix: update entities encoding/decoding (fix #3899)`. + - If you are resolving a special issue, add `(fix #xxxx[,#xxxx])` (#xxxx is the issue id) in your PR title for a better release log (e.g. `fix: update entities encoding/decoding (fix #3899)`). - Provide a detailed description of the bug in the PR. Live demo preferred. - Add appropriate test coverage if applicable. -- It's OK to have multiple small commits as you work on the PR - GitHub can automatically squash them before merging. +- It's OK to have multiple small commits as you work on the PR. GitHub can automatically squash them before merging. - Make sure tests pass! - Commit messages must follow the [commit message convention](./.github/commit-convention.md) so that changelogs can be automatically generated. Commit messages are automatically validated before commit (by invoking [Git Hooks](https://git-scm.com/docs/githooks) via [yorkie](https://github.com/yyx990803/yorkie)). -- No need to worry about code style as long as you have installed the dev dependencies - modified files are automatically formatted with Prettier on commit (by invoking [Git Hooks](https://git-scm.com/docs/githooks) via [yorkie](https://github.com/yyx990803/yorkie)). +- No need to worry about code style as long as you have installed the dev dependencies. Modified files are automatically formatted with Prettier on commit (by invoking [Git Hooks](https://git-scm.com/docs/githooks) via [yorkie](https://github.com/yyx990803/yorkie)). ## Maintenance Guidelines @@ -196,62 +196,41 @@ You can set the `DEBUG` environment variable to turn on debugging logs. E.g. `DE Vite aims to be lightweight, and this includes being aware of the number of npm dependencies and their size. -We use rollup to pre-bundle most dependencies before publishing! Therefore most dependencies, even used in src code, should be added under `devDependencies` by default. This also creates a number of constraints that we need to be aware of in the codebase: +We use Rollup to pre-bundle most dependencies before publishing! Therefore, most dependencies, even those used in runtime source code, should be added under `devDependencies` by default. This also creates the following constraints that we need to be aware of in the codebase. ### Usage of `require()` -In some cases we intentionally lazy-require some dependencies to improve startup performance. However, note that we cannot use simple `require('somedep')` calls since these are ignored in ESM files so the dependency won't be included in the bundle, and the actual dependency won't even be there when published since they are in `devDependencies`. +In some cases, we intentionally lazy-require some dependencies to improve start-up performance. However, note that we cannot use simple `require('somedep')` calls since these are ignored in ESM files, so the dependency won't be included in the bundle, and the actual dependency won't even be there when published since they are in `devDependencies`. Instead, use `(await import('somedep')).default`. -### Think before adding a dependency +### Think Before Adding a Dependency Most deps should be added to `devDependencies` even if they are needed at runtime. Some exceptions are: - Type packages. Example: `@types/*`. - Deps that cannot be properly bundled due to binary files. Example: `esbuild`. -- Deps that ships its own types and its type is used in vite's own public types. Example: `rollup`. +- Deps that ship their own types that are used in Vite's own public types. Example: `rollup`. -Avoid deps that has large transitive dependencies that results in bloated size compared to the functionality it provides. For example, `http-proxy` itself plus `@types/http-proxy` is a little over 1MB in size, but `http-proxy-middleware` pulls in a ton of dependencies that makes it 7MB(!) when a minimal custom middleware on top of `http-proxy` only requires a couple lines of code. +Avoid deps with large transitive dependencies that result in bloated size compared to the functionality it provides. For example, `http-proxy` itself plus `@types/http-proxy` is a little over 1MB in size, but `http-proxy-middleware` pulls in a ton of dependencies that make it 7MB(!) when a minimal custom middleware on top of `http-proxy` only requires a couple of lines of code. -### Ensure type support +### Ensure Type Support -Vite aims to be fully usable as a dependency in a TypeScript project (e.g. it should provide proper typings for VitePress), and also in `vite.config.ts`. This means technically a dependency whose types are exposed needs to be part of `dependencies` instead of `devDependencies`. However, these means we won't be able to bundle it. +Vite aims to be fully usable as a dependency in a TypeScript project (e.g. it should provide proper typings for VitePress), and also in `vite.config.ts`. This means technically a dependency whose types are exposed needs to be part of `dependencies` instead of `devDependencies`. However, this also means we won't be able to bundle it. -To get around this, we inline some of these dependencies' types in `packages/vite/types`. This way we can still expose the typing but bundle the dependency's source code. +To get around this, we inline some of these dependencies' types in `packages/vite/types`. This way, we can still expose the typing but bundle the dependency's source code. -Use `pnpm run check-dist-types` to check bundled types does not rely on types in `devDependencies`. If you are adding `dependencies`, make sure to configure `tsconfig.check.json`. +Use `pnpm run check-dist-types` to check that the bundled types do not rely on types in `devDependencies`. If you are adding `dependencies`, make sure to configure `tsconfig.check.json`. -### Think before adding yet another option +### Think Before Adding Yet Another Option -We already have many config options, and we should avoid fixing an issue by adding yet another one. Before adding an option, try to think about: +We already have many config options, and we should avoid fixing an issue by adding yet another one. Before adding an option, consider whether the problem: -- Whether the problem is really worth addressing -- Whether the problem can be fixed with a smarter default -- Whether the problem has workaround using existing options -- Whether the problem can be addressed with a plugin instead +- is really worth addressing +- can be fixed with a smarter default +- has workaround using existing options +- can be addressed with a plugin instead -## Docs translation contribution +## Docs Translation Contribution -If you would like to start a translation in your language, you are welcome to contribute! Please join [the #translations channel in Vite Land](https://chat.vitejs.dev) to discuss and coordinate with others. - -The english docs are embedded in the main Vite repo, to allow contributors to work on docs, tests and implementation in the same PR. Translations are done by forking the main repo. - -### How to start a translation repo - -1. In order to get all doc files, you first need to clone this repo in your personal account. -2. Keep all the files in `docs/` and remove everything else. - - - You should setup your translation site based on all the files in `docs/` folder as a VitePress project. - (that said, `package.json` is need). - - - Refresh git history by removing `.git` and then `git init` - -3. Translate the docs. - - - During this stage, you may be translating documents and synchronizing updates at the same time, but don't worry about that, it's very common in translation contribution. - -4. Push your commits to your GitHub repo. you can setup a netlify preview as well. -5. Use [Ryu-cho](https://github.com/vuejs-translations/ryu-cho) tool to setup a GitHub Action, automatically track English docs update later. - -We recommend talking with others in Vite Land so you find more contributors for your language to share the maintenance work. Once the translation is done, communicate it to the Vite team so the repo can be moved to the official vitejs org in GitHub. +To add a new language to the Vite docs, see [`vite-docs-template`](https://github.com/tony19/vite-docs-template/blob/main/.github/CONTRIBUTING.md). diff --git a/README.md b/README.md index fa452cb8bf7b1e..7449f11a54788b 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ - 🔩 Universal Plugin Interface - 🔑 Fully Typed APIs -Vite (French word for "quick", pronounced [`/vit/`](https://cdn.jsdelivr.net/gh/vitejs/vite@main/docs/public/vite.mp3), like "veet") is a new breed of frontend build tool that significantly improves the frontend development experience. It consists of two major parts: +Vite (French word for "quick", pronounced [`/vit/`](https://cdn.jsdelivr.net/gh/vitejs/vite@main/docs/public/vite.mp3), like "veet") is a new breed of frontend build tooling that significantly improves the frontend development experience. It consists of two major parts: - A dev server that serves your source files over [native ES modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules), with [rich built-in features](https://vitejs.dev/guide/features.html) and astonishingly fast [Hot Module Replacement (HMR)](https://vitejs.dev/guide/features.html#hot-module-replacement). @@ -33,17 +33,6 @@ In addition, Vite is highly extensible via its [Plugin API](https://vitejs.dev/g [Read the Docs to Learn More](https://vitejs.dev). -## v3.0 - -Current Status: **Alpha** (for internal testing, not recommended for production) - -The `main` branch is now for v3.0, if you are looking for current stable releases, check the [`v2` branch](https://github.com/vitejs/vite/tree/v2) branch instead. - -We will start drafting release notes and migration guide for v3.0 when we enter the beta stage. Before that you can check: - -- [v3.0 Milestone](https://github.com/vitejs/vite/milestone/5) -- [Breaking Change List](https://github.com/vitejs/vite/issues?q=label%3A%22breaking+change%22+is%3Aclosed+milestone%3A3.0) - ## Packages | Package | Version (click for changelogs) | diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 3f7762f2cdd2c4..010b599875f024 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -1,12 +1,60 @@ -import { defineConfig } from 'vitepress' +import { defineConfig, DefaultTheme } from 'vitepress' const ogDescription = 'Next Generation Frontend Tooling' -const ogImage = 'https://main.vitejs.dev/og-image.png' +const ogImage = 'https://vitejs.dev/og-image.png' const ogTitle = 'Vite' -const ogUrl = 'https://main.vitejs.dev' +const ogUrl = 'https://vitejs.dev' + +// netlify envs +const deployURL = process.env.DEPLOY_PRIME_URL || '' +const commitRef = process.env.COMMIT_REF?.slice(0, 8) || 'dev' + +const deployType = (() => { + switch (deployURL) { + case 'https://main--vite-docs-main.netlify.app': + return 'main' + case '': + return 'local' + default: + return 'release' + } +})() +const additionalTitle = ((): string => { + switch (deployType) { + case 'main': + return ' (main branch)' + case 'local': + return ' (local)' + case 'release': + return '' + } +})() +const versionLinks = ((): DefaultTheme.NavItemWithLink[] => { + switch (deployType) { + case 'main': + case 'local': + return [ + { + text: 'Vite 3 Docs (release)', + link: 'https://vitejs.dev' + }, + { + text: 'Vite 2 Docs', + link: 'https://v2.vitejs.dev' + } + ] + case 'release': + return [ + { + text: 'Vite 2 Docs', + link: 'https://v2.vitejs.dev' + } + ] + } +})() export default defineConfig({ - title: 'Vite', + title: `Vite${additionalTitle}`, description: 'Next Generation Frontend Tooling', head: [ @@ -15,11 +63,9 @@ export default defineConfig({ ['meta', { property: 'og:title', content: ogTitle }], ['meta', { property: 'og:image', content: ogImage }], ['meta', { property: 'og:url', content: ogUrl }], - ['meta', { property: 'twitter:description', content: ogDescription }], - ['meta', { property: 'twitter:title', content: ogTitle }], - ['meta', { property: 'twitter:card', content: 'summary_large_image' }], - ['meta', { property: 'twitter:image', content: ogImage }], - ['meta', { property: 'twitter:url', content: ogUrl }] + ['meta', { property: 'og:description', content: ogDescription }], + ['meta', { name: 'twitter:card', content: 'summary_large_image' }], + ['meta', { name: 'twitter:site', content: '@vite_js' }] ], vue: { @@ -41,6 +87,7 @@ export default defineConfig({ ], algolia: { + appId: 'BH4D9OD16A', apiKey: 'b573aa848fd57fb47d693b531297403c', indexName: 'vitejs', searchParameters: { @@ -63,7 +110,7 @@ export default defineConfig({ }, footer: { - message: 'Released under the MIT License.', + message: `Released under the MIT License. (${commitRef})`, copyright: 'Copyright © 2019-present Evan You & Vite Contributors' }, @@ -72,42 +119,42 @@ export default defineConfig({ { text: 'Config', link: '/config/', activeMatch: '/config/' }, { text: 'Plugins', link: '/plugins/', activeMatch: '/plugins/' }, { - text: 'Links', + text: 'Resources', items: [ + { text: 'Team', link: '/team' }, { - text: 'Twitter', - link: 'https://twitter.com/vite_js' - }, - { - text: 'Discord Chat', - link: 'https://chat.vitejs.dev' - }, - { - text: 'Awesome Vite', - link: 'https://github.com/vitejs/awesome-vite' - }, - { - text: 'DEV Community', - link: 'https://dev.to/t/vite' - }, - { - text: 'Rollup Plugins Compat', - link: 'https://vite-rollup-plugins.patak.dev/' - }, - { - text: 'Changelog', - link: 'https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md' + items: [ + { + text: 'Twitter', + link: 'https://twitter.com/vite_js' + }, + { + text: 'Discord Chat', + link: 'https://chat.vitejs.dev' + }, + { + text: 'Awesome Vite', + link: 'https://github.com/vitejs/awesome-vite' + }, + { + text: 'DEV Community', + link: 'https://dev.to/t/vite' + }, + { + text: 'Rollup Plugins Compat', + link: 'https://vite-rollup-plugins.patak.dev/' + }, + { + text: 'Changelog', + link: 'https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md' + } + ] } ] }, { - text: 'v3 (next)', - items: [ - { - text: 'v2.x (stable)', - link: 'https://v2.vitejs.dev' - } - ] + text: 'Version', + items: versionLinks } ], diff --git a/docs/.vitepress/theme/components/SvgImage.vue b/docs/.vitepress/theme/components/SvgImage.vue new file mode 100644 index 00000000000000..3440988030d2db --- /dev/null +++ b/docs/.vitepress/theme/components/SvgImage.vue @@ -0,0 +1,22 @@ + + + + + diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts index 3b4d7e38df76ab..39f1f2ffcae120 100644 --- a/docs/.vitepress/theme/index.ts +++ b/docs/.vitepress/theme/index.ts @@ -3,6 +3,7 @@ import Theme from 'vitepress/theme' import './styles/vars.css' import HomeSponsors from './components/HomeSponsors.vue' import AsideSponsors from './components/AsideSponsors.vue' +import SvgImage from './components/SvgImage.vue' export default { ...Theme, @@ -11,5 +12,8 @@ export default { 'home-features-after': () => h(HomeSponsors), 'aside-ads-before': () => h(AsideSponsors) }) + }, + enhanceApp({ app }) { + app.component('SvgImage', SvgImage) } } diff --git a/docs/.vitepress/theme/styles/vars.css b/docs/.vitepress/theme/styles/vars.css index feacdfcd2dfd4d..8022a97bda0903 100644 --- a/docs/.vitepress/theme/styles/vars.css +++ b/docs/.vitepress/theme/styles/vars.css @@ -6,6 +6,7 @@ --vp-c-brand: #646cff; --vp-c-brand-light: #747bff; --vp-c-brand-lighter: #9499ff; + --vp-c-brand-lightest: #bcc0ff; --vp-c-brand-dark: #535bf2; --vp-c-brand-darker: #454ce1; --vp-c-brand-dimm: rgba(100, 108, 255, 0.08); @@ -71,7 +72,7 @@ .dark { --vp-custom-block-tip-border: var(--vp-c-brand); - --vp-custom-block-tip-text: var(--vp-c-brand-lighter); + --vp-custom-block-tip-text: var(--vp-c-brand-lightest); --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); } @@ -82,3 +83,34 @@ .DocSearch { --docsearch-primary-color: var(--vp-c-brand) !important; } + +/** + * VitePress: Custom fix + * -------------------------------------------------------------------------- */ + +/* + Use lighter colors for links in dark mode for a11y. + Also specify some classes twice to have higher specificity + over scoped class data attribute. +*/ +.dark .vp-doc a, +.dark .vp-doc a > code, +.dark .VPNavBarMenuLink.VPNavBarMenuLink:hover, +.dark .VPNavBarMenuLink.VPNavBarMenuLink.active, +.dark .link.link:hover, +.dark .link.link.active, +.dark .edit-link-button.edit-link-button, +.dark .pager-link .title { + color: var(--vp-c-brand-lighter); +} + +.dark .vp-doc a:hover, +.dark .vp-doc a > code:hover { + color: var(--vp-c-brand-lightest); + opacity: 1; +} + +/* Transition by color instead of opacity */ +.dark .vp-doc .custom-block a { + transition: color 0.25s; +} diff --git a/docs/_data/team.js b/docs/_data/team.js new file mode 100644 index 00000000000000..43b56ad5bf481b --- /dev/null +++ b/docs/_data/team.js @@ -0,0 +1,152 @@ +export const core = [ + { + avatar: 'https://www.github.com/yyx990803.png', + name: 'Evan You', + title: 'Creator', + org: 'Vue.js', + orgLink: 'https://vuejs.org/', + desc: 'Husband, father of two, independent open source developer.', + links: [ + { icon: 'github', link: 'https://github.com/yyx990803' }, + { icon: 'twitter', link: 'https://twitter.com/youyuxi' } + ], + sponsor: 'https://github.com/sponsors/yyx990803' + }, + { + avatar: 'https://www.github.com/patak-dev.png', + name: 'Patak', + title: 'A collaborative being', + org: 'StackBlitz', + orgLink: 'https://stackblitz.com/', + desc: 'Core team member of Vite. Team member of Vue.', + links: [ + { icon: 'github', link: 'https://github.com/patak-dev' }, + { icon: 'twitter', link: 'https://twitter.com/patak_dev' } + ], + sponsor: 'https://github.com/sponsors/patak-dev' + }, + { + avatar: 'https://www.github.com/antfu.png', + name: 'Anthony Fu', + title: 'A fanatical open sourceror', + org: 'NuxtLabs', + orgLink: 'https://nuxtlabs.com/', + desc: 'Core team member of Vite & Vue. Working at NuxtLabs.', + links: [ + { icon: 'github', link: 'https://github.com/antfu' }, + { icon: 'twitter', link: 'https://twitter.com/antfu7' } + ], + sponsor: 'https://github.com/sponsors/antfu' + }, + { + avatar: 'https://github.com/sodatea.png', + name: 'Haoqun Jiang', + title: 'Developer', + org: 'Vue.js', + orgLink: 'https://vuejs.org/', + desc: 'Vite/Vite core team member. Full-time open sourcerer.', + links: [ + { icon: 'github', link: 'https://github.com/sodatea' }, + { icon: 'twitter', link: 'https://twitter.com/haoqunjiang' } + ], + sponsor: 'https://github.com/sponsors/sodatea' + }, + { + avatar: 'https://github.com/Shinigami92.png', + name: 'Shinigami', + title: 'Maintainer', + org: 'Faker', + orgLink: 'https://fakerjs.dev', + desc: 'Passionate TypeScript enthusiast working extensively with Vue SPA and pug.', + links: [ + { icon: 'github', link: 'https://github.com/Shinigami92' }, + { icon: 'twitter', link: 'https://twitter.com/Shini_92' } + ], + sponsor: 'https://github.com/sponsors/Shinigami92' + }, + { + avatar: 'https://i.imgur.com/KMed6rQ.jpeg', + name: 'Alec Larson', + title: 'Entrepreneur', + desc: 'Dabbling in social ecommerce, meta frameworks, and board games', + links: [ + { icon: 'github', link: 'https://github.com/aleclarson' }, + { icon: 'twitter', link: 'https://twitter.com/retropragma' } + ], + sponsor: 'https://github.com/sponsors/aleclarson' + }, + { + avatar: 'https://github.com/bluwy.png', + name: 'Bjorn Lu', + title: 'Frontend Developer', + desc: 'Svelte and Vite team member. Something something opinions.', + links: [ + { icon: 'github', link: 'https://github.com/bluwy' }, + { icon: 'twitter', link: 'https://twitter.com/bluwyoo' } + ], + sponsor: 'https://bjornlu.com/sponsor' + }, + { + avatar: 'https://github.com/poyoho.png', + name: 'yoho', + title: 'Frontend Developer', + desc: 'Frontend. Vite team member.', + links: [ + { icon: 'github', link: 'https://github.com/poyoho' }, + { icon: 'twitter', link: 'https://twitter.com/yoho_po' } + ] + }, + { + avatar: 'https://github.com/sapphi-red.png', + name: 'green', + title: 'Web Developer', + desc: 'Vite team member. Call me sapphi or green or midori ;)', + links: [ + { icon: 'github', link: 'https://github.com/sapphi-red' }, + { icon: 'twitter', link: 'https://twitter.com/sapphi_red' } + ], + sponsor: 'https://github.com/sponsors/sapphi-red' + }, + { + avatar: 'https://github.com/ygj6.png', + name: 'ygj6', + title: 'Developer', + desc: 'Web Developer. Vue & Vite team member', + links: [ + { icon: 'github', link: 'https://github.com/ygj6' }, + { icon: 'twitter', link: 'https://twitter.com/ygj_66' } + ] + }, + { + avatar: 'https://github.com/Niputi.png', + name: 'Niputi', + title: 'Developer', + org: 'Computershare Denmark', + desc: 'weeb/javascript lover.', + links: [ + { icon: 'github', link: 'https://github.com/Niputi' }, + { icon: 'twitter', link: 'https://twitter.com/Niputi_' } + ] + } +] + +export const emeriti = [ + { + avatar: 'https://github.com/underfin.png', + name: 'underfin', + title: 'Developer', + links: [{ icon: 'github', link: 'https://github.com/underfin' }] + }, + { + avatar: 'https://github.com/GrygrFlzr.png', + name: 'GrygrFlzr', + title: 'Developer', + links: [{ icon: 'github', link: 'https://github.com/GrygrFlzr' }] + }, + { + avatar: 'https://github.com/nihalgonsalves.png', + name: 'Nihal Gonsalves', + title: 'Senior Software Engineer', + links: [{ icon: 'github', link: 'https://github.com/nihalgonsalves' }] + } +] diff --git a/docs/blog/announcing-vite3.md b/docs/blog/announcing-vite3.md new file mode 100644 index 00000000000000..e17d29be1b4c89 --- /dev/null +++ b/docs/blog/announcing-vite3.md @@ -0,0 +1,270 @@ +--- +sidebar: false +head: + - - meta + - property: og:type + content: website + - - meta + - property: og:title + content: Announcing Vite 3 + - - meta + - property: og:image + content: https://vitejs.dev/og-image-announcing-vite3.png + - - meta + - property: og:url + content: https://vitejs.dev/blog/announcing-vite3 + - - meta + - property: og:description + content: Vite 3 Release Announcement + - - meta + - name: twitter:card + content: summary_large_image +--- + +# Vite 3.0 is out! + +In February last year, [Evan You](https://twitter.com/youyuxi) released Vite 2. Since then, its adoption has grown non-stop, reaching more than 1 million npm downloads per week. A sprawling ecosystem rapidly formed after the release. Vite is powering a renewed innovation race in Web frameworks. [Nuxt 3](https://v3.nuxtjs.org/) uses Vite by default. [SvelteKit](https://kit.svelte.dev/), [Astro](https://astro.build/), [Hydrogen](https://hydrogen.shopify.dev/), and [SolidStart](https://docs.solidjs.com/start) are all built with Vite. [Laravel has now decided to use Vite by default](https://laravel.com/docs/9.x/vite). [Vite Ruby](https://vite-ruby.netlify.app/) shows how Vite can improve Rails DX. [Vitest](https://vitest.dev) is making strides as a Vite-native alternative to Jest. Vite is behind [Cypress](https://docs.cypress.io/guides/component-testing/writing-your-first-component-test) and [Playwright](https://playwright.dev/docs/test-components)'s new Component Testing features, Storybook has [Vite as an official builder](https://github.com/storybookjs/builder-vite). And [the list goes on](https://patak.dev/vite/ecosystem.html). Maintainers from most of these projects got involved in improving the Vite core itself, working closely with the Vite [team](https://vitejs.dev/team) and other contributors. + +![Vite 3 Announcement Cover Image](/og-image-announcing-vite3.png) + +Today, 16 months from the v2 launch we are happy to announce the release of Vite 3. We decided to release a new Vite major at least every year to align with [Node.js's EOL](https://nodejs.org/en/about/releases/), and take the opportunity to review Vite's API regularly with a short migration path for projects in the ecosystem. + +Quick links: + +- [Docs](/) +- [Migration Guide](/guide/migration) +- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md#300-2022-07-13) + +If you are new to Vite, we recommend reading the [Why Vite Guide](https://vitejs.dev/guide/why.html). Then check out [the Getting Started](https://vitejs.dev/guide/) and [Features guide](https://vitejs.dev/guide/features) to see what Vite provides out of the box. As usual, contributions are welcome at [GitHub](https://github.com/vitejs/vite). More than [600 collaborators](https://github.com/vitejs/vite/graphs/contributors) have helped improve Vite so far. Follow the updates on [Twitter](https://twitter.com/vite_js), or join discussions with other Vite users on our [Discord chat server](http://chat.vitejs.dev/). + +## New Documentation + +Go to [vitejs.dev](https://vitejs.dev) to enjoy the new v3 docs. Vite is now using the new [VitePress](https://vitepress.vuejs.org) default theme, with a stunning dark mode between other features. + +[![Vite documentation frontpage](../images/v3-docs.png)](https://vitejs.dev) + +Several projects in the ecosystem have already migrated to it (see [Vitest](https://vitest.dev), [vite-plugin-pwa](https://vite-plugin-pwa.netlify.app/), and [VitePress](https://vitepress.vuejs.org/) itself). + +If you need to access the Vite 2 docs, they will remain online at [v2.vitejs.dev](https://v2.vitejs.dev). There is also a new [main.vitejs.dev](https://main.vitejs.dev) subdomain, where each commit to Vite’s main branch is auto deployed. This is useful when testing beta versions or contributing to the core’s development. + +There is also now an official Spanish translation, that has been added to the previous Chinese and Japanese translations: + +- [简体中文](https://cn.vitejs.dev/) +- [日本語](https://ja.vitejs.dev/) +- [Español](https://es.vitejs.dev/) + +## Create Vite Starter Templates + +[create-vite](/guide/#trying-vite-online) templates have been a great tool to quickly test Vite with your favorite framework. In Vite 3, all of the templates got a new theme in line with the new docs. Open them online and start playing with Vite 3 now: + + + + + +The theme is now shared by all templates. This should help better convey the scope for these starters as minimal templates to get started with Vite. For more complete solutions including linting, testing setup, and other features, there are official Vite-powered templates for some frameworks like [create-vue](https://github.com/vuejs/create-vue) and [create-svelte](https://github.com/sveltejs/kit). There is a community-maintained list of templates at [Awesome Vite](https://github.com/vitejs/awesome-vite#templates). + +## Dev Improvements + +### Vite CLI + +
+  VITE v3.0.0  ready in 320 ms
+
+    Local:   http://127.0.0.1:5173/
+    Network: use --host to expose
+
+ +Apart from the CLI’s aesthetics improvements, you’ll notice that the default dev server port is now 5173 and the preview server listening at 4173. This change ensures Vite will avoid collisions with other tools. + +### Improved WebSocket Connection Strategy + +One of the pain points of Vite 2 was configuring the server when running behind a proxy. Vite 3 changes the default connection scheme so it works out of the box in most scenarios. All these setups are now tested as part of the Vite Ecosystem CI through [`vite-setup-catalogue`](https://github.com/sapphi-red/vite-setup-catalogue). + +### Cold Start Improvements + +Vite now avoids full reload during cold start when imports are injected by plugins while crawling the initial statically imported modules ([#8869](https://github.com/vitejs/vite/issues/8869)). + +
+ Click to learn more + +In Vite 2.9, both the scanner and optimizer were run in the background. In the best scenario, where the scanner would find every dependency, no reload was needed in cold start. But if the scanner missed a dependency, a new optimization phase and then a reload were needed. Vite was able to avoid some of these reloads in v2.9, as we detected if the new optimized chunks were compatible with the ones the browser had. But if there was a common dep, the sub-chunks could change and a reload was required to avoid duplicated state. In Vite 3, the optimized deps aren't handed to the browser until the crawling of static imports is done. A quick optimization phase is issued if there is a missing dep (for example, injected by a plugin), and only then, the bundled deps are sent. So, a page reload is no longer needed for these cases. + +
+ +Two graphs comparing Vite 2.9 and Vite 3 optimization strategy + +### import.meta.glob + +`import.meta.glob` support was rewritten. Read about the new features in the [Glob Import Guide](/guide/features.html#glob-import): + +[Multiple Patterns](/guide/features.html#multiple-patterns) can be passed as an array + +```js +import.meta.glob(['./dir/*.js', './another/*.js']) +``` + +[Negative Patterns](/guide/features.html#negative-patterns) are now supported (prefixed with `!`) to ignore some specific files + +```js +import.meta.glob(['./dir/*.js', '!**/bar.js']) +``` + +[Named Imports](/guide/features.html#named-imports) can be specified to improve tree-shaking + +```js +import.meta.glob('./dir/*.js', { import: 'setup' }) +``` + +[Custom Queries](/guide/features.html#custom-queries) can be passed to attach metadata + +```js +import.meta.glob('./dir/*.js', { query: { custom: 'data' } }) +``` + +[Eager Imports](/guide/features.html#glob-import) is now passed as a flag + +```js +import.meta.glob('./dir/*.js', { eager: true }) +``` + +### Aligning WASM Import with Future Standards + +The WebAssembly import API has been revised to avoid collisions with future standards and to make it more flexible: + +```js +import init from './example.wasm?init' + +init().then((instance) => { + instance.exports.test() +}) +``` + +Learn more in the [WebAssembly guide](/guide/features.html#webassembly) + +## Build Improvements + +### ESM SSR Build by Default + +Most SSR frameworks in the ecosystem were already using ESM builds. So, Vite 3 makes ESM the default format for SSR builds. This allows us to streamline previous [SSR externalization heuristics](https://vitejs.dev/guide/ssr.html#ssr-externals), externalizing dependencies by default. + +### Improved Relative Base Support + +Vite 3 now properly supports relative base (using `base: ''`), allowing built assets to be deployed to different bases without re-building. This is useful when the base isn't known at build time, for example when deploying to content-addressable networks like [IPFS](https://ipfs.io/). + +## Experimental Features + +### Built Asset Paths fine-grained Control (Experimental) + +There are other deploy scenarios where this isn't enough. For example, if the generated hashed assets need to be deployed to a different CDN from the public files, then finer-grained control is required over path generation at build time. Vite 3 provides an experimental API to modify the built file paths. Check [Build Advanced Base Options](/guide/build.html#advanced-base-options) for more information. + +### Esbuild Deps Optimization at Build Time (Experimental) + +One of the main differences between dev and build time is how Vite handles dependencies. During build time, [`@rollupjs/plugin-commonjs`](https://github.com/rollup/plugins/tree/master/packages/commonjs) is used to allow importing CJS only dependencies (like React). When using the dev server, esbuild is used instead to pre-bundle and optimize dependencies, and an inline interop scheme is applied while transforming user code importing CJS deps. During the development of Vite 3, we introduced the changes needed to also allow the use of [esbuild to optimize dependencies during build time](/guide/migration.html#using-esbuild-deps-optimization-at-build-time). [`@rollupjs/plugin-commonjs`](https://github.com/rollup/plugins/tree/master/packages/commonjs) can then be avoided, making dev and build time work in the same way. + +Given that Rollup v3 will be out in the next months, and we're going to follow up with another Vite major, we've decided to make this mode optional to reduce v3 scope and give Vite and the ecosystem more time to work out possible issues with the new CJS interop approach during build time. Frameworks may switch to using esbuild deps optimization during build time by default at their own pace before Vite 4. + +### HMR Partial Accept (Experimental) + +There is opt-in support for [HMR Partial Accept](https://github.com/vitejs/vite/pull/7324). This feature could unlock finer-grained HMR for framework components that export several bindings in the same module. You can learn more at [the discussion for this proposal](https://github.com/vitejs/vite/discussions/7309). + +## Bundle Size Reduction + +Vite cares about its publish and install footprint; a fast installation of a new app is a feature. Vite bundles most of its dependencies and tries to use modern lightweight alternatives where possible. Continuing with this ongoing goal, Vite 3 publish size is 30% smaller than v2. + +| | Publish Size | Install Size | +| ----------- | :----------: | :----------: | +| Vite 2.9.14 | 4.38MB | 19.1MB | +| Vite 3.0.0 | 3.05MB | 17.8MB | +| Reduction | -30% | -7% | + +In part, this reduction was possible by making some dependencies that most users weren't needing optional. First, [Terser](https://github.com/terser/terser) is no longer installed by default. This dependency was no longer needed since we already made esbuild the default minifier for both JS and CSS in Vite 2. If you use `build.minify: 'terser'`, you'll need to install it (`npm add -D terser`). We also moved [node-forge](https://github.com/digitalbazaar/forge) out of the monorepo, implementing support for automatic https certificate generation as a new plugin: [`@vitejs/plugin-basic-ssl`](/guide/migration.html#automatic-https-certificate-generation). Since this feature only creates untrusted certificates that are not added to the local store, it didn't justify the added size. + +## Bug Fixing + +A triaging marathon was spearheaded by [@bluwyoo](https://twitter.com/bluwyoo), [@sapphi_red](https://twitter.com/sapphi_red), that recently joined the Vite team. During the past three months, the Vite open issues were reduced from 770 to 400. And this dive was achieved while the newly open PRs were at an all-time high. At the same time, [@haoqunjiang](https://twitter.com/haoqunjiang) had also curated a comprehensive [overview of Vite issues](https://github.com/vitejs/vite/discussions/8232). + +[![Graph of open issues and pull requests in Vite](../images/v3-open-issues-and-PRs.png)](https://www.repotrends.com/vitejs/vite) + +[![Graph of new issues and pull requests in Vite](../images/v3-new-open-issues-and-PRs.png)](https://www.repotrends.com/vitejs/vite) + +## Compatibility Notes + +- Vite no longer supports Node.js 12 / 13 / 15, which reached its EOL. Node.js 14.18+ / 16+ is now required. +- Vite is now published as ESM, with a CJS proxy to the ESM entry for compatibility. +- The Modern Browser Baseline now targets browsers which support the [native ES Modules](https://caniuse.com/es6-module), [native ESM dynamic import](https://caniuse.com/es6-module-dynamic-import), and [`import.meta`](https://caniuse.com/mdn-javascript_statements_import_meta) features. +- JS file extensions in SSR and library mode now use a valid extension (`js`, `mjs`, or `cjs`) for output JS entries and chunks based on their format and the package type. + +Learn more in the [Migration Guide](/guide/migration). + +## Upgrades to Vite Core + +While working towards Vite 3, we also improved the contributing experience for collaborators to [Vite Core](https://github.com/vitejs/vite). + +- Unit and E2E tests have been migrated to [Vitest](https://vitest.dev), providing a faster and more stable DX. This move also works as dog fooding for an important infrastructure project in the ecosystem. +- VitePress build is now tested as part of CI. +- Vite upgraded to [pnpm 7](https://pnpm.io/), following the rest of the ecosystem. +- Playgrounds have been moved to [`/playgrounds`](https://github.com/vitejs/vite/tree/main/playground) out of packages directory. +- The packages and playgrounds are now `"type": "module"`. +- Plugins are now bundled using [unbuild](https://github.com/unjs/unbuild), and [plugin-vue-jsx](https://github.com/vitejs/vite/tree/main/packages/plugin-vue-jsx) and [plugin-legacy](https://github.com/vitejs/vite/tree/main/packages/plugin-legacy) were moved to TypeScript. + +## The Ecosystem is Ready for v3 + +We have worked closely with projects in the ecosystem to ensure that frameworks powered by Vite are ready for Vite 3. [vite-ecosystem-ci](https://github.com/vitejs/vite-ecosystem-ci) allows us to run the CI's from the leading players in the ecosystem against Vite's main branch and receive timely reports before introducing a regression. Today's release should soon be compatible with most projects using Vite. + +## Acknowledgments + +Vite 3 is the result of the aggregate effort of members of the [Vite Team](/team) working together with ecosystem project maintainers and other collaborators to Vite core. + +We want to thank everyone that have implemented features, and fixes, given feedback, and have been involved in Vite 3: + +- Vite team members [@youyuxi](https://twitter.com/youyuxi), [@patak_dev](https://twitter.com/patak_dev), [@antfu7](https://twitter.com/antfu7), [@bluwyoo](https://twitter.com/bluwyoo), [@sapphi_red](https://twitter.com/sapphi_red), [@haoqunjiang](https://twitter.com/haoqunjiang), [@poyoho](https://github.com/poyoho), [@Shini_92](https://twitter.com/Shini_92), and [@retropragma](https://twitter.com/retropragma). +- [@benmccann](https://github.com/benmccann), [@danielcroe](https://twitter.com/danielcroe), [@brillout](https://twitter.com/brillout), [@sheremet_va](https://twitter.com/sheremet_va), [@userquin](https://twitter.com/userquin), [@enzoinnocenzi](https://twitter.com/enzoinnocenzi), [@maximomussini](https://twitter.com/maximomussini), [@IanVanSchooten](https://twitter.com/IanVanSchooten), the [Astro team](https://astro.build/), and all other maintainers of frameworks and plugins in the ecosystem in that helped shape v3. +- [@dominikg](https://github.com/dominikg) for his work on vite-ecosystem-ci. +- [@ZoltanKochan](https://twitter.com/ZoltanKochan) for his work on [pnpm](https://pnpm.io/), and for his responsivness when we needed support with it. +- [@rixo](https://github.com/rixo) for HMR Partial Accept support. +- [@KiaKing85](https://twitter.com/KiaKing85) for getting the theme ready for the Vite 3 release, and [@\_brc_dd](https://twitter.com/_brc_dd) for working on the VitePress internals. +- [@CodingWithCego](https://twitter.com/CodingWithCego) for the new Spanish translation, and [@ShenQingchuan](https://twitter.com/ShenQingchuan), [@hiro-lapis](https://github.com/hiro-lapis) and others in the Chinese and Japanese translations teams for keeping the translated docs up to date. + +We also want to thank individuals and companies sponsoring the Vite team, and companies investing in Vite development: some of [@antfu7](https://twitter.com/antfu7)'s work on Vite and the ecosystem is part of his job at [Nuxt Labs](https://nuxtlabs.com/), and [StackBlitz](https://stackblitz.com/) hired [@patak_dev](https://twitter.com/patak_dev) to work full time on Vite. + +## What's Next + +We'll take the following months to ensure a smooth transition for all the projects built on top of Vite. So the first minors will be focused on continuing our triaging efforts with a focus on newly opened issues. + +The Rollup team is [working on its next major](https://twitter.com/lukastaegert/status/1544186847399743488), to be released in the following months. Once the Rollup plugins ecosystem has time to update, we'll follow up with a new Vite major. This will give us another opportunity to introduce more significant changes this year, which we could take to stabilize some of the experimental features introduced in this release. + +If you are interested in helping improve Vite, the best way to get on board is to help with triaging issues. Join [our Discord](https://chat.vitejs.dev) and look for the `#contributing` channel. Or get involved in our `#docs`, `#help` others, or create plugins. We are just getting started. There are many open ideas to keep improving Vite's DX. diff --git a/docs/config/build-options.md b/docs/config/build-options.md index e4882e111c51ee..f2c9598f752ada 100644 --- a/docs/config/build-options.md +++ b/docs/config/build-options.md @@ -180,12 +180,12 @@ By default, Vite will empty the `outDir` on build if it is inside project root. Enable/disable gzip-compressed size reporting. Compressing large output files can be slow, so disabling this may increase build performance for large projects. -### build.chunkSizeWarningLimit +## build.chunkSizeWarningLimit - **Type:** `number` - **Default:** `500` - Limit for chunk size warnings (in kbs). +Limit for chunk size warnings (in kbs). ## build.watch diff --git a/docs/config/index.md b/docs/config/index.md index cab69067574a3b..48254361328e1e 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -15,7 +15,7 @@ export default { } ``` -Note Vite supports using ES modules syntax in the config file even if the project is not using native Node ESM via `type: "module"`. In this case, the config file is auto pre-processed before load. +Note Vite supports using ES modules syntax in the config file even if the project is not using native Node ESM, e.g. `type: "module"` in `package.json`. In this case, the config file is auto pre-processed before load. You can also explicitly specify a config file to use with the `--config` CLI option (resolved relative to `cwd`): @@ -23,19 +23,6 @@ You can also explicitly specify a config file to use with the `--config` CLI opt vite --config my-config.js ``` -::: tip NOTE -Vite will inject `__filename`, `__dirname` in config files and its deps. Declaring these variables at top level will result in an error: - -```js -const __filename = 'value' // SyntaxError: Identifier '__filename' has already been declared - -const func = () => { - const __filename = 'value' // no error -} -``` - -::: - ## Config Intellisense Since Vite ships with TypeScript typings, you can leverage your IDE's intellisense with jsdoc type hints: @@ -80,7 +67,7 @@ export default defineConfig(({ command, mode, ssrBuild }) => { It is important to note that in Vite's API the `command` value is `serve` during dev (in the cli `vite`, `vite dev`, and `vite serve` are aliases), and `build` when building for production (`vite build`). -Only `ssrBuild` is included instead of a more general `ssr` flag because, during dev, the config is shared by the single server handling SSR and non-SSR requests. +`ssrBuild` is experimental. It is only available during build instead of a more general `ssr` flag because, during dev, the config is shared by the single server handling SSR and non-SSR requests. The value could be `undefined` for tools that don't have separate commands for the browser and SSR build, so use explicit comparison against `true` and `false`. ## Async Config diff --git a/docs/config/server-options.md b/docs/config/server-options.md index 6a5ae5ebab3aa4..33208bd4b04155 100644 --- a/docs/config/server-options.md +++ b/docs/config/server-options.md @@ -14,9 +14,9 @@ This can be set via the CLI using `--host 0.0.0.0` or `--host`. There are cases when other servers might respond instead of Vite. -The first case is when `localhost` is used. Node.js below v17 reorders the result of DNS-resolved address by default. When accessing `localhost`, browsers use DNS to resolve the address and that address might differ from the address which Vite is listening. Vite prints the resolved address when it differs. +The first case is when `localhost` is used. Node.js under v17 reorders the result of DNS-resolved address by default. When accessing `localhost`, browsers use DNS to resolve the address and that address might differ from the address which Vite is listening. Vite prints the resolved address when it differs. -You could set [`dns.setDefaultResultOrder('verbatim')`](https://nodejs.org/api/dns.html#dns_dns_setdefaultresultorder_order) to disable the reordering behavior. Or you could set `server.host` to `127.0.0.1` explicitly. +You can set [`dns.setDefaultResultOrder('verbatim')`](https://nodejs.org/api/dns.html#dns_dns_setdefaultresultorder_order) to disable the reordering behavior. Vite will then print the address as `localhost`. ```js // vite.config.js @@ -55,6 +55,8 @@ Enable TLS + HTTP/2. Note this downgrades to TLS only when the [`server.proxy` o The value can also be an [options object](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener) passed to `https.createServer()`. +A valid certificate is needed. For a basic setup, you can add [@vitejs/plugin-basic-ssl](https://github.com/vitejs/vite-plugin-basic-ssl) to the project plugins, which will automatically create and cache a self-signed certificate. But we recommend creating your own certificates. + ## server.open - **Type:** `boolean | string` @@ -196,8 +198,8 @@ Create Vite server in middleware mode. - **Example:** ```js -const express = require('express') -const { createServer: createViteServer } = require('vite') +import express from 'express' +import { createServer as createViteServer } from 'vite' async function createServer() { const app = express() diff --git a/docs/config/ssr-options.md b/docs/config/ssr-options.md index 83f90b02c92a37..a9a2fa9fdd8a4d 100644 --- a/docs/config/ssr-options.md +++ b/docs/config/ssr-options.md @@ -1,20 +1,16 @@ # SSR Options -- **Related:** [SSR Externals](/guide/ssr#ssr-externals) - -:::warning Experimental -SSR options may be adjusted in minor releases. -::: - ## ssr.external - **Type:** `string[]` +- **Related:** [SSR Externals](/guide/ssr#ssr-externals) Force externalize dependencies for SSR. ## ssr.noExternal - **Type:** `string | RegExp | (string | RegExp)[] | true` +- **Related:** [SSR Externals](/guide/ssr#ssr-externals) Prevent listed dependencies from being externalized for SSR. If `true`, no dependencies are externalized. @@ -27,8 +23,8 @@ Build target for the SSR server. ## ssr.format +- **Experimental** - **Type:** `'esm' | 'cjs'` - **Default:** `esm` -- **Experimental** Build format for the SSR server. Since Vite v3 the SSR build generates ESM by default. `'cjs'` can be selected to generate a CJS build, but it isn't recommended. The option is left marked as experimental to give users more time to update to ESM. CJS builds requires complex externalization heuristics that aren't present in the ESM format. diff --git a/docs/guide/api-javascript.md b/docs/guide/api-javascript.md index 33202e0d608238..205d32a6070cda 100644 --- a/docs/guide/api-javascript.md +++ b/docs/guide/api-javascript.md @@ -13,7 +13,10 @@ async function createServer(inlineConfig?: InlineConfig): Promise **Example Usage:** ```js -const { createServer } = require('vite') +import { fileURLToPath } from 'url' +import { createServer } from 'vite' + +const __dirname = fileURLToPath(new URL('.', import.meta.url)) ;(async () => { const server = await createServer({ @@ -41,6 +44,13 @@ 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. +## `ResolvedConfig` + +The `ResolvedConfig` interface has all the same properties of a `UserConfig`, except most properties are resolved and non-undefined. It also contains utilities like: + +- `config.assetsInclude`: A function to check if an `id` is considered an asset. +- `config.logger`: Vite's internal logger object. + ## `ViteDevServer` ```ts @@ -134,8 +144,11 @@ async function build( **Example Usage:** ```js -const path = require('path') -const { build } = require('vite') +import path from 'path' +import { fileURLToPath } from 'url' +import { build } from 'vite' + +const __dirname = fileURLToPath(new URL('.', import.meta.url)) ;(async () => { await build({ @@ -161,8 +174,7 @@ async function preview(inlineConfig?: InlineConfig): Promise **Example Usage:** ```js -const { preview } = require('vite') - +import { preview } from 'vite' ;(async () => { const previewServer = await preview({ // any valid user config options, plus `mode` and `configFile` @@ -184,12 +196,74 @@ const { preview } = require('vite') async function resolveConfig( inlineConfig: InlineConfig, command: 'build' | 'serve', - defaultMode?: string + defaultMode = 'development' ): Promise ``` The `command` value is `serve` in dev (in the cli `vite`, `vite dev`, and `vite serve` are aliases). +## `mergeConfig` + +**Type Signature:** + +```ts +function mergeConfig( + defaults: Record, + overrides: Record, + isRoot = true +): Record +``` + +Deeply merge two Vite configs. `isRoot` represents the level within the Vite config which is being merged. For example, set `false` if you're merging two `build` options. + +## `searchForWorkspaceRoot` + +**Type Signature:** + +```ts +function searchForWorkspaceRoot( + current: string, + root = searchForPackageRoot(current) +): string +``` + +**Related:** [server.fs.allow](/config/server-options.md#server-fs-allow) + +Search for the root of the potential workspace if it meets the following conditions, otherwise it would fallback to `root`: + +- contains `workspaces` field in `package.json` +- contains one of the following file + - `lerna.json` + - `pnpm-workspace.yaml` + +## `loadEnv` + +**Type Signature:** + +```ts +function loadEnv( + mode: string, + envDir: string, + prefixes: string | string[] = 'VITE_' +): Record +``` + +**Related:** [`.env` Files](./env-and-mode.md#env-files) + +Load `.env` files within the `envDir`. By default only env variables prefixed with `VITE_` are loaded, unless `prefixes` is changed. + +## `normalizePath` + +**Type Signature:** + +```ts +function normalizePath(id: string): string +``` + +**Related:** [Path Normalization](./api-plugin.md#path-normalization) + +Normalizes a path to interoperate between Vite plugins. + ## `transformWithEsbuild` **Type Signature:** @@ -202,3 +276,24 @@ async function transformWithEsbuild( inMap?: object ): Promise ``` + +Transform JavaScript or TypeScript with esbuild. Useful for plugins that prefers matching Vite's internal esbuild transform. + +## `loadConfigFromFile` + +**Type Signature:** + +```ts +async function loadConfigFromFile( + configEnv: ConfigEnv, + configFile?: string, + configRoot: string = process.cwd(), + logLevel?: LogLevel +): Promise<{ + path: string + config: UserConfig + dependencies: string[] +} | null> +``` + +Load a Vite config file manually with esbuild. diff --git a/docs/guide/api-plugin.md b/docs/guide/api-plugin.md index 968505906b1c39..89c71cfdeecee7 100644 --- a/docs/guide/api-plugin.md +++ b/docs/guide/api-plugin.md @@ -11,7 +11,7 @@ Vite strives to offer established patterns out of the box, so before creating a When creating a plugin, you can inline it in your `vite.config.js`. There is no need to create a new package for it. Once you see that a plugin was useful in your projects, consider sharing it to help others [in the ecosystem](https://chat.vitejs.dev). ::: tip -When learning, debugging, or authoring plugins we suggest including [vite-plugin-inspect](https://github.com/antfu/vite-plugin-inspect) in your project. It allows you to inspect the intermediate state of Vite plugins. After installing, you can visit `localhost:5173/__inspect/` to inspect the modules and transformation stack of your project. Check out install instructions in the [vite-plugin-inspect docs](https://github.com/antfu/vite-plugin-inspect). +When learning, debugging, or authoring plugins, we suggest including [vite-plugin-inspect](https://github.com/antfu/vite-plugin-inspect) in your project. It allows you to inspect the intermediate state of Vite plugins. After installing, you can visit `localhost:5173/__inspect/` to inspect the modules and transformation stack of your project. Check out install instructions in the [vite-plugin-inspect docs](https://github.com/antfu/vite-plugin-inspect). ![vite-plugin-inspect](/images/vite-plugin-inspect.png) ::: @@ -199,7 +199,7 @@ Vite plugins can also provide hooks that serve Vite-specific purposes. These hoo name: 'mutate-config', config(config, { command }) { if (command === 'build') { - config.root = __dirname + config.root = 'foo' } } }) diff --git a/docs/guide/assets.md b/docs/guide/assets.md index a9483a610faccc..4ba6e417bd3d40 100644 --- a/docs/guide/assets.md +++ b/docs/guide/assets.md @@ -113,7 +113,3 @@ const imgUrl = new URL(imagePath, import.meta.url).href ::: warning Does not work with SSR This pattern does not work if you are using Vite for Server-Side Rendering, because `import.meta.url` have different semantics in browsers vs. Node.js. The server bundle also cannot determine the client host URL ahead of time. ::: - -::: warning `target` needs to be `es2020` or higher -This pattern will not work if [build-target](/config/build-options.md#build-target) or [optimizedeps.esbuildoptions.target](/config/dep-optimization-options.md#optimizedeps-esbuildoptions) is set to a value lower than `es2020`. -::: diff --git a/docs/guide/backend-integration.md b/docs/guide/backend-integration.md index 3cde869121d6d7..92bb4d084d23e6 100644 --- a/docs/guide/backend-integration.md +++ b/docs/guide/backend-integration.md @@ -33,6 +33,7 @@ If you need a custom integration, you can follow the steps in this guide to conf ```html + ``` diff --git a/docs/guide/build.md b/docs/guide/build.md index 48d2f5a14ccf9c..5aab94565c1bce 100644 --- a/docs/guide/build.md +++ b/docs/guide/build.md @@ -35,7 +35,7 @@ The build can be customized via various [build config options](/config/build-opt ```js // vite.config.js -module.exports = defineConfig({ +export default defineConfig({ build: { rollupOptions: { // https://rollupjs.org/guide/en/#big-list-of-options @@ -53,7 +53,7 @@ You can configure how chunks are split using `build.rollupOptions.output.manualC ```js // vite.config.js import { splitVendorChunkPlugin } from 'vite' -module.exports = defineConfig({ +export default defineConfig({ plugins: [splitVendorChunkPlugin()] }) ``` @@ -66,7 +66,7 @@ You can enable rollup watcher with `vite build --watch`. Or, you can directly ad ```js // vite.config.js -module.exports = defineConfig({ +export default defineConfig({ build: { watch: { // https://rollupjs.org/guide/en/#watch-options @@ -97,10 +97,10 @@ During build, all you need to do is to specify multiple `.html` files as entry p ```js // vite.config.js -const { resolve } = require('path') -const { defineConfig } = require('vite') +import { resolve } from 'path' +import { defineConfig } from 'vite' -module.exports = defineConfig({ +export default defineConfig({ build: { rollupOptions: { input: { @@ -122,13 +122,13 @@ When it is time to bundle your library for distribution, use the [`build.lib` co ```js // vite.config.js -const path = require('path') -const { defineConfig } = require('vite') +import { resolve } from 'path' +import { defineConfig } from 'vite' -module.exports = defineConfig({ +export default defineConfig({ build: { lib: { - entry: path.resolve(__dirname, 'lib/main.js'), + entry: resolve(__dirname, 'lib/main.js'), name: 'MyLib', // the proper extensions will be added fileName: 'my-lib' @@ -163,8 +163,8 @@ Running `vite build` with this config uses a Rollup preset that is oriented towa ``` $ vite build building for production... -[write] my-lib.mjs 0.08kb, brotli: 0.07kb -[write] my-lib.umd.js 0.30kb, brotli: 0.16kb +dist/my-lib.js 0.08 KiB / gzip: 0.07 KiB +dist/my-lib.umd.cjs 0.30 KiB / gzip: 0.16 KiB ``` Recommended `package.json` for your lib: @@ -172,18 +172,27 @@ Recommended `package.json` for your lib: ```json { "name": "my-lib", + "type": "module", "files": ["dist"], - "main": "./dist/my-lib.umd.js", - "module": "./dist/my-lib.mjs", + "main": "./dist/my-lib.umd.cjs", + "module": "./dist/my-lib.js", "exports": { ".": { - "import": "./dist/my-lib.mjs", - "require": "./dist/my-lib.umd.js" + "import": "./dist/my-lib.js", + "require": "./dist/my-lib.umd.cjs" } } } ``` +::: tip Note +If the `package.json` does not contain `"type": "module"`, Vite will generate different file extensions for Node.js compatibility. `.js` will become `.mjs` and `.cjs` will become `.js`. +::: + +::: tip Environment Variables +In library mode, all `import.meta.env.*` usage are statically replaced when building for production. However, `process.env.*` usage are not, so that consumers of your library can dynamically change it. If this is undesirable, you can use `define: { 'process.env.``NODE_ENV': '"production"' }` for example to statically replace them. +::: + ## Advanced Base Options ::: warning @@ -214,17 +223,17 @@ experimental: { If the hashed assets and public files aren't deployed together, options for each group can be defined independently using asset `type` included in the third `context` param given to the function. ```js - experimental: { - renderBuiltUrl(filename: string, { hostType: 'js' | 'css' | 'html', type: 'public' | 'asset' }) { - if (type === 'public') { - return 'https://www.domain.com/' + filename - } - else if (path.extname(importer) === '.js') { - return { runtime: `window.__assetsPath(${JSON.stringify(filename)})` } - } - else { - return 'https://cdn.domain.com/assets/' + filename - } +experimental: { + renderBuiltUrl(filename: string, { hostType: 'js' | 'css' | 'html', type: 'public' | 'asset' }) { + if (type === 'public') { + return 'https://www.domain.com/' + filename + } + else if (path.extname(importer) === '.js') { + return { runtime: `window.__assetsPath(${JSON.stringify(filename)})` } + } + else { + return 'https://cdn.domain.com/assets/' + filename } } +} ``` diff --git a/docs/guide/env-and-mode.md b/docs/guide/env-and-mode.md index e3eb14f6524329..c91a53dc6f1a2b 100644 --- a/docs/guide/env-and-mode.md +++ b/docs/guide/env-and-mode.md @@ -12,6 +12,8 @@ Vite exposes env variables on the special **`import.meta.env`** object. Some bui - **`import.meta.env.DEV`**: {boolean} whether the app is running in development (always the opposite of `import.meta.env.PROD`) +- **`import.meta.env.SSR`**: {boolean} whether the app is running in the [server](./ssr.md#conditional-logic). + ### Production Replacement During production, these env variables are **statically replaced**. It is therefore necessary to always reference them using the full static string. For example, dynamic key access like `import.meta.env[key]` will not work. @@ -47,13 +49,18 @@ Loaded env variables are also exposed to your client source code via `import.met To prevent accidentally leaking env variables to the client, only variables prefixed with `VITE_` are exposed to your Vite-processed code. e.g. the following file: ``` -DB_PASSWORD=foobar VITE_SOME_KEY=123 +DB_PASSWORD=foobar ``` Only `VITE_SOME_KEY` will be exposed as `import.meta.env.VITE_SOME_KEY` to your client source code, but `DB_PASSWORD` will not. -If you want to customize env variables prefix, see [envPrefix](/config/index#envprefix) option. +```js +console.log(import.meta.env.VITE_SOME_KEY) // 123 +console.log(import.meta.env.DB_PASSWORD) // undefined +``` + +If you want to customize env variables prefix, see [envPrefix](/config/shared-options.html#envprefix) option. :::warning SECURITY NOTES diff --git a/docs/guide/features.md b/docs/guide/features.md index 265d6c82fa45ef..db1f45b4ddeb99 100644 --- a/docs/guide/features.md +++ b/docs/guide/features.md @@ -108,11 +108,12 @@ Vite provides first-class Vue support: - Vue 3 SFC support via [@vitejs/plugin-vue](https://github.com/vitejs/vite/tree/main/packages/plugin-vue) - Vue 3 JSX support via [@vitejs/plugin-vue-jsx](https://github.com/vitejs/vite/tree/main/packages/plugin-vue-jsx) -- Vue 2 support via [underfin/vite-plugin-vue2](https://github.com/underfin/vite-plugin-vue2) +- Vue 2.7 support via [vitejs/vite-plugin-vue2](https://github.com/vitejs/vite-plugin-vue2) +- Vue <2.7 support via [underfin/vite-plugin-vue2](https://github.com/underfin/vite-plugin-vue2) ## JSX -`.jsx` and `.tsx` files are also supported out of the box. JSX transpilation is also handled via [esbuild](https://esbuild.github.io), and defaults to the React 16 flavor. React 17 style JSX support in esbuild is tracked [here](https://github.com/evanw/esbuild/issues/334). +`.jsx` and `.tsx` files are also supported out of the box. JSX transpilation is also handled via [esbuild](https://esbuild.github.io). Vue users should use the official [@vitejs/plugin-vue-jsx](https://github.com/vitejs/vite/tree/main/packages/plugin-vue-jsx) plugin, which provides Vue 3 specific features including HMR, global component resolving, directives and slots. @@ -537,7 +538,10 @@ Vite automatically generates `` directives for entry c In real world applications, Rollup often generates "common" chunks - code that is shared between two or more other chunks. Combined with dynamic imports, it is quite common to have the following scenario: -![graph](/images/graph.png) + + In the non-optimized scenarios, when async chunk `A` is imported, the browser will have to request and parse `A` before it can figure out that it also needs the common chunk `C`. This results in an extra network roundtrip: diff --git a/docs/guide/index.md b/docs/guide/index.md index f0f327c22988a2..d7657d15e61fda 100644 --- a/docs/guide/index.md +++ b/docs/guide/index.md @@ -18,7 +18,7 @@ You can learn more about the rationale behind the project in the [Why Vite](./wh ## Browser Support -- The default build targets browsers that support both [native ES Modules](https://caniuse.com/es6-module) and [native ESM dynamic import](https://caniuse.com/es6-module-dynamic-import). Legacy browsers can be supported via the official [@vitejs/plugin-legacy](https://github.com/vitejs/vite/tree/main/packages/plugin-legacy) - see the [Building for Production](./build) section for more details. +The default build targets browsers that support both [native ES Modules](https://caniuse.com/es6-module) and [native ESM dynamic import](https://caniuse.com/es6-module-dynamic-import). Legacy browsers can be supported via the official [@vitejs/plugin-legacy](https://github.com/vitejs/vite/tree/main/packages/plugin-legacy) - see the [Building for Production](./build) section for more details. ## Trying Vite Online @@ -38,7 +38,7 @@ The supported template presets are: ## Scaffolding Your First Vite Project ::: tip Compatibility Note -Vite requires [Node.js](https://nodejs.org/en/) version >=14.18.0. However, some templates require a higher Node.js version to work, please upgrade if your package manager warns about it. +Vite requires [Node.js](https://nodejs.org/en/) version 14.18+, 16+. However, some templates require a higher Node.js version to work, please upgrade if your package manager warns about it. ::: With NPM: diff --git a/docs/guide/migration.md b/docs/guide/migration.md index acf6460f93cf9a..a156c712963b19 100644 --- a/docs/guide/migration.md +++ b/docs/guide/migration.md @@ -1,8 +1,8 @@ # Migration from v2 -## Node Support +## Node.js Support -Vite no longer supports Node v12, which reached its EOL. Node 14.18+ is now required. +Vite no longer supports Node.js 12 / 13 / 15, which reached its EOL. Node.js 14.18+ / 16+ is now required. ## Modern Browser Baseline change @@ -17,39 +17,27 @@ A small fraction of users will now require using [@vitejs/plugin-legacy](https:/ ## Config Options Changes -- The following options that were already deprecated in v2 have been removed: +The following options that were already deprecated in v2 have been removed: - - `alias` (switch to [`resolve.alias`](../config/shared-options.md#resolve-alias)) - - `dedupe` (switch to [`resolve.dedupe`](../config/shared-options.md#resolve-dedupe)) - - `build.base` (switch to [`base`](../config/shared-options.md#base)) - - `build.brotliSize` (switch to [`build.reportCompressedSize`](../config/build-options.md#build-reportcompressedsize)) - - `build.cleanCssOptions` (Vite now uses esbuild for CSS minification) - - `build.polyfillDynamicImport` (use [`@vitejs/plugin-legacy`](https://github.com/vitejs/vite/tree/main/packages/plugin-legacy) for browsers without dynamic import support) - - `optimizeDeps.keepNames` (switch to [`optimizeDeps.esbuildOptions.keepNames`](../config/dep-optimization-options.md#optimizedeps-esbuildoptions)) +- `alias` (switch to [`resolve.alias`](../config/shared-options.md#resolve-alias)) +- `dedupe` (switch to [`resolve.dedupe`](../config/shared-options.md#resolve-dedupe)) +- `build.base` (switch to [`base`](../config/shared-options.md#base)) +- `build.brotliSize` (switch to [`build.reportCompressedSize`](../config/build-options.md#build-reportcompressedsize)) +- `build.cleanCssOptions` (Vite now uses esbuild for CSS minification) +- `build.polyfillDynamicImport` (use [`@vitejs/plugin-legacy`](https://github.com/vitejs/vite/tree/main/packages/plugin-legacy) for browsers without dynamic import support) +- `optimizeDeps.keepNames` (switch to [`optimizeDeps.esbuildOptions.keepNames`](../config/dep-optimization-options.md#optimizedeps-esbuildoptions)) -## Architecture changes and legacy Options +## Architecture Changes and Legacy Options This section describes the biggest architecture changes in Vite v3. To allow projects to migrate from v2 in case of a compat issue, legacy options have been added to revert to the Vite v2 strategies. -:::warning -These options are marked as experimental and deprecated. They may be removed in a future v3 minor without respecting semver. Please pin the Vite version when using them. - -- `legacy.buildRollupPluginCommonjs` -- `legacy.buildSsrCjsExternalHeuristics` - -::: - ### Dev Server Changes Vite's default dev server port is now 5173. You can use [`server.port`](../config/server-options.md#server-port) to set it to 3000. -Vite's default dev server host is now `localhost`. You can use [`server.host`](../config/server-options.md#server-host) to set it to `127.0.0.1`. - -### Build Changes +Vite's default dev server host is now `localhost`. In Vite v2, Vite was listening to `127.0.0.1` by default. Node.js under v17 normally resolves `localhost` to `127.0.0.1`, so for those versions, the host won't change. For Node.js 17+, you can use [`server.host`](../config/server-options.md#server-host) to set it to `127.0.0.1` to keep the same host as Vite v2. -In v3, Vite uses esbuild to optimize dependencies by default. Doing so, it removes one of the most significant differences between dev and prod present in v2. Because esbuild converts CJS-only dependencies to ESM, [`@rollupjs/plugin-commonjs`](https://github.com/rollup/plugins/tree/master/packages/commonjs) is no longer used. - -If you need to get back to the v2 strategy, you can use `legacy.buildRollupPluginCommonjs`. +Note that Vite v3 now prints the correct host. This means Vite may print `127.0.0.1` as the listening host when `localhost` is used. You can set [`dns.setDefaultResultOrder('verbatim')`](https://nodejs.org/api/dns.html#dns_dns_setdefaultresultorder_order) to prevent this. See [`server.host`](../config/server-options.md#server-host) for more details. ### SSR Changes @@ -86,7 +74,7 @@ Also [`build.rollupOptions.output.inlineDynamicImports`](https://rollupjs.org/gu - When using an alias with `import.meta.glob`, the keys are always absolute. - `import.meta.globEager` is now deprecated. Use `import.meta.glob('*', { eager: true })` instead. -### WebAssembly support +### WebAssembly Support `import init from 'example.wasm'` syntax is dropped to prevent future collision with ["ESM integration for Wasm"](https://github.com/WebAssembly/esm-integration). You can use `?init` which is similar to the previous behavior. @@ -101,6 +89,28 @@ You can use `?init` which is similar to the previous behavior. }) ``` +### Automatic https Certificate Generation + +A valid certificate is needed when using `https`. In Vite v2, if no certificate was configured, a self-signed certificate was automatically created and cached. +Since Vite v3, we recommend manually creating your certificates. If you still want to use the automatic generation from v2, this feature can be enabled back by adding [@vitejs/plugin-basic-ssl](https://github.com/vitejs/vite-plugin-basic-ssl) to the project plugins. + +```js +import basicSsl from '@vitejs/plugin-basic-ssl' + +export default { + plugins: [basicSsl()] +} +``` + +## Experimental + +### Using esbuild deps optimization at build time + +In v3, Vite allows the use of esbuild to optimize dependencies during build time. If enabled, it removes one of the most significant differences between dev and prod present in v2. [`@rollupjs/plugin-commonjs`](https://github.com/rollup/plugins/tree/master/packages/commonjs) is no longer needed in this case since esbuild converts CJS-only dependencies to ESM. + +If you want to try this build strategy, you can use `optimizeDeps.disabled: false` (the default in v3 is `disabled: 'build'`). `@rollup/plugin-commonjs` +can be removed by passing `build.commonjsOptions: { include: [] }` + ## Advanced There are some changes which only affects plugin/tool creators. @@ -131,8 +141,6 @@ Also there are other breaking changes which only affect few users. - `server.force` option was removed in favor of `optimizeDeps.force` option. - [[#8550] fix: dont handle sigterm in middleware mode](https://github.com/vitejs/vite/pull/8550) - When running in middleware mode, Vite no longer kills process on `SIGTERM`. -- [[#8647] feat: print resolved address for localhost](https://github.com/vitejs/vite/pull/8647) - - `server.printUrls` and `previewServer.printUrls` are now async ## Migration from v1 diff --git a/docs/guide/ssr.md b/docs/guide/ssr.md index d4eb69b1cecc35..6defcd69dec1a6 100644 --- a/docs/guide/ssr.md +++ b/docs/guide/ssr.md @@ -1,9 +1,5 @@ # Server-Side Rendering -:::warning Experimental -SSR support is still experimental and you may encounter bugs and unsupported use cases. Proceed at your own risk. -::: - :::tip Note SSR specifically refers to front-end frameworks (for example React, Preact, Vue, and Svelte) that support running the same application in Node.js, pre-rendering it to HTML, and finally hydrating it on the client. If you are looking for integration with traditional server-side frameworks, check out the [Backend Integration guide](./backend-integration) instead. @@ -66,10 +62,13 @@ When building an SSR app, you likely want to have full control over your main se **server.js** ```js{17-19} -const fs = require('fs') -const path = require('path') -const express = require('express') -const { createServer: createViteServer } = require('vite') +import fs from 'fs' +import path from 'path' +import { fileURLToPath } from 'url' +import express from 'express' +import { createServer as createViteServer } from 'vite' + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) async function createServer() { const app = express() @@ -81,7 +80,9 @@ async function createServer() { server: { middlewareMode: true }, appType: 'custom' }) + // use vite's connect instance as middleware + // if you use your own express router (express.Router()), you should use router.use app.use(vite.middlewares) app.use('*', async (req, res) => { @@ -152,7 +153,7 @@ The `dev` script in `package.json` should also be changed to use the server scri To ship an SSR project for production, we need to: 1. Produce a client build as normal; -2. Produce an SSR build, which can be directly loaded via `require()` so that we don't have to go through Vite's `ssrLoadModule`; +2. Produce an SSR build, which can be directly loaded via `import()` so that we don't have to go through Vite's `ssrLoadModule`; Our scripts in `package.json` will look like this: @@ -172,7 +173,7 @@ Then, in `server.js` we need to add some production specific logic by checking ` - Instead of reading the root `index.html`, use the `dist/client/index.html` as the template instead, since it contains the correct asset links to the client build. -- Instead of `await vite.ssrLoadModule('/src/entry-server.js')`, use `require('./dist/server/entry-server.js')` instead (this file is the result of the SSR build). +- Instead of `await vite.ssrLoadModule('/src/entry-server.js')`, use `import('./dist/server/entry-server.js')` instead (this file is the result of the SSR build). - Move the creation and all usage of the `vite` dev server behind dev-only conditional branches, then add static file serving middlewares to serve files from `dist/client`. @@ -208,17 +209,9 @@ If the routes and the data needed for certain routes are known ahead of time, we ## SSR Externals -Many dependencies ship both ESM and CommonJS files. When running SSR, a dependency that provides CommonJS builds can be "externalized" from Vite's SSR transform / module system to speed up both dev and build. For example, instead of pulling in the pre-bundled ESM version of React and then transforming it back to be Node.js-compatible, it is more efficient to simply `require('react')` instead. It also greatly improves the speed of the SSR bundle build. - -Vite performs automated SSR externalization based on the following heuristics: +Dependencies are "externalized" from Vite's SSR transform module system by default when running SSR. This speeds up both dev and build. -- If a dependency's resolved ESM entry point and its default Node entry point are different, its default Node entry is probably a CommonJS build that can be externalized. For example, `vue` will be automatically externalized because it ships both ESM and CommonJS builds. - -- Otherwise, Vite will check whether the package's entry point contains valid ESM syntax - if not, the package is likely CommonJS and will be externalized. As an example, `react-dom` will be automatically externalized because it only specifies a single entry which is in CommonJS format. - -If this heuristics leads to errors, you can manually adjust SSR externals using `ssr.external` and `ssr.noExternal` config options. - -In the future, this heuristics will likely improve to detect if the project has `type: "module"` enabled, so that Vite can also externalize dependencies that ship Node-compatible ESM builds by importing them via dynamic `import()` during SSR. +If a dependency needs to be transformed by Vite's pipeline, for example, because Vite features are used untranspiled in them, they can be added to [`ssr.noExternal`](../config/ssr-options.md#ssrnoexternal). :::warning Working with Aliases If you have configured aliases that redirects one package to another, you may want to alias the actual `node_modules` packages instead to make it work for SSR externalized dependencies. Both [Yarn](https://classic.yarnpkg.com/en/docs/cli/add/#toc-yarn-add-alias) and [pnpm](https://pnpm.js.org/en/aliases) support aliasing via the `npm:` prefix. @@ -271,3 +264,7 @@ The CLI commands `$ vite dev` and `$ vite preview` can also be used for SSR apps :::tip Note Use a post hook so that your SSR middleware runs _after_ Vite's middlewares. ::: + +## SSR Format + +By default, Vite generates the SSR bundle in ESM. There is experimental support for configuring `ssr.format`, but it isn't recommended. Future efforts around SSR development will be based on ESM, and commonjs remain available for backward compatibility. If using ESM for SSR isn't possible in your project, you can set `legacy.buildSsrCjsExternalHeuristics: true` to generate a CJS bundle using the same [externalization heuristics of Vite v2](https://v2.vitejs.dev/guide/ssr.html#ssr-externals). diff --git a/docs/guide/static-deploy.md b/docs/guide/static-deploy.md index e3f5731aaae5a6..756f6a9c85d010 100644 --- a/docs/guide/static-deploy.md +++ b/docs/guide/static-deploy.md @@ -18,10 +18,10 @@ The following guides are based on some shared assumptions: It is important to note that `vite preview` is intended for previewing the build locally and not meant as a production server. ::: tip NOTE -These guides provide instructions for performing a static deployment of your Vite site. Vite also has experimental support for Server Side Rendering. SSR refers to front-end frameworks that support running the same application in Node.js, pre-rendering it to HTML, and finally hydrating it on the client. Check out the [SSR Guide](./ssr) to learn about this feature. On the other hand, if you are looking for integration with traditional server-side frameworks, check out the [Backend Integration guide](./backend-integration) instead. +These guides provide instructions for performing a static deployment of your Vite site. Vite also supports Server Side Rendering. SSR refers to front-end frameworks that support running the same application in Node.js, pre-rendering it to HTML, and finally hydrating it on the client. Check out the [SSR Guide](./ssr) to learn about this feature. On the other hand, if you are looking for integration with traditional server-side frameworks, check out the [Backend Integration guide](./backend-integration) instead. ::: -## Building The App +## Building the App You may run `npm run build` command to build the app. @@ -31,7 +31,7 @@ $ npm run build By default, the build output will be placed at `dist`. You may deploy this `dist` folder to any of your preferred platforms. -### Testing The App Locally +### Testing the App Locally Once you've built the app, you may test it locally by running `npm run preview` command. @@ -52,7 +52,7 @@ You may configure the port of the server by passing `--port` flag as an argument } ``` -Now the `preview` method will launch the server at `http://localhost:8080`. +Now the `preview` command will launch the server at `http://localhost:8080`. ## GitHub Pages @@ -97,40 +97,6 @@ Now the `preview` method will launch the server at `http://localhost:8080`. You can also run the above script in your CI setup to enable automatic deployment on each push. ::: -### GitHub Pages and Travis CI - -1. Set the correct `base` in `vite.config.js`. - - If you are deploying to `https://.github.io/`, you can omit `base` as it defaults to `'/'`. - - If you are deploying to `https://.github.io//`, for example your repository is at `https://github.com//`, then set `base` to `'//'`. - -2. Create a file named `.travis.yml` in the root of your project. - -3. Run `npm install` locally and commit the generated lockfile (`package-lock.json`). - -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: main - ``` - ## GitLab Pages and GitLab CI 1. Set the correct `base` in `vite.config.js`. @@ -187,6 +153,72 @@ The Netlify CLI will share with you a preview URL to inspect. When you are ready $ ntl deploy --prod ``` +## Vercel + +### Vercel CLI + +1. Install the [Vercel CLI](https://vercel.com/cli) and run `vercel` to deploy. +2. Vercel will detect that you are using Vite and will enable the correct settings for your deployment. +3. Your application is deployed! (e.g. [vite-vue-template.vercel.app](https://vite-vue-template.vercel.app/)) + +```bash +$ npm i -g vercel +$ vercel init vite +Vercel CLI +> Success! Initialized "vite" example in ~/your-folder. +- To deploy, `cd vite` and run `vercel`. +``` + +### Vercel for Git + +1. Push your code to your git repository (GitHub, GitLab, Bitbucket). +2. [Import your Vite project](https://vercel.com/new) into Vercel. +3. Vercel will detect that you are using Vite and will enable the correct settings for your deployment. +4. Your application is deployed! (e.g. [vite-vue-template.vercel.app](https://vite-vue-template.vercel.app/)) + +After your project has been imported and deployed, all subsequent pushes to branches will generate [Preview Deployments](https://vercel.com/docs/concepts/deployments/environments#preview), and all changes made to the Production Branch (commonly “main”) will result in a [Production Deployment](https://vercel.com/docs/concepts/deployments/environments#production). + +Learn more about Vercel’s [Git Integration](https://vercel.com/docs/concepts/git). + +## Cloudflare Pages + +### Cloudflare Pages via Wrangler + +1. Install [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/get-started/). +2. Authenticate Wrangler with your Cloudflare account using `wrangler login`. +3. Run your build command. +4. Deploy using `npx wrangler pages publish dist`. + +```bash +# Install Wrangler CLI +$ npm install -g wrangler + +# Login to Cloudflare account from CLI +$ wrangler login + +# Run your build command +$ npm run build + +# Create new deployment +$ npx wrangler pages publish dist +``` + +After your assets are uploaded, Wrangler will give you a preview URL to inspect your site. When you log into the Cloudflare Pages dashboard, you will see your new project. + +### Cloudflare Pages with Git + +1. Push your code to your git repository (GitHub, GitLab). +2. Log in to the Cloudflare dashboard and select your account in **Account Home** > **Pages**. +3. Select **Create a new Project** and the **Connect Git** option. +4. Select the git project you want to deploy and click **Begin setup** +5. Select the corresponding framework preset in the build setting depending on the Vite framework you have selected. +6. Then save and deploy! +7. Your application is deployed! (e.g `https://.pages.dev/`) + +After your project has been imported and deployed, all subsequent pushes to branches will generate [Preview Deployments](https://developers.cloudflare.com/pages/platform/preview-deployments/) unless specified not to in your [branch build controls](https://developers.cloudflare.com/pages/platform/branch-build-controls/). All changes to the Production Branch (commonly “main”) will result in a Production Deployment. + +You can also add custom domains and handle custom build settings on Pages. Learn more about [Cloudflare Pages Git Integration](https://developers.cloudflare.com/pages/get-started/#manage-your-site). + ## Google Firebase 1. Make sure you have [firebase-tools](https://www.npmjs.com/package/firebase-tools) installed. @@ -286,33 +318,6 @@ You can also deploy to a [custom domain](http://surge.sh/help/adding-a-custom-do $ heroku open ``` -## Vercel - -### Vercel CLI - -1. Install the [Vercel CLI](https://vercel.com/cli) and run `vercel` to deploy. -2. Vercel will detect that you are using Vite and will enable the correct settings for your deployment. -3. Your application is deployed! (e.g. [vite-vue-template.vercel.app](https://vite-vue-template.vercel.app/)) - -```bash -$ npm i -g vercel -$ vercel init vite -Vercel CLI -> Success! Initialized "vite" example in ~/your-folder. -- To deploy, `cd vite` and run `vercel`. -``` - -### Vercel for Git - -1. Push your code to your git repository (GitHub, GitLab, Bitbucket). -2. [Import your Vite project](https://vercel.com/new) into Vercel. -3. Vercel will detect that you are using Vite and will enable the correct settings for your deployment. -4. Your application is deployed! (e.g. [vite-vue-template.vercel.app](https://vite-vue-template.vercel.app/)) - -After your project has been imported and deployed, all subsequent pushes to branches will generate [Preview Deployments](https://vercel.com/docs/concepts/deployments/environments#preview), and all changes made to the Production Branch (commonly “main”) will result in a [Production Deployment](https://vercel.com/docs/concepts/deployments/environments#production). - -Learn more about Vercel’s [Git Integration](https://vercel.com/docs/concepts/git). - ## Azure Static Web Apps You can quickly deploy your Vite app with Microsoft Azure [Static Web Apps](https://aka.ms/staticwebapps) service. You need: diff --git a/docs/guide/why.md b/docs/guide/why.md index 9a24cf64777611..24b1acfef6358f 100644 --- a/docs/guide/why.md +++ b/docs/guide/why.md @@ -6,7 +6,7 @@ Before ES modules were available in browsers, developers had no native mechanism Over time we have seen tools like [webpack](https://webpack.js.org/), [Rollup](https://rollupjs.org) and [Parcel](https://parceljs.org/), which greatly improved the development experience for frontend developers. -However, as we start to build more and more ambitious applications, the amount of JavaScript we are dealing with also increased exponentially. It is not uncommon for large scale projects to contain thousands of modules. We are starting to hit a performance bottleneck for JavaScript based tooling: it can often take an unreasonably long wait (sometimes up to minutes!) to spin up a dev server, and even with HMR, file edits can take a couple seconds to be reflected in the browser. The slow feedback loop can greatly affect developers' productivity and happiness. +However, as we build more and more ambitious applications, the amount of JavaScript we are dealing with is also increasing dramatically. It is not uncommon for large scale projects to contain thousands of modules. We are starting to hit a performance bottleneck for JavaScript based tooling: it can often take an unreasonably long wait (sometimes up to minutes!) to spin up a dev server, and even with Hot Module Replacement (HMR), file edits can take a couple of seconds to be reflected in the browser. The slow feedback loop can greatly affect developers' productivity and happiness. Vite aims to address these issues by leveraging new advancements in the ecosystem: the availability of native ES modules in the browser, and the rise of JavaScript tools written in compile-to-native languages. @@ -24,9 +24,12 @@ Vite improves the dev server start time by first dividing the modules in an appl Vite serves source code over [native ESM](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules). This is essentially letting the browser take over part of the job of a bundler: Vite only needs to transform and serve source code on demand, as the browser requests it. Code behind conditional dynamic imports is only processed if actually used on the current screen. - ![bundler based dev server](/images/bundler.png) - - ![esm based dev server](/images/esm.png) + + + ### Slow Updates diff --git a/docs/images/bundler.png b/docs/images/bundler.png deleted file mode 100644 index 22d0a072dc7303..00000000000000 Binary files a/docs/images/bundler.png and /dev/null differ diff --git a/docs/images/bundler.svg b/docs/images/bundler.svg new file mode 100644 index 00000000000000..598f708c8c5cc5 --- /dev/null +++ b/docs/images/bundler.svg @@ -0,0 +1,37 @@ + +Bundle based dev server + + +entry + +··· + +route + +route + + + + + + + + + + +module + +module + +module + +module + +··· + + + +Bundle + +Server ready + diff --git a/docs/images/diagrams.fig b/docs/images/diagrams.fig new file mode 100644 index 00000000000000..300edd04609ba8 Binary files /dev/null and b/docs/images/diagrams.fig differ diff --git a/docs/images/esm.png b/docs/images/esm.png deleted file mode 100644 index 2998a6d0688dee..00000000000000 Binary files a/docs/images/esm.png and /dev/null differ diff --git a/docs/images/esm.svg b/docs/images/esm.svg new file mode 100644 index 00000000000000..ac772db0bb80a4 --- /dev/null +++ b/docs/images/esm.svg @@ -0,0 +1,51 @@ + +Native ESM based dev server + +entry + + +··· + + +route + +route + + + + + + + + + + + +module + +module + +module + +module + +··· + +Server ready + + +Dynamic import (code split point) +HTTP request + + + + + + + + + + + + + diff --git a/docs/images/graph.png b/docs/images/graph.png deleted file mode 100644 index 8b45aa9b673a6e..00000000000000 Binary files a/docs/images/graph.png and /dev/null differ diff --git a/docs/images/graph.svg b/docs/images/graph.svg new file mode 100644 index 00000000000000..df02c439121b29 --- /dev/null +++ b/docs/images/graph.svg @@ -0,0 +1,16 @@ + + +Entry + +async chunk A + +common chunk C + +async chunk B + + +dynamic import +direct import + + + diff --git a/docs/images/lit.svg b/docs/images/lit.svg new file mode 100644 index 00000000000000..4a9c1fe662ea4e --- /dev/null +++ b/docs/images/lit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/images/preact.svg b/docs/images/preact.svg new file mode 100644 index 00000000000000..908f17def0b5a4 --- /dev/null +++ b/docs/images/preact.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/images/react.svg b/docs/images/react.svg new file mode 100644 index 00000000000000..6c87de9bb33584 --- /dev/null +++ b/docs/images/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/images/svelte.svg b/docs/images/svelte.svg new file mode 100644 index 00000000000000..c5e08481f8aede --- /dev/null +++ b/docs/images/svelte.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/images/v3-docs.png b/docs/images/v3-docs.png new file mode 100644 index 00000000000000..1198937195b605 Binary files /dev/null and b/docs/images/v3-docs.png differ diff --git a/docs/images/v3-new-open-issues-and-PRs.png b/docs/images/v3-new-open-issues-and-PRs.png new file mode 100644 index 00000000000000..48fd1dea0a2cf6 Binary files /dev/null and b/docs/images/v3-new-open-issues-and-PRs.png differ diff --git a/docs/images/v3-open-issues-and-PRs.png b/docs/images/v3-open-issues-and-PRs.png new file mode 100644 index 00000000000000..fa53ba8a12a6ad Binary files /dev/null and b/docs/images/v3-open-issues-and-PRs.png differ diff --git a/docs/images/vite-3-cold-start.svg b/docs/images/vite-3-cold-start.svg new file mode 100644 index 00000000000000..216c3a878d0c3d --- /dev/null +++ b/docs/images/vite-3-cold-start.svg @@ -0,0 +1,16 @@ + + + + + + + scancrawling of static importsA. The scanner is able to find every dependency optimizeVite 2.9Vite 3.0scancrawling of static importsB. The scanner missed some dependencies optimizesend optimized deps to the browseroptimizecrawling of static importsmissing depscancrawling of static importsoptimizescancrawling of static importsoptimizemissing depoptimizebrowser loadingfinishedbrowser loadingfinishedsend optimized deps to the browsersend optimized deps to the browserbrowser loadingfinishedbrowser loadingfinishedsend optimized deps to the browserA. The scanner is able to find every dependency B. The scanner missed some dependencies \ No newline at end of file diff --git a/packages/create-vite/template-vanilla-ts/favicon.svg b/docs/images/vite.svg similarity index 100% rename from packages/create-vite/template-vanilla-ts/favicon.svg rename to docs/images/vite.svg diff --git a/docs/images/vue.svg b/docs/images/vue.svg new file mode 100644 index 00000000000000..770e9d333ee70e --- /dev/null +++ b/docs/images/vue.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/public/og-image-announcing-vite3.png b/docs/public/og-image-announcing-vite3.png new file mode 100644 index 00000000000000..859f1bcda75fb0 Binary files /dev/null and b/docs/public/og-image-announcing-vite3.png differ diff --git a/docs/team.md b/docs/team.md new file mode 100644 index 00000000000000..fdd2cb822e9afa --- /dev/null +++ b/docs/team.md @@ -0,0 +1,36 @@ +--- +layout: page +title: Meet the Team +description: The development of Vite is guided by an international team. +--- + + + + + + + + + + + + + + + diff --git a/docs/vite.config.ts b/docs/vite.config.ts index 3da9f8c96af31a..94f3ed69000771 100644 --- a/docs/vite.config.ts +++ b/docs/vite.config.ts @@ -6,5 +6,10 @@ export default defineConfig({ }, legacy: { buildSsrCjsExternalHeuristics: true + }, + optimizeDeps: { + // vitepress is aliased with replacement `join(DIST_CLIENT_PATH, '/index')` + // This needs to be excluded from optimization + exclude: ['vitepress'] } }) diff --git a/package.json b/package.json index 0704bdc7081142..c30278e0f326c7 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "vite-monorepo", "private": true, "engines": { - "node": ">=14.18.0" + "node": "^14.18.0 || >=16.0.0" }, "homepage": "https://vitejs.dev/", "keywords": [ @@ -21,7 +21,7 @@ "test": "run-s test-unit test-serve test-build", "test-serve": "vitest run -c vitest.config.e2e.ts", "test-build": "cross-env VITE_TEST_BUILD=1 vitest run -c vitest.config.e2e.ts", - "test-build-legacy-cjs": "cross-env VITE_TEST_LEGACY_CJS_PLUGIN=1 pnpm test-build", + "test-build-without-plugin-commonjs": "cross-env VITE_TEST_WITHOUT_PLUGIN_COMMONJS=1 pnpm test-build", "test-unit": "vitest run", "test-docs": "pnpm run docs-build", "debug-serve": "cross-env VITE_DEBUG_SERVE=1 vitest run -c vitest.config.e2e.ts", @@ -36,15 +36,15 @@ "ci-docs": "run-s build docs-build" }, "devDependencies": { - "@babel/types": "^7.18.7", - "@microsoft/api-extractor": "^7.28.2", + "@babel/types": "^7.18.9", + "@microsoft/api-extractor": "^7.28.4", "@rollup/plugin-typescript": "^8.3.3", "@types/babel__core": "^7.1.19", "@types/babel__standalone": "^7.1.4", "@types/convert-source-map": "^1.5.2", "@types/cross-spawn": "^6.0.2", "@types/debug": "^4.1.7", - "@types/estree": "^0.0.52", + "@types/estree": "^1.0.0", "@types/etag": "^1.8.1", "@types/fs-extra": "^9.0.13", "@types/hash-sum": "^1.0.0", @@ -59,12 +59,12 @@ "@types/semver": "^7.3.10", "@types/stylus": "^0.48.38", "@types/ws": "^8.5.3", - "@typescript-eslint/eslint-plugin": "^5.30.4", - "@typescript-eslint/parser": "^5.30.4", + "@typescript-eslint/eslint-plugin": "^5.30.6", + "@typescript-eslint/parser": "^5.30.6", "conventional-changelog-cli": "^2.2.2", "cross-env": "^7.0.3", "esbuild": "^0.14.47", - "eslint": "^8.19.0", + "eslint": "^8.20.0", "eslint-define-config": "^1.5.1", "eslint-plugin-import": "^2.26.0", "eslint-plugin-node": "^11.1.0", @@ -73,11 +73,11 @@ "kill-port": "^1.6.1", "lint-staged": "^13.0.3", "minimist": "^1.2.6", - "node-fetch": "^3.2.6", + "node-fetch": "^3.2.8", "npm-run-all": "^4.1.5", "picocolors": "^1.0.0", - "playwright-chromium": "^1.23.1", - "pnpm": "^7.5.0", + "playwright-chromium": "^1.23.4", + "pnpm": "^7.5.2", "prettier": "2.7.1", "prompts": "^2.4.2", "rimraf": "^3.0.2", @@ -86,12 +86,12 @@ "simple-git-hooks": "^2.8.0", "sirv": "^2.0.2", "tslib": "^2.4.0", - "tsx": "^3.7.1", + "tsx": "^3.8.0", "typescript": "^4.6.4", "unbuild": "^0.7.4", "vite": "workspace:*", "vitepress": "^1.0.0-alpha.4", - "vitest": "^0.17.0", + "vitest": "^0.18.1", "vue": "^3.2.37" }, "simple-git-hooks": { @@ -112,7 +112,7 @@ "eslint --cache --fix" ] }, - "packageManager": "pnpm@7.5.0", + "packageManager": "pnpm@7.5.2", "pnpm": { "overrides": { "vite": "workspace:*", diff --git a/packages/create-vite/CHANGELOG.md b/packages/create-vite/CHANGELOG.md index d8759a4e269c97..be26f7b3cce15a 100644 --- a/packages/create-vite/CHANGELOG.md +++ b/packages/create-vite/CHANGELOG.md @@ -1,3 +1,42 @@ +## 3.0.0 (2022-07-13) + +* chore: bump minors and rebuild lock (#8074) ([aeb5b74](https://github.com/vitejs/vite/commit/aeb5b74)), closes [#8074](https://github.com/vitejs/vite/issues/8074) +* chore: cleanup now that we've dropped Node 12 (#8239) ([29659a0](https://github.com/vitejs/vite/commit/29659a0)), closes [#8239](https://github.com/vitejs/vite/issues/8239) +* chore: enable ESLint for `__tests__` dir (#8370) ([cd21abf](https://github.com/vitejs/vite/commit/cd21abf)), closes [#8370](https://github.com/vitejs/vite/issues/8370) +* chore: update major deps (#8572) ([0e20949](https://github.com/vitejs/vite/commit/0e20949)), closes [#8572](https://github.com/vitejs/vite/issues/8572) +* chore: use node prefix (#8309) ([60721ac](https://github.com/vitejs/vite/commit/60721ac)), closes [#8309](https://github.com/vitejs/vite/issues/8309) +* chore: use vite-env.d.ts convention (#8988) ([cf23963](https://github.com/vitejs/vite/commit/cf23963)), closes [#8988](https://github.com/vitejs/vite/issues/8988) +* chore(create-vite): add current directory description (#8501) ([8d08220](https://github.com/vitejs/vite/commit/8d08220)), closes [#8501](https://github.com/vitejs/vite/issues/8501) +* chore(create-vite): react-ts non-null-assertion (#7881) ([771312b](https://github.com/vitejs/vite/commit/771312b)), closes [#7881](https://github.com/vitejs/vite/issues/7881) +* chore(create-vite): update logo and header styles (#8502) ([1f1ca5e](https://github.com/vitejs/vite/commit/1f1ca5e)), closes [#8502](https://github.com/vitejs/vite/issues/8502) +* chore(create-vite): upgrade vite-plugin-svelte (#9076) ([acaf9e0](https://github.com/vitejs/vite/commit/acaf9e0)), closes [#9076](https://github.com/vitejs/vite/issues/9076) +* chore(create-vite): use Type assertion in preact-ts (#8579) ([d1ba059](https://github.com/vitejs/vite/commit/d1ba059)), closes [#8579](https://github.com/vitejs/vite/issues/8579) +* chore(deps): update all non-major dependencies (#8474) ([6d0ede7](https://github.com/vitejs/vite/commit/6d0ede7)), closes [#8474](https://github.com/vitejs/vite/issues/8474) +* chore(deps): update all non-major dependencies (#8669) ([628863d](https://github.com/vitejs/vite/commit/628863d)), closes [#8669](https://github.com/vitejs/vite/issues/8669) +* chore(deps): update all non-major dependencies (#8905) ([4a24c17](https://github.com/vitejs/vite/commit/4a24c17)), closes [#8905](https://github.com/vitejs/vite/issues/8905) +* chore(deps): update all non-major dependencies (#9022) ([6342140](https://github.com/vitejs/vite/commit/6342140)), closes [#9022](https://github.com/vitejs/vite/issues/9022) +* chore(deps): update dependency @tsconfig/svelte to v3 (#8282) ([015ebed](https://github.com/vitejs/vite/commit/015ebed)), closes [#8282](https://github.com/vitejs/vite/issues/8282) +* fix: template-react-ts warning when importing path in vite.config.ts (#8924) ([0e6b82e](https://github.com/vitejs/vite/commit/0e6b82e)), closes [#8924](https://github.com/vitejs/vite/issues/8924) +* fix: use Vitest for unit testing, clean regex bug (#8040) ([63cd53d](https://github.com/vitejs/vite/commit/63cd53d)), closes [#8040](https://github.com/vitejs/vite/issues/8040) +* fix(create-vite): allow slash at the end of project path (#6897) ([8167db3](https://github.com/vitejs/vite/commit/8167db3)), closes [#6897](https://github.com/vitejs/vite/issues/6897) +* fix(create-vite): remove import from public (#9074) ([880f560](https://github.com/vitejs/vite/commit/880f560)), closes [#9074](https://github.com/vitejs/vite/issues/9074) +* fix(deps): update all non-major dependencies (#8281) ([c68db4d](https://github.com/vitejs/vite/commit/c68db4d)), closes [#8281](https://github.com/vitejs/vite/issues/8281) +* fix(deps): update all non-major dependencies (#8391) ([842f995](https://github.com/vitejs/vite/commit/842f995)), closes [#8391](https://github.com/vitejs/vite/issues/8391) +* fix(deps): update all non-major dependencies (#8558) ([9a1fd4c](https://github.com/vitejs/vite/commit/9a1fd4c)), closes [#8558](https://github.com/vitejs/vite/issues/8558) +* fix(deps): update all non-major dependencies (#8802) ([a4a634d](https://github.com/vitejs/vite/commit/a4a634d)), closes [#8802](https://github.com/vitejs/vite/issues/8802) +* fix(lib): use proper extension (#6827) ([34df307](https://github.com/vitejs/vite/commit/34df307)), closes [#6827](https://github.com/vitejs/vite/issues/6827) +* docs: correct pnpm command (#8763) ([8108b1b](https://github.com/vitejs/vite/commit/8108b1b)), closes [#8763](https://github.com/vitejs/vite/issues/8763) +* feat: bump minimum node version to 14.18.0 (#8662) ([8a05432](https://github.com/vitejs/vite/commit/8a05432)), closes [#8662](https://github.com/vitejs/vite/issues/8662) +* feat(create-vite): add `type: module` to all templates (#8251) ([c3ec60c](https://github.com/vitejs/vite/commit/c3ec60c)), closes [#8251](https://github.com/vitejs/vite/issues/8251) +* feat(create-vite): align template styles with docs (#8478) ([d72b3dd](https://github.com/vitejs/vite/commit/d72b3dd)), closes [#8478](https://github.com/vitejs/vite/issues/8478) +* feat(create-vite): migrate to ESM (#8253) ([49478ae](https://github.com/vitejs/vite/commit/49478ae)), closes [#8253](https://github.com/vitejs/vite/issues/8253) +* feat(create-vite): supports nested directory (closes #6638) (#6739) ([6ccf9aa](https://github.com/vitejs/vite/commit/6ccf9aa)), closes [#6638](https://github.com/vitejs/vite/issues/6638) [#6739](https://github.com/vitejs/vite/issues/6739) +* feat(create-vite): use framework brand glow color (#8539) ([3a21a5e](https://github.com/vitejs/vite/commit/3a21a5e)), closes [#8539](https://github.com/vitejs/vite/issues/8539) +* build!: bump targets (#8045) ([66efd69](https://github.com/vitejs/vite/commit/66efd69)), closes [#8045](https://github.com/vitejs/vite/issues/8045) +* build!: remove node v12 support (#7833) ([eeac2d2](https://github.com/vitejs/vite/commit/eeac2d2)), closes [#7833](https://github.com/vitejs/vite/issues/7833) + + + ## 2.9.3 (2022-05-02) * chore(create-vite): update reference to volar vscode extension (#7994) ([2b6d8fe](https://github.com/vitejs/vite/commit/2b6d8fe)), closes [#7994](https://github.com/vitejs/vite/issues/7994) diff --git a/packages/create-vite/README.md b/packages/create-vite/README.md index 519268a4d79da2..015fd257461ed5 100644 --- a/packages/create-vite/README.md +++ b/packages/create-vite/README.md @@ -3,7 +3,7 @@ ## Scaffolding Your First Vite Project > **Compatibility Note:** -> Vite requires [Node.js](https://nodejs.org/en/) version >=14.18.0. However, some templates require a higher Node.js version to work, please upgrade if your package manager warns about it. +> Vite requires [Node.js](https://nodejs.org/en/) version 14.18+, 16+. However, some templates require a higher Node.js version to work, please upgrade if your package manager warns about it. With NPM: diff --git a/packages/create-vite/package.json b/packages/create-vite/package.json index 87ff4af835b962..77ae57a92c60fd 100644 --- a/packages/create-vite/package.json +++ b/packages/create-vite/package.json @@ -1,6 +1,6 @@ { "name": "create-vite", - "version": "2.9.3", + "version": "3.0.0", "type": "module", "license": "MIT", "author": "Evan You", @@ -14,7 +14,7 @@ ], "main": "index.js", "engines": { - "node": ">=14.18.0" + "node": "^14.18.0 || >=16.0.0" }, "repository": { "type": "git", diff --git a/packages/create-vite/template-lit-ts/package.json b/packages/create-vite/template-lit-ts/package.json index d19a17d7fa0ef8..ec8cee932013e0 100644 --- a/packages/create-vite/template-lit-ts/package.json +++ b/packages/create-vite/template-lit-ts/package.json @@ -21,6 +21,6 @@ }, "devDependencies": { "typescript": "^4.6.4", - "vite": "^2.9.13" + "vite": "^3.0.1" } } diff --git a/packages/create-vite/template-lit-ts/src/my-element.ts b/packages/create-vite/template-lit-ts/src/my-element.ts index ba01ce52154a0d..da680eb1d0f19c 100644 --- a/packages/create-vite/template-lit-ts/src/my-element.ts +++ b/packages/create-vite/template-lit-ts/src/my-element.ts @@ -1,6 +1,5 @@ import { html, css, LitElement } from 'lit' import { customElement, property } from 'lit/decorators.js' -import viteLogo from '/vite.svg' import litLogo from './assets/lit.svg' /** @@ -27,7 +26,7 @@ export class MyElement extends LitElement { return html`
- + diff --git a/packages/create-vite/template-lit-ts/tsconfig.node.json b/packages/create-vite/template-lit-ts/tsconfig.node.json index 65dbdb96ae5dcf..9d31e2aed93c87 100644 --- a/packages/create-vite/template-lit-ts/tsconfig.node.json +++ b/packages/create-vite/template-lit-ts/tsconfig.node.json @@ -2,7 +2,8 @@ "compilerOptions": { "composite": true, "module": "ESNext", - "moduleResolution": "Node" + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true }, "include": ["vite.config.ts"] } diff --git a/packages/create-vite/template-lit/package.json b/packages/create-vite/template-lit/package.json index 96af5308786c29..9720d03e13f027 100644 --- a/packages/create-vite/template-lit/package.json +++ b/packages/create-vite/template-lit/package.json @@ -18,6 +18,6 @@ "lit": "^2.2.7" }, "devDependencies": { - "vite": "^2.9.13" + "vite": "^3.0.1" } } diff --git a/packages/create-vite/template-lit/src/my-element.js b/packages/create-vite/template-lit/src/my-element.js index 74fde11f608122..411701454b89de 100644 --- a/packages/create-vite/template-lit/src/my-element.js +++ b/packages/create-vite/template-lit/src/my-element.js @@ -1,5 +1,4 @@ import { html, css, LitElement } from 'lit' -import viteLogo from '/vite.svg' import litLogo from './assets/lit.svg' /** @@ -33,7 +32,7 @@ export class MyElement extends LitElement { return html`
- + diff --git a/packages/create-vite/template-preact-ts/package.json b/packages/create-vite/template-preact-ts/package.json index 7211956abe377b..42d5fdd956c56e 100644 --- a/packages/create-vite/template-preact-ts/package.json +++ b/packages/create-vite/template-preact-ts/package.json @@ -9,11 +9,11 @@ "preview": "vite preview" }, "dependencies": { - "preact": "^10.8.2" + "preact": "^10.10.0" }, "devDependencies": { "@preact/preset-vite": "^2.3.0", "typescript": "^4.6.4", - "vite": "^2.9.13" + "vite": "^3.0.1" } } diff --git a/packages/create-vite/template-preact-ts/src/app.tsx b/packages/create-vite/template-preact-ts/src/app.tsx index 13cf0b1b01f2fc..ccde5b9f39b1d0 100644 --- a/packages/create-vite/template-preact-ts/src/app.tsx +++ b/packages/create-vite/template-preact-ts/src/app.tsx @@ -1,5 +1,4 @@ import { useState } from 'preact/hooks' -import viteLogo from '/vite.svg' import preactLogo from './assets/preact.svg' import './app.css' @@ -10,7 +9,7 @@ export function App() { <>
- + diff --git a/packages/create-vite/template-preact-ts/tsconfig.node.json b/packages/create-vite/template-preact-ts/tsconfig.node.json index 65dbdb96ae5dcf..9d31e2aed93c87 100644 --- a/packages/create-vite/template-preact-ts/tsconfig.node.json +++ b/packages/create-vite/template-preact-ts/tsconfig.node.json @@ -2,7 +2,8 @@ "compilerOptions": { "composite": true, "module": "ESNext", - "moduleResolution": "Node" + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true }, "include": ["vite.config.ts"] } diff --git a/packages/create-vite/template-preact/package.json b/packages/create-vite/template-preact/package.json index 782c58cb22e4d7..3d8182eec28b1a 100644 --- a/packages/create-vite/template-preact/package.json +++ b/packages/create-vite/template-preact/package.json @@ -9,10 +9,10 @@ "preview": "vite preview" }, "dependencies": { - "preact": "^10.8.2" + "preact": "^10.10.0" }, "devDependencies": { "@preact/preset-vite": "^2.3.0", - "vite": "^2.9.13" + "vite": "^3.0.1" } } diff --git a/packages/create-vite/template-preact/src/app.jsx b/packages/create-vite/template-preact/src/app.jsx index 717cc480198df8..2679f488673db1 100644 --- a/packages/create-vite/template-preact/src/app.jsx +++ b/packages/create-vite/template-preact/src/app.jsx @@ -1,5 +1,4 @@ import { useState } from 'preact/hooks' -import viteLogo from '/vite.svg' import preactLogo from './assets/preact.svg' import './app.css' @@ -10,7 +9,7 @@ export function App() { <>
- + diff --git a/packages/create-vite/template-react-ts/package.json b/packages/create-vite/template-react-ts/package.json index d4e368fb9be663..4ef22bf97a465a 100644 --- a/packages/create-vite/template-react-ts/package.json +++ b/packages/create-vite/template-react-ts/package.json @@ -13,10 +13,10 @@ "react-dom": "^18.2.0" }, "devDependencies": { - "@types/react": "^18.0.14", - "@types/react-dom": "^18.0.5", - "@vitejs/plugin-react": "^1.3.2", + "@types/react": "^18.0.15", + "@types/react-dom": "^18.0.6", + "@vitejs/plugin-react": "^2.0.0", "typescript": "^4.6.4", - "vite": "^2.9.13" + "vite": "^3.0.1" } } diff --git a/packages/create-vite/template-react-ts/src/App.tsx b/packages/create-vite/template-react-ts/src/App.tsx index dfe8ceddf40982..cd201360b421e4 100644 --- a/packages/create-vite/template-react-ts/src/App.tsx +++ b/packages/create-vite/template-react-ts/src/App.tsx @@ -1,5 +1,4 @@ import { useState } from 'react' -import viteLogo from '/vite.svg' import reactLogo from './assets/react.svg' import './App.css' @@ -10,7 +9,7 @@ function App() {
- Vite logo + Vite logo React logo diff --git a/packages/create-vite/template-react-ts/tsconfig.node.json b/packages/create-vite/template-react-ts/tsconfig.node.json index 65dbdb96ae5dcf..9d31e2aed93c87 100644 --- a/packages/create-vite/template-react-ts/tsconfig.node.json +++ b/packages/create-vite/template-react-ts/tsconfig.node.json @@ -2,7 +2,8 @@ "compilerOptions": { "composite": true, "module": "ESNext", - "moduleResolution": "Node" + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true }, "include": ["vite.config.ts"] } diff --git a/packages/create-vite/template-react/package.json b/packages/create-vite/template-react/package.json index ef49229047ce93..67817c291b4ebb 100644 --- a/packages/create-vite/template-react/package.json +++ b/packages/create-vite/template-react/package.json @@ -13,9 +13,9 @@ "react-dom": "^18.2.0" }, "devDependencies": { - "@types/react": "^18.0.14", - "@types/react-dom": "^18.0.5", - "@vitejs/plugin-react": "^1.3.2", - "vite": "^2.9.13" + "@types/react": "^18.0.15", + "@types/react-dom": "^18.0.6", + "@vitejs/plugin-react": "^2.0.0", + "vite": "^3.0.1" } } diff --git a/packages/create-vite/template-react/src/App.jsx b/packages/create-vite/template-react/src/App.jsx index 14be1971f75675..ef0adc0d53eba9 100644 --- a/packages/create-vite/template-react/src/App.jsx +++ b/packages/create-vite/template-react/src/App.jsx @@ -1,5 +1,4 @@ import { useState } from 'react' -import viteLogo from '/vite.svg' import reactLogo from './assets/react.svg' import './App.css' @@ -10,7 +9,7 @@ function App() {
- Vite logo + Vite logo React logo diff --git a/packages/create-vite/template-svelte-ts/package.json b/packages/create-vite/template-svelte-ts/package.json index 91763551a0f82a..f58708b1344cdc 100644 --- a/packages/create-vite/template-svelte-ts/package.json +++ b/packages/create-vite/template-svelte-ts/package.json @@ -10,13 +10,13 @@ "check": "svelte-check --tsconfig ./tsconfig.json" }, "devDependencies": { - "@sveltejs/vite-plugin-svelte": "^1.0.0-next.49", + "@sveltejs/vite-plugin-svelte": "^1.0.1", "@tsconfig/svelte": "^3.0.0", - "svelte": "^3.48.0", + "svelte": "^3.49.0", "svelte-check": "^2.8.0", "svelte-preprocess": "^4.10.7", "tslib": "^2.4.0", "typescript": "^4.6.4", - "vite": "^2.9.13" + "vite": "^3.0.1" } } diff --git a/packages/create-vite/template-svelte-ts/src/App.svelte b/packages/create-vite/template-svelte-ts/src/App.svelte index 480e1d072d5a2e..d657a537e4829a 100644 --- a/packages/create-vite/template-svelte-ts/src/App.svelte +++ b/packages/create-vite/template-svelte-ts/src/App.svelte @@ -1,5 +1,4 @@ @@ -7,7 +6,7 @@
- + diff --git a/packages/create-vite/template-svelte/package.json b/packages/create-vite/template-svelte/package.json index 1601057ce323b6..e325de545b7cfd 100644 --- a/packages/create-vite/template-svelte/package.json +++ b/packages/create-vite/template-svelte/package.json @@ -9,8 +9,8 @@ "preview": "vite preview" }, "devDependencies": { - "@sveltejs/vite-plugin-svelte": "^1.0.0-next.49", - "svelte": "^3.48.0", - "vite": "^2.9.13" + "@sveltejs/vite-plugin-svelte": "^1.0.1", + "svelte": "^3.49.0", + "vite": "^3.0.1" } } diff --git a/packages/create-vite/template-svelte/src/App.svelte b/packages/create-vite/template-svelte/src/App.svelte index b2eb01b52ac2de..704ad09e9ea536 100644 --- a/packages/create-vite/template-svelte/src/App.svelte +++ b/packages/create-vite/template-svelte/src/App.svelte @@ -1,5 +1,4 @@ @@ -7,7 +6,7 @@
- + diff --git a/packages/create-vite/template-vanilla-ts/package.json b/packages/create-vite/template-vanilla-ts/package.json index 357f680278e836..c224ecbe25c8aa 100644 --- a/packages/create-vite/template-vanilla-ts/package.json +++ b/packages/create-vite/template-vanilla-ts/package.json @@ -10,6 +10,6 @@ }, "devDependencies": { "typescript": "^4.6.4", - "vite": "^2.9.13" + "vite": "^3.0.1" } } diff --git a/packages/create-vite/template-vanilla-ts/src/main.ts b/packages/create-vite/template-vanilla-ts/src/main.ts index b4a91405cdee25..df7c82c3cae37d 100644 --- a/packages/create-vite/template-vanilla-ts/src/main.ts +++ b/packages/create-vite/template-vanilla-ts/src/main.ts @@ -1,12 +1,11 @@ import './style.css' -import viteLogo from '/vite.svg' import typescriptLogo from './typescript.svg' import { setupCounter } from './counter' document.querySelector('#app')!.innerHTML = `
- + diff --git a/packages/create-vite/template-vanilla-ts/src/style.css b/packages/create-vite/template-vanilla-ts/src/style.css index 12320801d3635d..ac37d84b935425 100644 --- a/packages/create-vite/template-vanilla-ts/src/style.css +++ b/packages/create-vite/template-vanilla-ts/src/style.css @@ -53,7 +53,7 @@ h1 { filter: drop-shadow(0 0 2em #646cffaa); } .logo.vanilla:hover { - filter: drop-shadow(0 0 2em #f7df1eaa); + filter: drop-shadow(0 0 2em #3178c6aa); } .card { diff --git a/packages/create-vite/template-vanilla/main.js b/packages/create-vite/template-vanilla/main.js index bbdb9004d5f3d8..727b4ea209e978 100644 --- a/packages/create-vite/template-vanilla/main.js +++ b/packages/create-vite/template-vanilla/main.js @@ -1,12 +1,11 @@ import './style.css' -import viteLogo from '/vite.svg' import javascriptLogo from './javascript.svg' import { setupCounter } from './counter.js' document.querySelector('#app').innerHTML = `
- + diff --git a/packages/create-vite/template-vanilla/package.json b/packages/create-vite/template-vanilla/package.json index e5d2b2742b9cf1..39732f1b2dd1c2 100644 --- a/packages/create-vite/template-vanilla/package.json +++ b/packages/create-vite/template-vanilla/package.json @@ -9,6 +9,6 @@ "preview": "vite preview" }, "devDependencies": { - "vite": "^2.9.13" + "vite": "^3.0.1" } } diff --git a/packages/create-vite/template-vue-ts/package.json b/packages/create-vite/template-vue-ts/package.json index 06e21979b4c36e..0d237f20f25826 100644 --- a/packages/create-vite/template-vue-ts/package.json +++ b/packages/create-vite/template-vue-ts/package.json @@ -12,9 +12,9 @@ "vue": "^3.2.37" }, "devDependencies": { - "@vitejs/plugin-vue": "^2.3.3", + "@vitejs/plugin-vue": "^3.0.1", "typescript": "^4.6.4", - "vite": "^2.9.13", - "vue-tsc": "^0.38.2" + "vite": "^3.0.1", + "vue-tsc": "^0.38.8" } } diff --git a/packages/create-vite/template-vue-ts/src/env.d.ts b/packages/create-vite/template-vue-ts/src/vite-env.d.ts similarity index 66% rename from packages/create-vite/template-vue-ts/src/env.d.ts rename to packages/create-vite/template-vue-ts/src/vite-env.d.ts index aafef9509dd5c4..323c78a6cd8507 100644 --- a/packages/create-vite/template-vue-ts/src/env.d.ts +++ b/packages/create-vite/template-vue-ts/src/vite-env.d.ts @@ -2,7 +2,6 @@ declare module '*.vue' { import type { DefineComponent } from 'vue' - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types const component: DefineComponent<{}, {}, any> export default component } diff --git a/packages/create-vite/template-vue-ts/tsconfig.node.json b/packages/create-vite/template-vue-ts/tsconfig.node.json index 65dbdb96ae5dcf..9d31e2aed93c87 100644 --- a/packages/create-vite/template-vue-ts/tsconfig.node.json +++ b/packages/create-vite/template-vue-ts/tsconfig.node.json @@ -2,7 +2,8 @@ "compilerOptions": { "composite": true, "module": "ESNext", - "moduleResolution": "Node" + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true }, "include": ["vite.config.ts"] } diff --git a/packages/create-vite/template-vue/package.json b/packages/create-vite/template-vue/package.json index 58985a381b00d3..3b9d219d114708 100644 --- a/packages/create-vite/template-vue/package.json +++ b/packages/create-vite/template-vue/package.json @@ -12,7 +12,7 @@ "vue": "^3.2.37" }, "devDependencies": { - "@vitejs/plugin-vue": "^2.3.3", - "vite": "^2.9.13" + "@vitejs/plugin-vue": "^3.0.1", + "vite": "^3.0.1" } } diff --git a/packages/plugin-legacy/CHANGELOG.md b/packages/plugin-legacy/CHANGELOG.md index be2b4309e7e55a..11783e3f959c44 100644 --- a/packages/plugin-legacy/CHANGELOG.md +++ b/packages/plugin-legacy/CHANGELOG.md @@ -1,3 +1,19 @@ +## 2.0.0 (2022-07-13) + +* chore: 3.0 release notes and bump peer deps (#9072) ([427ba26](https://github.com/vitejs/vite/commit/427ba26)), closes [#9072](https://github.com/vitejs/vite/issues/9072) +* chore(deps): update all non-major dependencies (#9022) ([6342140](https://github.com/vitejs/vite/commit/6342140)), closes [#9022](https://github.com/vitejs/vite/issues/9022) +* docs: cleanup changes (#8989) ([07aef1b](https://github.com/vitejs/vite/commit/07aef1b)), closes [#8989](https://github.com/vitejs/vite/issues/8989) + + + +## 2.0.0-beta.1 (2022-07-06) + +* fix(deps): update all non-major dependencies (#8802) ([a4a634d](https://github.com/vitejs/vite/commit/a4a634d)), closes [#8802](https://github.com/vitejs/vite/issues/8802) +* feat: experimental.renderBuiltUrl (revised build base options) (#8762) ([895a7d6](https://github.com/vitejs/vite/commit/895a7d6)), closes [#8762](https://github.com/vitejs/vite/issues/8762) +* chore: use `tsx` directly instead of indirect `esno` (#8773) ([f018f13](https://github.com/vitejs/vite/commit/f018f13)), closes [#8773](https://github.com/vitejs/vite/issues/8773) + + + ## 2.0.0-beta.0 (2022-06-21) * feat: bump minimum node version to 14.18.0 (#8662) ([8a05432](https://github.com/vitejs/vite/commit/8a05432)), closes [#8662](https://github.com/vitejs/vite/issues/8662) diff --git a/packages/plugin-legacy/README.md b/packages/plugin-legacy/README.md index 4cec856f95d7af..b5c3631ab2ac60 100644 --- a/packages/plugin-legacy/README.md +++ b/packages/plugin-legacy/README.md @@ -163,7 +163,7 @@ Run `node --input-type=module -e "import {cspHashes} from '@vitejs/plugin-legacy These values (without the `sha256-` prefix) can also be retrieved via ```js -const { cspHashes } = require('@vitejs/plugin-legacy') +import { cspHashes } from '@vitejs/plugin-legacy' ``` When using the `regenerator-runtime` polyfill, it will attempt to use the `globalThis` object to register itself. If `globalThis` is not available (it is [fairly new](https://caniuse.com/?search=globalThis) and not widely supported, including IE 11), it attempts to perform dynamic `Function(...)` call which violates the CSP. To avoid dynamic `eval` in the absence of `globalThis` consider adding `core-js/proposals/global-this` to `additionalLegacyPolyfills` to define it. diff --git a/packages/plugin-legacy/package.json b/packages/plugin-legacy/package.json index b443eea58e8fbd..ecbc5088db6cc4 100644 --- a/packages/plugin-legacy/package.json +++ b/packages/plugin-legacy/package.json @@ -1,6 +1,6 @@ { "name": "@vitejs/plugin-legacy", - "version": "2.0.0-beta.0", + "version": "2.0.0", "license": "MIT", "author": "Evan You", "files": [ @@ -23,7 +23,7 @@ "prepublishOnly": "npm run build" }, "engines": { - "node": ">=14.18.0" + "node": "^14.18.0 || >=16.0.0" }, "repository": { "type": "git", @@ -35,18 +35,18 @@ }, "homepage": "https://github.com/vitejs/vite/tree/main/packages/plugin-legacy#readme", "dependencies": { - "@babel/standalone": "^7.18.7", - "core-js": "^3.23.1", + "@babel/standalone": "^7.18.9", + "core-js": "^3.23.5", "magic-string": "^0.26.2", "regenerator-runtime": "^0.13.9", "systemjs": "^6.12.1" }, "peerDependencies": { "terser": "^5.4.0", - "vite": "^3.0.0-alpha" + "vite": "^3.0.0" }, "devDependencies": { - "@babel/core": "^7.18.6", + "@babel/core": "^7.18.9", "vite": "workspace:*" } } diff --git a/packages/plugin-react/CHANGELOG.md b/packages/plugin-react/CHANGELOG.md index dfffbf17fe73bc..78b6de12fea5f0 100644 --- a/packages/plugin-react/CHANGELOG.md +++ b/packages/plugin-react/CHANGELOG.md @@ -1,3 +1,19 @@ +## 2.0.0 (2022-07-13) + +* chore: 3.0 release notes and bump peer deps (#9072) ([427ba26](https://github.com/vitejs/vite/commit/427ba26)), closes [#9072](https://github.com/vitejs/vite/issues/9072) +* fix(react): sourcemap incorrect warning and classic runtime sourcemap (#9006) ([bdae7fa](https://github.com/vitejs/vite/commit/bdae7fa)), closes [#9006](https://github.com/vitejs/vite/issues/9006) + + + +## 2.0.0-beta.1 (2022-07-06) + +* fix(deps): update all non-major dependencies (#8802) ([a4a634d](https://github.com/vitejs/vite/commit/a4a634d)), closes [#8802](https://github.com/vitejs/vite/issues/8802) +* fix(plugin-react): pass correct context to runPluginOverrides (#8809) ([09742e2](https://github.com/vitejs/vite/commit/09742e2)), closes [#8809](https://github.com/vitejs/vite/issues/8809) +* fix(plugin-react): return code if should skip in transform (fix #7586) (#8676) ([206e22a](https://github.com/vitejs/vite/commit/206e22a)), closes [#7586](https://github.com/vitejs/vite/issues/7586) [#8676](https://github.com/vitejs/vite/issues/8676) +* chore: use `tsx` directly instead of indirect `esno` (#8773) ([f018f13](https://github.com/vitejs/vite/commit/f018f13)), closes [#8773](https://github.com/vitejs/vite/issues/8773) + + + ## 2.0.0-beta.0 (2022-06-21) * feat: bump minimum node version to 14.18.0 (#8662) ([8a05432](https://github.com/vitejs/vite/commit/8a05432)), closes [#8662](https://github.com/vitejs/vite/issues/8662) diff --git a/packages/plugin-react/README.md b/packages/plugin-react/README.md index e8d27d0e57242b..6a8f3cb0ac9e21 100644 --- a/packages/plugin-react/README.md +++ b/packages/plugin-react/README.md @@ -83,7 +83,7 @@ Here's the [complete list of Babel parser plugins](https://babeljs.io/docs/en/ba ## Middleware mode -In [middleware mode](https://vitejs.dev/config/#server-middlewaremode), you should make sure your entry `index.html` file is transformed by Vite. Here's an example for an Express server: +In [middleware mode](https://vitejs.dev/config/server-options.html#server-middlewaremode), you should make sure your entry `index.html` file is transformed by Vite. Here's an example for an Express server: ```js app.get('/', async (req, res, next) => { diff --git a/packages/plugin-react/package.json b/packages/plugin-react/package.json index d6e2c9c163c1e5..47a97b5ef612a9 100644 --- a/packages/plugin-react/package.json +++ b/packages/plugin-react/package.json @@ -1,6 +1,6 @@ { "name": "@vitejs/plugin-react", - "version": "2.0.0-beta.0", + "version": "2.0.0", "license": "MIT", "author": "Evan You", "contributors": [ @@ -27,7 +27,7 @@ "prepublishOnly": "npm run build" }, "engines": { - "node": ">=14.18.0" + "node": "^14.18.0 || >=16.0.0" }, "repository": { "type": "git", @@ -39,15 +39,16 @@ }, "homepage": "https://github.com/vitejs/vite/tree/main/packages/plugin-react#readme", "dependencies": { - "@babel/core": "^7.18.6", + "@babel/core": "^7.18.9", "@babel/plugin-transform-react-jsx": "^7.18.6", "@babel/plugin-transform-react-jsx-development": "^7.18.6", "@babel/plugin-transform-react-jsx-self": "^7.18.6", "@babel/plugin-transform-react-jsx-source": "^7.18.6", + "magic-string": "^0.26.2", "react-refresh": "^0.14.0" }, "peerDependencies": { - "vite": "^3.0.0-alpha.11" + "vite": "^3.0.0" }, "devDependencies": { "vite": "workspace:*" diff --git a/packages/plugin-react/src/index.ts b/packages/plugin-react/src/index.ts index 160e9ca1d2f883..f1adf81510bcef 100644 --- a/packages/plugin-react/src/index.ts +++ b/packages/plugin-react/src/index.ts @@ -3,6 +3,8 @@ import type { ParserOptions, TransformOptions, types as t } from '@babel/core' import * as babel from '@babel/core' import { createFilter, normalizePath } from 'vite' import type { Plugin, PluginOption, ResolvedConfig } from 'vite' +import MagicString from 'magic-string' +import type { SourceMap } from 'magic-string' import { addRefreshWrapper, isRefreshBoundary, @@ -88,11 +90,14 @@ declare module 'vite' { } } +const prependReactImportCode = "import React from 'react'; " + export default function viteReact(opts: Options = {}): PluginOption[] { // Provide default values for Rollup compat. let devBase = '/' let resolvedCacheDir: string let filter = createFilter(opts.include, opts.exclude) + let needHiresSourcemap = false let isProduction = true let projectRoot = process.cwd() let skipFastRefresh = opts.fastRefresh === false @@ -135,6 +140,8 @@ export default function viteReact(opts: Options = {}): PluginOption[] { filter = createFilter(opts.include, opts.exclude, { resolve: projectRoot }) + needHiresSourcemap = + config.command === 'build' && !!config.build.sourcemap isProduction = config.isProduction skipFastRefresh ||= isProduction || config.command === 'build' @@ -217,6 +224,7 @@ export default function viteReact(opts: Options = {}): PluginOption[] { } let ast: t.File | null | undefined + let prependReactImport = false if (!isProjectFile || isJSX) { if (useAutomaticRuntime) { // By reverse-compiling "React.createElement" calls into JSX, @@ -261,11 +269,23 @@ export default function viteReact(opts: Options = {}): PluginOption[] { // Even if the automatic JSX runtime is not used, we can still // inject the React import for .jsx and .tsx modules. if (!skipReactImport && !importReactRE.test(code)) { - code = `import React from 'react'; ` + code + prependReactImport = true } } } + let inputMap: SourceMap | undefined + if (prependReactImport) { + if (needHiresSourcemap) { + const s = new MagicString(code) + s.prepend(prependReactImportCode) + code = s.toString() + inputMap = s.generateMap({ hires: true, source: id }) + } else { + code = prependReactImportCode + code + } + } + // Plugins defined through this Vite plugin are only applied // to modules within the project root, but "babel.config.js" // files can define plugins that need to be applied to every @@ -275,10 +295,11 @@ export default function viteReact(opts: Options = {}): PluginOption[] { !babelOptions.configFile && !(isProjectFile && babelOptions.babelrc) + // Avoid parsing if no plugins exist. if (shouldSkip) { - // Avoid parsing if no plugins exist. return { - code + code, + map: inputMap ?? null } } @@ -326,7 +347,7 @@ export default function viteReact(opts: Options = {}): PluginOption[] { plugins, sourceMaps: true, // Vite handles sourcemap flattening - inputSourceMap: false as any + inputSourceMap: inputMap ?? (false as any) }) if (result) { diff --git a/packages/plugin-vue-jsx/CHANGELOG.md b/packages/plugin-vue-jsx/CHANGELOG.md index a2618a14927bc4..d5c54726f3e012 100644 --- a/packages/plugin-vue-jsx/CHANGELOG.md +++ b/packages/plugin-vue-jsx/CHANGELOG.md @@ -1,3 +1,12 @@ +## 2.0.0 (2022-07-13) + +* chore: 3.0 release notes and bump peer deps (#9072) ([427ba26](https://github.com/vitejs/vite/commit/427ba26)), closes [#9072](https://github.com/vitejs/vite/issues/9072) +* chore: use `tsx` directly instead of indirect `esno` (#8773) ([f018f13](https://github.com/vitejs/vite/commit/f018f13)), closes [#8773](https://github.com/vitejs/vite/issues/8773) +* chore(deps): update all non-major dependencies (#9022) ([6342140](https://github.com/vitejs/vite/commit/6342140)), closes [#9022](https://github.com/vitejs/vite/issues/9022) +* fix(deps): update all non-major dependencies (#8802) ([a4a634d](https://github.com/vitejs/vite/commit/a4a634d)), closes [#8802](https://github.com/vitejs/vite/issues/8802) + + + ## 2.0.0-beta.0 (2022-06-21) * chore: update major deps (#8572) ([0e20949](https://github.com/vitejs/vite/commit/0e20949)), closes [#8572](https://github.com/vitejs/vite/issues/8572) diff --git a/packages/plugin-vue-jsx/package.json b/packages/plugin-vue-jsx/package.json index d340b603b8efd7..aadc2f5aa25e7c 100644 --- a/packages/plugin-vue-jsx/package.json +++ b/packages/plugin-vue-jsx/package.json @@ -1,6 +1,6 @@ { "name": "@vitejs/plugin-vue-jsx", - "version": "2.0.0-beta.0", + "version": "2.0.0", "license": "MIT", "author": "Evan You", "files": [ @@ -23,7 +23,7 @@ "prepublishOnly": "npm run build" }, "engines": { - "node": ">=14.18.0" + "node": "^14.18.0 || >=16.0.0" }, "repository": { "type": "git", @@ -35,16 +35,16 @@ }, "homepage": "https://github.com/vitejs/vite/tree/main/packages/plugin-vue-jsx#readme", "dependencies": { - "@babel/core": "^7.18.6", + "@babel/core": "^7.18.9", "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-transform-typescript": "^7.18.6", + "@babel/plugin-transform-typescript": "^7.18.8", "@vue/babel-plugin-jsx": "^1.1.1" }, "devDependencies": { "vite": "workspace:*" }, "peerDependencies": { - "vite": "^3.0.0-alpha", + "vite": "^3.0.0", "vue": "^3.0.0" } } diff --git a/packages/plugin-vue/CHANGELOG.md b/packages/plugin-vue/CHANGELOG.md index 26cae010056f50..2bc0752d6fc351 100644 --- a/packages/plugin-vue/CHANGELOG.md +++ b/packages/plugin-vue/CHANGELOG.md @@ -1,3 +1,28 @@ +## 3.0.1 (2022-07-18) + +* fix: mention that Node.js 13/15 support is dropped (fixes #9113) (#9116) ([2826303](https://github.com/vitejs/vite/commit/2826303)), closes [#9113](https://github.com/vitejs/vite/issues/9113) [#9116](https://github.com/vitejs/vite/issues/9116) +* fix(vue): remove ssr.external config (#9128) ([ec91f98](https://github.com/vitejs/vite/commit/ec91f98)), closes [#9128](https://github.com/vitejs/vite/issues/9128) +* refactor(vue): limit passable compilerOptions (#8994) ([b7b3e65](https://github.com/vitejs/vite/commit/b7b3e65)), closes [#8994](https://github.com/vitejs/vite/issues/8994) + + + +## 3.0.0 (2022-07-13) + +* chore: 3.0 release notes and bump peer deps (#9072) ([427ba26](https://github.com/vitejs/vite/commit/427ba26)), closes [#9072](https://github.com/vitejs/vite/issues/9072) +* fix(vue): handle undefined on import.meta.hot.accept (fixes #8625) (#9011) ([70af44a](https://github.com/vitejs/vite/commit/70af44a)), closes [#8625](https://github.com/vitejs/vite/issues/8625) [#9011](https://github.com/vitejs/vite/issues/9011) +* docs: cleanup changes (#8989) ([07aef1b](https://github.com/vitejs/vite/commit/07aef1b)), closes [#8989](https://github.com/vitejs/vite/issues/8989) + + + +## 3.0.0-beta.1 (2022-07-06) + +* fix(deps): update all non-major dependencies (#8802) ([a4a634d](https://github.com/vitejs/vite/commit/a4a634d)), closes [#8802](https://github.com/vitejs/vite/issues/8802) +* fix(plugin-vue): handle TS decorators in rewriteDefault fallback ([cb0c76a](https://github.com/vitejs/vite/commit/cb0c76a)) +* chore: use `tsx` directly instead of indirect `esno` (#8773) ([f018f13](https://github.com/vitejs/vite/commit/f018f13)), closes [#8773](https://github.com/vitejs/vite/issues/8773) +* chore(plugin-vue): mark export helper with null byte (#8792) ([8de4319](https://github.com/vitejs/vite/commit/8de4319)), closes [#8792](https://github.com/vitejs/vite/issues/8792) + + + ## 3.0.0-beta.0 (2022-06-21) * feat: bump minimum node version to 14.18.0 (#8662) ([8a05432](https://github.com/vitejs/vite/commit/8a05432)), closes [#8662](https://github.com/vitejs/vite/issues/8662) diff --git a/packages/plugin-vue/README.md b/packages/plugin-vue/README.md index ae848051cecd10..be02ab7ae4ab36 100644 --- a/packages/plugin-vue/README.md +++ b/packages/plugin-vue/README.md @@ -45,9 +45,18 @@ export interface Options { reactivityTransform?: boolean | string | RegExp | (string | RegExp)[] // options to pass on to vue/compiler-sfc - script?: Partial - template?: Partial - style?: Partial + script?: Partial> + template?: Partial< + Pick< + SFCTemplateCompileOptions, + | 'compiler' + | 'compilerOptions' + | 'preprocessOptions' + | 'preprocessCustomRequire' + | 'transformAssetUrls' + > + > + style?: Partial> } ``` @@ -110,6 +119,7 @@ export default { ```ts import vue from '@vitejs/plugin-vue' +import yaml from 'js-yaml' const vueI18nPlugin = { name: 'vue-i18n', @@ -118,7 +128,7 @@ const vueI18nPlugin = { return } if (/\.ya?ml$/.test(id)) { - code = JSON.stringify(require('js-yaml').load(code.trim())) + code = JSON.stringify(yaml.load(code.trim())) } return `export default Comp => { Comp.i18n = ${code} diff --git a/packages/plugin-vue/package.json b/packages/plugin-vue/package.json index 0fd91b55829172..255e1936174e30 100644 --- a/packages/plugin-vue/package.json +++ b/packages/plugin-vue/package.json @@ -1,6 +1,6 @@ { "name": "@vitejs/plugin-vue", - "version": "3.0.0-beta.0", + "version": "3.0.1", "license": "MIT", "author": "Evan You", "files": [ @@ -23,7 +23,7 @@ "prepublishOnly": "npm run build" }, "engines": { - "node": ">=14.18.0" + "node": "^14.18.0 || >=16.0.0" }, "repository": { "type": "git", @@ -35,7 +35,7 @@ }, "homepage": "https://github.com/vitejs/vite/tree/main/packages/plugin-vue#readme", "peerDependencies": { - "vite": "^3.0.0-alpha", + "vite": "^3.0.0", "vue": "^3.2.25" }, "devDependencies": { diff --git a/packages/plugin-vue/src/index.ts b/packages/plugin-vue/src/index.ts index 6bc0db06fe2b10..5a7a6947929be4 100644 --- a/packages/plugin-vue/src/index.ts +++ b/packages/plugin-vue/src/index.ts @@ -30,9 +30,18 @@ export interface Options { isProduction?: boolean // options to pass on to vue/compiler-sfc - script?: Partial - template?: Partial - style?: Partial + script?: Partial> + template?: Partial< + Pick< + SFCTemplateCompileOptions, + | 'compiler' + | 'compilerOptions' + | 'preprocessOptions' + | 'preprocessCustomRequire' + | 'transformAssetUrls' + > + > + style?: Partial> /** * Transform Vue SFCs into custom elements. @@ -124,7 +133,9 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin { __VUE_PROD_DEVTOOLS__: config.define?.__VUE_PROD_DEVTOOLS__ ?? false }, ssr: { - external: ['vue', '@vue/server-renderer'] + external: config.legacy?.buildSsrCjsExternalHeuristics + ? ['vue', '@vue/server-renderer'] + : [] } } }, diff --git a/packages/plugin-vue/src/main.ts b/packages/plugin-vue/src/main.ts index 5771d64d1dfcee..37de21de004442 100644 --- a/packages/plugin-vue/src/main.ts +++ b/packages/plugin-vue/src/main.ts @@ -128,7 +128,9 @@ export async function transformMain( output.push(`export const _rerender_only = true`) } output.push( - `import.meta.hot.accept(({ default: updated, _rerender_only }) => {`, + `import.meta.hot.accept(mod => {`, + ` if (!mod) return`, + ` const { default: updated, _rerender_only } = mod`, ` if (_rerender_only) {`, ` __VUE_HMR_RUNTIME__.rerender(updated.__hmrId, updated.render)`, ` } else {`, diff --git a/packages/vite/CHANGELOG.md b/packages/vite/CHANGELOG.md index a1b050c70da301..fa07b58412b932 100644 --- a/packages/vite/CHANGELOG.md +++ b/packages/vite/CHANGELOG.md @@ -1,77 +1,43 @@ -## 3.0.0-beta.6 (2022-07-04) - -* chore: add package.json to export map (#8838) ([cbefc63](https://github.com/vitejs/vite/commit/cbefc63)), closes [#8838](https://github.com/vitejs/vite/issues/8838) -* chore: update deprecation warnings for improved migration DX (#8866) ([4eb2348](https://github.com/vitejs/vite/commit/4eb2348)), closes [#8866](https://github.com/vitejs/vite/issues/8866) -* chore: use tsconfig for client build (#8815) ([10936cd](https://github.com/vitejs/vite/commit/10936cd)), closes [#8815](https://github.com/vitejs/vite/issues/8815) -* chore(deps): update all non-major dependencies (#8905) ([4a24c17](https://github.com/vitejs/vite/commit/4a24c17)), closes [#8905](https://github.com/vitejs/vite/issues/8905) -* chore(deps): update dependency connect-history-api-fallback to v2 (#8906) ([129c7c6](https://github.com/vitejs/vite/commit/129c7c6)), closes [#8906](https://github.com/vitejs/vite/issues/8906) -* refactor: remove ?used inject in glob plugin (#8900) ([f9b5c14](https://github.com/vitejs/vite/commit/f9b5c14)), closes [#8900](https://github.com/vitejs/vite/issues/8900) -* fix: avoid optimizing non-optimizable external deps (#8860) ([cd8d63b](https://github.com/vitejs/vite/commit/cd8d63b)), closes [#8860](https://github.com/vitejs/vite/issues/8860) -* fix: ensure define overrides import.meta in build (#8892) ([7d810a9](https://github.com/vitejs/vite/commit/7d810a9)), closes [#8892](https://github.com/vitejs/vite/issues/8892) -* fix: ignore Playwright test results directory (#8778) ([314c09c](https://github.com/vitejs/vite/commit/314c09c)), closes [#8778](https://github.com/vitejs/vite/issues/8778) -* fix: node platform for ssr dev regression (#8840) ([7257fd8](https://github.com/vitejs/vite/commit/7257fd8)), closes [#8840](https://github.com/vitejs/vite/issues/8840) -* fix: optimize deps on dev SSR, builtin imports in node (#8854) ([d49856c](https://github.com/vitejs/vite/commit/d49856c)), closes [#8854](https://github.com/vitejs/vite/issues/8854) -* fix: prevent crash when the pad amount is negative (#8747) ([3af6a1b](https://github.com/vitejs/vite/commit/3af6a1b)), closes [#8747](https://github.com/vitejs/vite/issues/8747) -* fix: reverts #8278 ([a0da2f0](https://github.com/vitejs/vite/commit/a0da2f0)), closes [#8278](https://github.com/vitejs/vite/issues/8278) -* fix: server.force deprecation and force on restart API (#8842) ([c94f564](https://github.com/vitejs/vite/commit/c94f564)), closes [#8842](https://github.com/vitejs/vite/issues/8842) -* fix(deps): update all non-major dependencies (#8802) ([a4a634d](https://github.com/vitejs/vite/commit/a4a634d)), closes [#8802](https://github.com/vitejs/vite/issues/8802) -* fix(hmr): set isSelfAccepting unless it is delayed (#8898) ([ae34565](https://github.com/vitejs/vite/commit/ae34565)), closes [#8898](https://github.com/vitejs/vite/issues/8898) -* fix(worker): dont throw on `import.meta.url` in ssr (#8846) ([ef749ed](https://github.com/vitejs/vite/commit/ef749ed)), closes [#8846](https://github.com/vitejs/vite/issues/8846) -* feat: accept AcceptedPlugin type for postcss plugin (#8830) ([6886078](https://github.com/vitejs/vite/commit/6886078)), closes [#8830](https://github.com/vitejs/vite/issues/8830) -* feat: ssrBuild flag in config env (#8863) ([b6d655a](https://github.com/vitejs/vite/commit/b6d655a)), closes [#8863](https://github.com/vitejs/vite/issues/8863) - - - -## 3.0.0-beta.5 (2022-06-28) - -* fix: deps optimizer should wait on entries (#8822) ([2db1b5b](https://github.com/vitejs/vite/commit/2db1b5b)), closes [#8822](https://github.com/vitejs/vite/issues/8822) -* fix: incorrectly resolving `knownJsSrcRE` files from root (fixes #4161) (#8808) ([e1e426e](https://github.com/vitejs/vite/commit/e1e426e)), closes [#4161](https://github.com/vitejs/vite/issues/4161) [#8808](https://github.com/vitejs/vite/issues/8808) -* feat: experimental.renderBuiltUrl (revised build base options) (#8762) ([895a7d6](https://github.com/vitejs/vite/commit/895a7d6)), closes [#8762](https://github.com/vitejs/vite/issues/8762) -* feat: respect esbuild minify config for css (#8811) ([d90409e](https://github.com/vitejs/vite/commit/d90409e)), closes [#8811](https://github.com/vitejs/vite/issues/8811) -* feat: use esbuild supported feature (#8665) ([2061d41](https://github.com/vitejs/vite/commit/2061d41)), closes [#8665](https://github.com/vitejs/vite/issues/8665) - - - -## 3.0.0-beta.4 (2022-06-27) - -* fix: /@fs/ dir traversal with escaped chars (fixes #8498) (#8804) ([6851009](https://github.com/vitejs/vite/commit/6851009)), closes [#8498](https://github.com/vitejs/vite/issues/8498) [#8804](https://github.com/vitejs/vite/issues/8804) -* fix: preserve extension of css assets in the manifest (#8768) ([9508549](https://github.com/vitejs/vite/commit/9508549)), closes [#8768](https://github.com/vitejs/vite/issues/8768) - - +## 3.0.2 (2022-07-18) -## 3.0.0-beta.3 (2022-06-26) +* fix: fs serve only edit pathname (fixes #9148) (#9173) ([28cffc9](https://github.com/vitejs/vite/commit/28cffc9)), closes [#9148](https://github.com/vitejs/vite/issues/9148) [#9173](https://github.com/vitejs/vite/issues/9173) +* fix: prevent null pathname error (#9188) ([d66ffd0](https://github.com/vitejs/vite/commit/d66ffd0)), closes [#9188](https://github.com/vitejs/vite/issues/9188) +* fix: return 500 on proxy error only if possible (fixes #9172) (#9193) ([b2f6bdc](https://github.com/vitejs/vite/commit/b2f6bdc)), closes [#9172](https://github.com/vitejs/vite/issues/9172) [#9193](https://github.com/vitejs/vite/issues/9193) +* fix(deps): update all non-major dependencies (#9176) ([31d3b70](https://github.com/vitejs/vite/commit/31d3b70)), closes [#9176](https://github.com/vitejs/vite/issues/9176) +* fix(dev): build.ssr is set during dev, fix #9134 (#9187) ([99b0e67](https://github.com/vitejs/vite/commit/99b0e67)), closes [#9134](https://github.com/vitejs/vite/issues/9134) [#9187](https://github.com/vitejs/vite/issues/9187) +* fix(ssr): strip NULL_BYTE_PLACEHOLDER before import (#9124) ([c5f2dc7](https://github.com/vitejs/vite/commit/c5f2dc7)), closes [#9124](https://github.com/vitejs/vite/issues/9124) -* fix: always remove temp config (#8782) ([2c2a86b](https://github.com/vitejs/vite/commit/2c2a86b)), closes [#8782](https://github.com/vitejs/vite/issues/8782) -* fix: ensure deps optimizer first run, fixes #8750 (#8775) ([3f689a4](https://github.com/vitejs/vite/commit/3f689a4)), closes [#8750](https://github.com/vitejs/vite/issues/8750) [#8775](https://github.com/vitejs/vite/issues/8775) -* fix: remove buildTimeImportMetaUrl (#8785) ([cd32095](https://github.com/vitejs/vite/commit/cd32095)), closes [#8785](https://github.com/vitejs/vite/issues/8785) -* fix: skip inline html (#8789) ([4a6408b](https://github.com/vitejs/vite/commit/4a6408b)), closes [#8789](https://github.com/vitejs/vite/issues/8789) -* fix(optimizer): only run require-import conversion if require'd (#8795) ([7ae0d3e](https://github.com/vitejs/vite/commit/7ae0d3e)), closes [#8795](https://github.com/vitejs/vite/issues/8795) -* perf: avoid sourcemap chains during dev (#8796) ([1566f61](https://github.com/vitejs/vite/commit/1566f61)), closes [#8796](https://github.com/vitejs/vite/issues/8796) -* chore: use `tsx` directly instead of indirect `esno` (#8773) ([f018f13](https://github.com/vitejs/vite/commit/f018f13)), closes [#8773](https://github.com/vitejs/vite/issues/8773) -* feat: respect esbuild minify config (#8754) ([8b77695](https://github.com/vitejs/vite/commit/8b77695)), closes [#8754](https://github.com/vitejs/vite/issues/8754) -* chore!: update rollup commonjs plugin to v22 (#8743) ([d4dcdd1](https://github.com/vitejs/vite/commit/d4dcdd1)), closes [#8743](https://github.com/vitejs/vite/issues/8743) +## 3.0.1 (2022-07-18) -## 3.0.0-beta.2 (2022-06-24) - -* feat: enable tree-shaking for lib es (#8737) ([5dc0f72](https://github.com/vitejs/vite/commit/5dc0f72)), closes [#8737](https://github.com/vitejs/vite/issues/8737) -* feat: supports cts and mts config (#8729) ([c2b09db](https://github.com/vitejs/vite/commit/c2b09db)), closes [#8729](https://github.com/vitejs/vite/issues/8729) -* fix: avoid type mismatch with Rollup (fix #7843) (#8701) ([87e51f7](https://github.com/vitejs/vite/commit/87e51f7)), closes [#7843](https://github.com/vitejs/vite/issues/7843) [#8701](https://github.com/vitejs/vite/issues/8701) -* fix: optimizeDeps.entries transformRequest url (fix #8719) (#8748) ([9208c3b](https://github.com/vitejs/vite/commit/9208c3b)), closes [#8719](https://github.com/vitejs/vite/issues/8719) [#8748](https://github.com/vitejs/vite/issues/8748) -* fix(hmr): __HMR_PORT__ should not be `'undefined'` (#8761) ([3271266](https://github.com/vitejs/vite/commit/3271266)), closes [#8761](https://github.com/vitejs/vite/issues/8761) -* perf(lib): improve helper inject regex (#8741) ([19fc7e5](https://github.com/vitejs/vite/commit/19fc7e5)), closes [#8741](https://github.com/vitejs/vite/issues/8741) -* refactor: remove unnecessary condition (#8742) ([2ae269e](https://github.com/vitejs/vite/commit/2ae269e)), closes [#8742](https://github.com/vitejs/vite/issues/8742) -* docs: fix alpha changelog links (#8736) ([31348b5](https://github.com/vitejs/vite/commit/31348b5)), closes [#8736](https://github.com/vitejs/vite/issues/8736) -* chore: v3 beta release notes (#8718) ([7e899d0](https://github.com/vitejs/vite/commit/7e899d0)), closes [#8718](https://github.com/vitejs/vite/issues/8718) +* fix: avoid errors when loading the overlay code in workers (#9064) ([a52b45e](https://github.com/vitejs/vite/commit/a52b45e)), closes [#9064](https://github.com/vitejs/vite/issues/9064) +* fix: check server after tsconfig reload (#9106) ([d12d469](https://github.com/vitejs/vite/commit/d12d469)), closes [#9106](https://github.com/vitejs/vite/issues/9106) +* fix: disable keepNames in `vite:esbuild` (fixes #9164) (#9166) ([e6f3b02](https://github.com/vitejs/vite/commit/e6f3b02)), closes [#9164](https://github.com/vitejs/vite/issues/9164) [#9166](https://github.com/vitejs/vite/issues/9166) +* fix: externalize workspace relative import when bundle config (#9140) ([5a8a3ab](https://github.com/vitejs/vite/commit/5a8a3ab)), closes [#9140](https://github.com/vitejs/vite/issues/9140) +* fix: mention that Node.js 13/15 support is dropped (fixes #9113) (#9116) ([2826303](https://github.com/vitejs/vite/commit/2826303)), closes [#9113](https://github.com/vitejs/vite/issues/9113) [#9116](https://github.com/vitejs/vite/issues/9116) +* fix: resolve drive relative path (#9097) ([b393451](https://github.com/vitejs/vite/commit/b393451)), closes [#9097](https://github.com/vitejs/vite/issues/9097) +* fix: respect .mjs .cjs extension in all modes (#9141) ([5ea70b3](https://github.com/vitejs/vite/commit/5ea70b3)), closes [#9141](https://github.com/vitejs/vite/issues/9141) +* fix: return 500 on proxy error only if possible (fixes #9172) (#9175) ([d2f02a8](https://github.com/vitejs/vite/commit/d2f02a8)), closes [#9172](https://github.com/vitejs/vite/issues/9172) [#9175](https://github.com/vitejs/vite/issues/9175) +* fix: server.proxy ws error causes crash (#9123) ([c2426d1](https://github.com/vitejs/vite/commit/c2426d1)), closes [#9123](https://github.com/vitejs/vite/issues/9123) +* fix: ssr.external/noExternal should apply to packageName (#9146) ([5844d8e](https://github.com/vitejs/vite/commit/5844d8e)), closes [#9146](https://github.com/vitejs/vite/issues/9146) +* fix: use correct require extension to load config (#9118) ([ebf682e](https://github.com/vitejs/vite/commit/ebf682e)), closes [#9118](https://github.com/vitejs/vite/issues/9118) +* fix(esbuild): always support dynamic import and import meta (#9105) ([57a7936](https://github.com/vitejs/vite/commit/57a7936)), closes [#9105](https://github.com/vitejs/vite/issues/9105) +* feat: allow declaring dirname (#9154) ([1e078ad](https://github.com/vitejs/vite/commit/1e078ad)), closes [#9154](https://github.com/vitejs/vite/issues/9154) +* refactor: always load config with esbuild bundled code (#9121) ([a2b3131](https://github.com/vitejs/vite/commit/a2b3131)), closes [#9121](https://github.com/vitejs/vite/issues/9121) +* docs: update default for optimizeDeps.disabled (#9078) ([4fbf9a8](https://github.com/vitejs/vite/commit/4fbf9a8)), closes [#9078](https://github.com/vitejs/vite/issues/9078) +* chore: 3.0 release notes and bump peer deps (#9072) ([427ba26](https://github.com/vitejs/vite/commit/427ba26)), closes [#9072](https://github.com/vitejs/vite/issues/9072) -## 3.0.0-beta.1 (2022-06-22) +## 3.0.0 (2022-07-13) ### Main Changes -- New docs theme using [VitePress](https://vitepress.vuejs.org/) v1 alpha: https://main.vitejs.dev +> **Vite 3 is out!** +> Read the [Vite 3 Annoucement blog post](https://vitejs.dev/blog/announcing-vite3) + +- New docs theme using [VitePress](https://vitepress.vuejs.org/) v1 alpha: https://vitejs.dev - Vite CLI - The default dev server port is now 5173, with the preview server starting at 4173. - The default dev server host is now `localhost` instead of `127.0.0.1`. @@ -81,23 +47,43 @@ - The Modern Browser Baseline now targets browsers which support the [native ES Modules](https://caniuse.com/es6-module) and [native ESM dynamic import](https://caniuse.com/es6-module-dynamic-import) and [`import.meta`](https://caniuse.com/mdn-javascript_statements_import_meta). - JS file extensions in SSR and lib mode now use a valid extension (`js`, `mjs`, or `cjs`) for output JS entries and chunks based on their format and the package type. - Architecture changes - - Vite no longer pre-scans user code with esbuild to get an initial list of dependencies on cold start. Instead, it delays the first dependency optimization run until every imported user module on load is processed. - - Vite now uses esbuild to optimize dependencies avoiding the need of[`@rollupjs/plugin-commonjs`](https://github.com/rollup/plugins/tree/master/packages/commonjs), removing one of the most significant differences between dev and prod present in v2. + - Vite now avoids full reload during cold start when imports are injected by plugins in while crawling the initial statically imported modules ([#8869](https://github.com/vitejs/vite/issues/8869)). - Vite uses ESM for the SSR build by default, and previous [SSR externalization heuristics](https://vitejs.dev/guide/ssr.html#ssr-externals) are no longer needed. -- `import.meta.glob` has been improved, read about the new features in the [Glob Import Guide](https://main.vitejs.dev/guide/features.html#glob-import) -- The WebAssembly import API has been revised to avoid collisions with future standards. Read more in the [WebAssembly guide](https://main.vitejs.dev/guide/features.html#webassembly) +- `import.meta.glob` has been improved, read about the new features in the [Glob Import Guide](https://vitejs.dev/guide/features.html#glob-import) +- The WebAssembly import API has been revised to avoid collisions with future standards. Read more in the [WebAssembly guide](https://vitejs.dev/guide/features.html#webassembly) - Improved support for relative base. - Experimental Features - - [Build Advanced Base Options](https://main.vitejs.dev/guide/build.html#advanced-base-options) + - [Build Advanced Base Options](https://vitejs.dev/guide/build.html#advanced-base-options) - [HMR Partial Accept](https://github.com/vitejs/vite/pull/7324) -- Terser is now an optional dependency to reduce the bundle size. If you use `build.minify: 'terser'`, you'll need to install it (`npm add -D terser`) -- Options that were [already deprecated in v2](https://main.vitejs.dev/guide/migration.html#config-options-changes) have been removed. - + - Vite now allows the use of [esbuild to optimize dependencies during build time](https://vitejs.dev/guide/migration.html#using-esbuild-deps-optimization-at-build-time) avoiding the need of [`@rollupjs/plugin-commonjs`](https://github.com/rollup/plugins/tree/master/packages/commonjs), removing one of the difference id dependency handling between dev and prod. +- Bundle size reduction + - Terser is now an optional dependency. If you use `build.minify: 'terser'`, you'll need to install it (`npm add -D terser`) + - node-forge moved out of the monorepo to [@vitejs/plugin-basic-ssl](https://vitejs.dev/guide/migration.html#automatic-https-certificate-generation) +- Options that were [already deprecated in v2](https://vitejs.dev/guide/migration.html#config-options-changes) have been removed. + > **Note** -> Before updating, check out the [migration guide from v2](https://main.vitejs.dev/guide/migration) +> Before updating, check out the [migration guide from v2](https://vitejs.dev/guide/migration) ### Features +* feat: expose server resolved urls (#8986) ([26bcdc3](https://github.com/vitejs/vite/commit/26bcdc3)), closes [#8986](https://github.com/vitejs/vite/issues/8986) +* feat: show ws connection error (#9007) ([da7c3ae](https://github.com/vitejs/vite/commit/da7c3ae)), closes [#9007](https://github.com/vitejs/vite/issues/9007) +* docs: update api-javascript (#8999) ([05b17df](https://github.com/vitejs/vite/commit/05b17df)), closes [#8999](https://github.com/vitejs/vite/issues/8999) +* refactor: opt-in optimizeDeps during build and SSR (#8965) ([f8c8cf2](https://github.com/vitejs/vite/commit/f8c8cf2)), closes [#8965](https://github.com/vitejs/vite/issues/8965) +* refactor!: move basic ssl setup to external plugin, fix #8532 (#8961) ([5c6cf5a](https://github.com/vitejs/vite/commit/5c6cf5a)), closes [#8532](https://github.com/vitejs/vite/issues/8532) [#8961](https://github.com/vitejs/vite/issues/8961) +* feat: avoid scanner during build and only optimize CJS in SSR (#8932) ([339d9e3](https://github.com/vitejs/vite/commit/339d9e3)), closes [#8932](https://github.com/vitejs/vite/issues/8932) +* feat: improved cold start using deps scanner (#8869) ([188f188](https://github.com/vitejs/vite/commit/188f188)), closes [#8869](https://github.com/vitejs/vite/issues/8869) +* feat: ssr.optimizeDeps (#8917) ([f280dd9](https://github.com/vitejs/vite/commit/f280dd9)), closes [#8917](https://github.com/vitejs/vite/issues/8917) +* feat: support import assertions (#8937) ([2390422](https://github.com/vitejs/vite/commit/2390422)), closes [#8937](https://github.com/vitejs/vite/issues/8937) +* feat: accept AcceptedPlugin type for postcss plugin (#8830) ([6886078](https://github.com/vitejs/vite/commit/6886078)), closes [#8830](https://github.com/vitejs/vite/issues/8830) +* feat: ssrBuild flag in config env (#8863) ([b6d655a](https://github.com/vitejs/vite/commit/b6d655a)), closes [#8863](https://github.com/vitejs/vite/issues/8863) +* feat: experimental.renderBuiltUrl (revised build base options) (#8762) ([895a7d6](https://github.com/vitejs/vite/commit/895a7d6)), closes [#8762](https://github.com/vitejs/vite/issues/8762) +* feat: respect esbuild minify config for css (#8811) ([d90409e](https://github.com/vitejs/vite/commit/d90409e)), closes [#8811](https://github.com/vitejs/vite/issues/8811) +* feat: use esbuild supported feature (#8665) ([2061d41](https://github.com/vitejs/vite/commit/2061d41)), closes [#8665](https://github.com/vitejs/vite/issues/8665) +* feat: respect esbuild minify config (#8754) ([8b77695](https://github.com/vitejs/vite/commit/8b77695)), closes [#8754](https://github.com/vitejs/vite/issues/8754) +* feat: update rollup commonjs plugin to v22 (#8743) ([d4dcdd1](https://github.com/vitejs/vite/commit/d4dcdd1)), closes [#8743](https://github.com/vitejs/vite/issues/8743) +* feat: enable tree-shaking for lib es (#8737) ([5dc0f72](https://github.com/vitejs/vite/commit/5dc0f72)), closes [#8737](https://github.com/vitejs/vite/issues/8737) +* feat: supports cts and mts config (#8729) ([c2b09db](https://github.com/vitejs/vite/commit/c2b09db)), closes [#8729](https://github.com/vitejs/vite/issues/8729) * feat: bump minimum node version to 14.18.0 (#8662) ([8a05432](https://github.com/vitejs/vite/commit/8a05432)), closes [#8662](https://github.com/vitejs/vite/issues/8662) * feat: experimental.buildAdvancedBaseOptions (#8450) ([8ef7333](https://github.com/vitejs/vite/commit/8ef7333)), closes [#8450](https://github.com/vitejs/vite/issues/8450) * feat: export esbuildVersion and rollupVersion (#8675) ([15ebe1e](https://github.com/vitejs/vite/commit/15ebe1e)), closes [#8675](https://github.com/vitejs/vite/issues/8675) @@ -152,6 +138,42 @@ ### Bug Fixes +* fix: prevent production node_env in serve (#9066) ([7662998](https://github.com/vitejs/vite/commit/7662998)), closes [#9066](https://github.com/vitejs/vite/issues/9066) +* fix: reload on restart with middleware mode (fixes #9038) (#9040) ([e372693](https://github.com/vitejs/vite/commit/e372693)), closes [#9038](https://github.com/vitejs/vite/issues/9038) [#9040](https://github.com/vitejs/vite/issues/9040) +* fix: remove ws is already closed error (#9041) ([45b8b53](https://github.com/vitejs/vite/commit/45b8b53)), closes [#9041](https://github.com/vitejs/vite/issues/9041) +* fix(ssr): sourcemap content (fixes #8657) (#8997) ([aff4544](https://github.com/vitejs/vite/commit/aff4544)), closes [#8657](https://github.com/vitejs/vite/issues/8657) [#8997](https://github.com/vitejs/vite/issues/8997) +* fix: respect explicitily external/noExternal config (#8983) ([e369880](https://github.com/vitejs/vite/commit/e369880)), closes [#8983](https://github.com/vitejs/vite/issues/8983) +* fix: cjs interop export names local clash, fix #8950 (#8953) ([2185f72](https://github.com/vitejs/vite/commit/2185f72)), closes [#8950](https://github.com/vitejs/vite/issues/8950) [#8953](https://github.com/vitejs/vite/issues/8953) +* fix: handle context resolve options (#8966) ([57c6c15](https://github.com/vitejs/vite/commit/57c6c15)), closes [#8966](https://github.com/vitejs/vite/issues/8966) +* fix: re-encode url to prevent fs.allow bypass (fixes #8498) (#8979) ([b835699](https://github.com/vitejs/vite/commit/b835699)), closes [#8498](https://github.com/vitejs/vite/issues/8498) [#8979](https://github.com/vitejs/vite/issues/8979) +* fix(scan): detect import .ts as .js (#8969) ([752af6c](https://github.com/vitejs/vite/commit/752af6c)), closes [#8969](https://github.com/vitejs/vite/issues/8969) +* fix: ssrBuild is optional, avoid breaking VitePress (#8912) ([722f514](https://github.com/vitejs/vite/commit/722f514)), closes [#8912](https://github.com/vitejs/vite/issues/8912) +* fix(css): always use css module content (#8936) ([6e0dd3a](https://github.com/vitejs/vite/commit/6e0dd3a)), closes [#8936](https://github.com/vitejs/vite/issues/8936) +* fix: avoid optimizing non-optimizable external deps (#8860) ([cd8d63b](https://github.com/vitejs/vite/commit/cd8d63b)), closes [#8860](https://github.com/vitejs/vite/issues/8860) +* fix: ensure define overrides import.meta in build (#8892) ([7d810a9](https://github.com/vitejs/vite/commit/7d810a9)), closes [#8892](https://github.com/vitejs/vite/issues/8892) +* fix: ignore Playwright test results directory (#8778) ([314c09c](https://github.com/vitejs/vite/commit/314c09c)), closes [#8778](https://github.com/vitejs/vite/issues/8778) +* fix: node platform for ssr dev regression (#8840) ([7257fd8](https://github.com/vitejs/vite/commit/7257fd8)), closes [#8840](https://github.com/vitejs/vite/issues/8840) +* fix: optimize deps on dev SSR, builtin imports in node (#8854) ([d49856c](https://github.com/vitejs/vite/commit/d49856c)), closes [#8854](https://github.com/vitejs/vite/issues/8854) +* fix: prevent crash when the pad amount is negative (#8747) ([3af6a1b](https://github.com/vitejs/vite/commit/3af6a1b)), closes [#8747](https://github.com/vitejs/vite/issues/8747) +* fix: reverts #8278 ([a0da2f0](https://github.com/vitejs/vite/commit/a0da2f0)), closes [#8278](https://github.com/vitejs/vite/issues/8278) +* fix: server.force deprecation and force on restart API (#8842) ([c94f564](https://github.com/vitejs/vite/commit/c94f564)), closes [#8842](https://github.com/vitejs/vite/issues/8842) +* fix(deps): update all non-major dependencies (#8802) ([a4a634d](https://github.com/vitejs/vite/commit/a4a634d)), closes [#8802](https://github.com/vitejs/vite/issues/8802) +* fix(hmr): set isSelfAccepting unless it is delayed (#8898) ([ae34565](https://github.com/vitejs/vite/commit/ae34565)), closes [#8898](https://github.com/vitejs/vite/issues/8898) +* fix(worker): dont throw on `import.meta.url` in ssr (#8846) ([ef749ed](https://github.com/vitejs/vite/commit/ef749ed)), closes [#8846](https://github.com/vitejs/vite/issues/8846) +* fix: deps optimizer should wait on entries (#8822) ([2db1b5b](https://github.com/vitejs/vite/commit/2db1b5b)), closes [#8822](https://github.com/vitejs/vite/issues/8822) +* fix: incorrectly resolving `knownJsSrcRE` files from root (fixes #4161) (#8808) ([e1e426e](https://github.com/vitejs/vite/commit/e1e426e)), closes [#4161](https://github.com/vitejs/vite/issues/4161) [#8808](https://github.com/vitejs/vite/issues/8808) +* fix: /@fs/ dir traversal with escaped chars (fixes #8498) (#8804) ([6851009](https://github.com/vitejs/vite/commit/6851009)), closes [#8498](https://github.com/vitejs/vite/issues/8498) [#8804](https://github.com/vitejs/vite/issues/8804) +* fix: preserve extension of css assets in the manifest (#8768) ([9508549](https://github.com/vitejs/vite/commit/9508549)), closes [#8768](https://github.com/vitejs/vite/issues/8768) +* fix: always remove temp config (#8782) ([2c2a86b](https://github.com/vitejs/vite/commit/2c2a86b)), closes [#8782](https://github.com/vitejs/vite/issues/8782) +* fix: ensure deps optimizer first run, fixes #8750 (#8775) ([3f689a4](https://github.com/vitejs/vite/commit/3f689a4)), closes [#8750](https://github.com/vitejs/vite/issues/8750) [#8775](https://github.com/vitejs/vite/issues/8775) +* fix: remove buildTimeImportMetaUrl (#8785) ([cd32095](https://github.com/vitejs/vite/commit/cd32095)), closes [#8785](https://github.com/vitejs/vite/issues/8785) +* fix: skip inline html (#8789) ([4a6408b](https://github.com/vitejs/vite/commit/4a6408b)), closes [#8789](https://github.com/vitejs/vite/issues/8789) +* fix(optimizer): only run require-import conversion if require'd (#8795) ([7ae0d3e](https://github.com/vitejs/vite/commit/7ae0d3e)), closes [#8795](https://github.com/vitejs/vite/issues/8795) +* perf: avoid sourcemap chains during dev (#8796) ([1566f61](https://github.com/vitejs/vite/commit/1566f61)), closes [#8796](https://github.com/vitejs/vite/issues/8796) +* perf(lib): improve helper inject regex (#8741) ([19fc7e5](https://github.com/vitejs/vite/commit/19fc7e5)), closes [#8741](https://github.com/vitejs/vite/issues/8741) +* fix: avoid type mismatch with Rollup (fix #7843) (#8701) ([87e51f7](https://github.com/vitejs/vite/commit/87e51f7)), closes [#7843](https://github.com/vitejs/vite/issues/7843) [#8701](https://github.com/vitejs/vite/issues/8701) +* fix: optimizeDeps.entries transformRequest url (fix #8719) (#8748) ([9208c3b](https://github.com/vitejs/vite/commit/9208c3b)), closes [#8719](https://github.com/vitejs/vite/issues/8719) [#8748](https://github.com/vitejs/vite/issues/8748) +* fix(hmr): __HMR_PORT__ should not be `'undefined'` (#8761) ([3271266](https://github.com/vitejs/vite/commit/3271266)), closes [#8761](https://github.com/vitejs/vite/issues/8761) * fix: respect `rollupOptions.external` for transitive dependencies (#8679) ([4f9097b](https://github.com/vitejs/vite/commit/4f9097b)), closes [#8679](https://github.com/vitejs/vite/issues/8679) * fix: use esbuild platform browser/node instead of neutral (#8714) ([a201cd4](https://github.com/vitejs/vite/commit/a201cd4)), closes [#8714](https://github.com/vitejs/vite/issues/8714) * fix: disable inlineDynamicImports for ssr.target = node (#8641) ([3b41a8e](https://github.com/vitejs/vite/commit/3b41a8e)), closes [#8641](https://github.com/vitejs/vite/issues/8641) @@ -233,10 +255,62 @@ ### Previous Changelogs -#### [3.0.0-beta.0](https://github.com/vitejs/vite/compare/v2.9.12...v3.0.0-beta.0) (2022-06-21) + +#### [3.0.0-beta.10](https://github.com/vitejs/vite/compare/v3.0.0-beta.9...v3.0.0-beta.10) (2022-07-11) + +See [3.0.0-beta.10 changelog](https://github.com/vitejs/vite/blob/v3.0.0-beta.10/packages/vite/CHANGELOG.md) + + +#### [3.0.0-beta.9](https://github.com/vitejs/vite/compare/v3.0.0-beta.8...v3.0.0-beta.9) (2022-07-08) + +See [3.0.0-beta.9 changelog](https://github.com/vitejs/vite/blob/v3.0.0-beta.9/packages/vite/CHANGELOG.md) + + +#### [3.0.0-beta.8](https://github.com/vitejs/vite/compare/v3.0.0-beta.7...v3.0.0-beta.8) (2022-07-08) + +See [3.0.0-beta.8 changelog](https://github.com/vitejs/vite/blob/v3.0.0-beta.8/packages/vite/CHANGELOG.md) + + +#### [3.0.0-beta.7](https://github.com/vitejs/vite/compare/v3.0.0-beta.6...v3.0.0-beta.7) (2022-07-06) + +See [3.0.0-beta.7 changelog](https://github.com/vitejs/vite/blob/v3.0.0-beta.7/packages/vite/CHANGELOG.md) + + +#### [3.0.0-beta.6](https://github.com/vitejs/vite/compare/v3.0.0-beta.5...v3.0.0-beta.6) (2022-07-04) + +See [3.0.0-beta.6 changelog](https://github.com/vitejs/vite/blob/v3.0.0-beta.6/packages/vite/CHANGELOG.md) + + +#### [3.0.0-beta.5](https://github.com/vitejs/vite/compare/v3.0.0-beta.4...v3.0.0-beta.5) (2022-06-28) + +See [3.0.0-beta.5 changelog](https://github.com/vitejs/vite/blob/v3.0.0-beta.5/packages/vite/CHANGELOG.md) + + +#### [3.0.0-beta.4](https://github.com/vitejs/vite/compare/v3.0.0-beta.3...v3.0.0-beta.4) (2022-06-27) + +See [3.0.0-beta.4 changelog](https://github.com/vitejs/vite/blob/v3.0.0-beta.4/packages/vite/CHANGELOG.md) + + +#### [3.0.0-beta.3](https://github.com/vitejs/vite/compare/v3.0.0-beta.2...v3.0.0-beta.3) (2022-06-26) + +See [3.0.0-beta.3 changelog](https://github.com/vitejs/vite/blob/v3.0.0-beta.3/packages/vite/CHANGELOG.md) + + +#### [3.0.0-beta.2](https://github.com/vitejs/vite/compare/v3.0.0-beta.1...v3.0.0-beta.2) (2022-06-24) + +See [3.0.0-beta.2 changelog](https://github.com/vitejs/vite/blob/v3.0.0-beta.2/packages/vite/CHANGELOG.md) + + +#### [3.0.0-beta.1](https://github.com/vitejs/vite/compare/v3.0.0-beta.0...v3.0.0-beta.1) (2022-06-22) + +See [3.0.0-beta.1 changelog](https://github.com/vitejs/vite/blob/v3.0.0-beta.1/packages/vite/CHANGELOG.md) + + +#### [3.0.0-beta.0](https://github.com/vitejs/vite/compare/v3.0.0-alpha.14...v3.0.0-beta.0) (2022-06-21) See [3.0.0-beta.0 changelog](https://github.com/vitejs/vite/blob/v3.0.0-beta.0/packages/vite/CHANGELOG.md) + #### [3.0.0-alpha.14](https://github.com/vitejs/vite/compare/v3.0.0-alpha.13...v3.0.0-alpha.14) (2022-06-20) See [3.0.0-alpha.14 changelog](https://github.com/vitejs/vite/blob/v3.0.0-alpha.14/packages/vite/CHANGELOG.md) @@ -313,6 +387,22 @@ See [3.0.0-alpha.0 changelog](https://github.com/vitejs/vite/blob/v3.0.0-alpha.0 +## 2.9.14 (2022-07-08) + +* fix: re-encode url to prevent fs.allow bypass (fixes #8498) (#8990) ([adb61c5](https://github.com/vitejs/vite/commit/adb61c5)), closes [#8498](https://github.com/vitejs/vite/issues/8498) [#8990](https://github.com/vitejs/vite/issues/8990) +* fix: reverts #8471, fix css content ([da77dee](https://github.com/vitejs/vite/commit/da77dee)), closes [#8874](https://github.com/vitejs/vite/issues/8874) +* fix(css): preserve dynamic import css code (fixes #5348) ([d4d89b9](https://github.com/vitejs/vite/commit/d4d89b9)), closes [#5348](https://github.com/vitejs/vite/issues/5348) [#7746](https://github.com/vitejs/vite/issues/7746) +* fix(css): always use css module content (#8977) ([84ec02a](https://github.com/vitejs/vite/commit/84ec02a)), closes [#8936](https://github.com/vitejs/vite/issues/8936) [#8977](https://github.com/vitejs/vite/issues/8977) + + + +## 2.9.13 (2022-06-27) + +* fix: /@fs/ dir traversal with escaped chars (fixes #8498) (#8805) ([e109d64](https://github.com/vitejs/vite/commit/e109d64)), closes [#8498](https://github.com/vitejs/vite/issues/8498) [#8805](https://github.com/vitejs/vite/issues/8805) +* fix(wasm): support decoding data URL in Node < v16 (#8668) ([1afc1c2](https://github.com/vitejs/vite/commit/1afc1c2)), closes [#8668](https://github.com/vitejs/vite/issues/8668) + + + ## 2.9.12 (2022-06-10) * fix: outdated optimized dep removed from module graph (#8534) ([c0d6c60](https://github.com/vitejs/vite/commit/c0d6c60)), closes [#8534](https://github.com/vitejs/vite/issues/8534) diff --git a/packages/vite/LICENSE.md b/packages/vite/LICENSE.md index 9bfb71d673183a..41da37ad32dd33 100644 --- a/packages/vite/LICENSE.md +++ b/packages/vite/LICENSE.md @@ -25,7 +25,7 @@ SOFTWARE. # Licenses of bundled dependencies The published Vite artifact additionally contains code with the following licenses: -Apache-2.0, BSD-2-Clause, CC0-1.0, ISC, MIT, (BSD-3-Clause OR GPL-2.0) +Apache-2.0, BSD-2-Clause, CC0-1.0, ISC, MIT # Bundled dependencies: ## @ampproject/remapping @@ -975,7 +975,7 @@ Repository: http://github.com/bripkens/connect-history-api-fallback.git > The MIT License > -> Copyright (c) 2012 Ben Ripkens http://bripkens.de +> Copyright (c) 2022 Ben Blackmore and contributors > > Permission is hereby granted, free of charge, to any person obtaining a copy > of this software and associated documentation files (the "Software"), to deal @@ -2276,344 +2276,6 @@ Repository: zeit/ms --------------------------------------- -## node-forge -License: (BSD-3-Clause OR GPL-2.0) -By: Digital Bazaar, Inc., Dave Longley, David I. Lehn, Stefan Siegl, Christoph Dorn -Repository: https://github.com/digitalbazaar/forge - -> You may use the Forge project under the terms of either the BSD License or the -> GNU General Public License (GPL) Version 2. -> -> The BSD License is recommended for most projects. It is simple and easy to -> understand and it places almost no restrictions on what you can do with the -> Forge project. -> -> If the GPL suits your project better you are also free to use Forge under -> that license. -> -> You don't have to do anything special to choose one license or the other and -> you don't have to notify anyone which license you are using. You are free to -> use this project in commercial projects as long as the copyright header is -> left intact. -> -> If you are a commercial entity and use this set of libraries in your -> commercial software then reasonable payment to Digital Bazaar, if you can -> afford it, is not required but is expected and would be appreciated. If this -> library saves you time, then it's saving you money. The cost of developing -> the Forge software was on the order of several hundred hours and tens of -> thousands of dollars. We are attempting to strike a balance between helping -> the development community while not being taken advantage of by lucrative -> commercial entities for our efforts. -> -> ------------------------------------------------------------------------------- -> New BSD License (3-clause) -> Copyright (c) 2010, Digital Bazaar, Inc. -> All rights reserved. -> -> Redistribution and use in source and binary forms, with or without -> modification, are permitted provided that the following conditions are met: -> * Redistributions of source code must retain the above copyright -> notice, this list of conditions and the following disclaimer. -> * Redistributions in binary form must reproduce the above copyright -> notice, this list of conditions and the following disclaimer in the -> documentation and/or other materials provided with the distribution. -> * Neither the name of Digital Bazaar, Inc. nor the -> names of its contributors may be used to endorse or promote products -> derived from this software without specific prior written permission. -> -> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -> ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -> WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -> DISCLAIMED. IN NO EVENT SHALL DIGITAL BAZAAR BE LIABLE FOR ANY -> DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -> (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -> LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -> ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -> (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -> SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -> -> ------------------------------------------------------------------------------- -> GNU GENERAL PUBLIC LICENSE -> Version 2, June 1991 -> -> Copyright (C) 1989, 1991 Free Software Foundation, Inc. -> 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -> Everyone is permitted to copy and distribute verbatim copies -> of this license document, but changing it is not allowed. -> -> Preamble -> -> The licenses for most software are designed to take away your -> freedom to share and change it. By contrast, the GNU General Public -> License is intended to guarantee your freedom to share and change free -> software--to make sure the software is free for all its users. This -> General Public License applies to most of the Free Software -> Foundation's software and to any other program whose authors commit to -> using it. (Some other Free Software Foundation software is covered by -> the GNU Lesser General Public License instead.) You can apply it to -> your programs, too. -> -> When we speak of free software, we are referring to freedom, not -> price. Our General Public Licenses are designed to make sure that you -> have the freedom to distribute copies of free software (and charge for -> this service if you wish), that you receive source code or can get it -> if you want it, that you can change the software or use pieces of it -> in new free programs; and that you know you can do these things. -> -> To protect your rights, we need to make restrictions that forbid -> anyone to deny you these rights or to ask you to surrender the rights. -> These restrictions translate to certain responsibilities for you if you -> distribute copies of the software, or if you modify it. -> -> For example, if you distribute copies of such a program, whether -> gratis or for a fee, you must give the recipients all the rights that -> you have. You must make sure that they, too, receive or can get the -> source code. And you must show them these terms so they know their -> rights. -> -> We protect your rights with two steps: (1) copyright the software, and -> (2) offer you this license which gives you legal permission to copy, -> distribute and/or modify the software. -> -> Also, for each author's protection and ours, we want to make certain -> that everyone understands that there is no warranty for this free -> software. If the software is modified by someone else and passed on, we -> want its recipients to know that what they have is not the original, so -> that any problems introduced by others will not reflect on the original -> authors' reputations. -> -> Finally, any free program is threatened constantly by software -> patents. We wish to avoid the danger that redistributors of a free -> program will individually obtain patent licenses, in effect making the -> program proprietary. To prevent this, we have made it clear that any -> patent must be licensed for everyone's free use or not licensed at all. -> -> The precise terms and conditions for copying, distribution and -> modification follow. -> -> GNU GENERAL PUBLIC LICENSE -> TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -> -> 0. This License applies to any program or other work which contains -> a notice placed by the copyright holder saying it may be distributed -> under the terms of this General Public License. The "Program", below, -> refers to any such program or work, and a "work based on the Program" -> means either the Program or any derivative work under copyright law: -> that is to say, a work containing the Program or a portion of it, -> either verbatim or with modifications and/or translated into another -> language. (Hereinafter, translation is included without limitation in -> the term "modification".) Each licensee is addressed as "you". -> -> Activities other than copying, distribution and modification are not -> covered by this License; they are outside its scope. The act of -> running the Program is not restricted, and the output from the Program -> is covered only if its contents constitute a work based on the -> Program (independent of having been made by running the Program). -> Whether that is true depends on what the Program does. -> -> 1. You may copy and distribute verbatim copies of the Program's -> source code as you receive it, in any medium, provided that you -> conspicuously and appropriately publish on each copy an appropriate -> copyright notice and disclaimer of warranty; keep intact all the -> notices that refer to this License and to the absence of any warranty; -> and give any other recipients of the Program a copy of this License -> along with the Program. -> -> You may charge a fee for the physical act of transferring a copy, and -> you may at your option offer warranty protection in exchange for a fee. -> -> 2. You may modify your copy or copies of the Program or any portion -> of it, thus forming a work based on the Program, and copy and -> distribute such modifications or work under the terms of Section 1 -> above, provided that you also meet all of these conditions: -> -> a) You must cause the modified files to carry prominent notices -> stating that you changed the files and the date of any change. -> -> b) You must cause any work that you distribute or publish, that in -> whole or in part contains or is derived from the Program or any -> part thereof, to be licensed as a whole at no charge to all third -> parties under the terms of this License. -> -> c) If the modified program normally reads commands interactively -> when run, you must cause it, when started running for such -> interactive use in the most ordinary way, to print or display an -> announcement including an appropriate copyright notice and a -> notice that there is no warranty (or else, saying that you provide -> a warranty) and that users may redistribute the program under -> these conditions, and telling the user how to view a copy of this -> License. (Exception: if the Program itself is interactive but -> does not normally print such an announcement, your work based on -> the Program is not required to print an announcement.) -> -> These requirements apply to the modified work as a whole. If -> identifiable sections of that work are not derived from the Program, -> and can be reasonably considered independent and separate works in -> themselves, then this License, and its terms, do not apply to those -> sections when you distribute them as separate works. But when you -> distribute the same sections as part of a whole which is a work based -> on the Program, the distribution of the whole must be on the terms of -> this License, whose permissions for other licensees extend to the -> entire whole, and thus to each and every part regardless of who wrote it. -> -> Thus, it is not the intent of this section to claim rights or contest -> your rights to work written entirely by you; rather, the intent is to -> exercise the right to control the distribution of derivative or -> collective works based on the Program. -> -> In addition, mere aggregation of another work not based on the Program -> with the Program (or with a work based on the Program) on a volume of -> a storage or distribution medium does not bring the other work under -> the scope of this License. -> -> 3. You may copy and distribute the Program (or a work based on it, -> under Section 2) in object code or executable form under the terms of -> Sections 1 and 2 above provided that you also do one of the following: -> -> a) Accompany it with the complete corresponding machine-readable -> source code, which must be distributed under the terms of Sections -> 1 and 2 above on a medium customarily used for software interchange; or, -> -> b) Accompany it with a written offer, valid for at least three -> years, to give any third party, for a charge no more than your -> cost of physically performing source distribution, a complete -> machine-readable copy of the corresponding source code, to be -> distributed under the terms of Sections 1 and 2 above on a medium -> customarily used for software interchange; or, -> -> c) Accompany it with the information you received as to the offer -> to distribute corresponding source code. (This alternative is -> allowed only for noncommercial distribution and only if you -> received the program in object code or executable form with such -> an offer, in accord with Subsection b above.) -> -> The source code for a work means the preferred form of the work for -> making modifications to it. For an executable work, complete source -> code means all the source code for all modules it contains, plus any -> associated interface definition files, plus the scripts used to -> control compilation and installation of the executable. However, as a -> special exception, the source code distributed need not include -> anything that is normally distributed (in either source or binary -> form) with the major components (compiler, kernel, and so on) of the -> operating system on which the executable runs, unless that component -> itself accompanies the executable. -> -> If distribution of executable or object code is made by offering -> access to copy from a designated place, then offering equivalent -> access to copy the source code from the same place counts as -> distribution of the source code, even though third parties are not -> compelled to copy the source along with the object code. -> -> 4. You may not copy, modify, sublicense, or distribute the Program -> except as expressly provided under this License. Any attempt -> otherwise to copy, modify, sublicense or distribute the Program is -> void, and will automatically terminate your rights under this License. -> However, parties who have received copies, or rights, from you under -> this License will not have their licenses terminated so long as such -> parties remain in full compliance. -> -> 5. You are not required to accept this License, since you have not -> signed it. However, nothing else grants you permission to modify or -> distribute the Program or its derivative works. These actions are -> prohibited by law if you do not accept this License. Therefore, by -> modifying or distributing the Program (or any work based on the -> Program), you indicate your acceptance of this License to do so, and -> all its terms and conditions for copying, distributing or modifying -> the Program or works based on it. -> -> 6. Each time you redistribute the Program (or any work based on the -> Program), the recipient automatically receives a license from the -> original licensor to copy, distribute or modify the Program subject to -> these terms and conditions. You may not impose any further -> restrictions on the recipients' exercise of the rights granted herein. -> You are not responsible for enforcing compliance by third parties to -> this License. -> -> 7. If, as a consequence of a court judgment or allegation of patent -> infringement or for any other reason (not limited to patent issues), -> conditions are imposed on you (whether by court order, agreement or -> otherwise) that contradict the conditions of this License, they do not -> excuse you from the conditions of this License. If you cannot -> distribute so as to satisfy simultaneously your obligations under this -> License and any other pertinent obligations, then as a consequence you -> may not distribute the Program at all. For example, if a patent -> license would not permit royalty-free redistribution of the Program by -> all those who receive copies directly or indirectly through you, then -> the only way you could satisfy both it and this License would be to -> refrain entirely from distribution of the Program. -> -> If any portion of this section is held invalid or unenforceable under -> any particular circumstance, the balance of the section is intended to -> apply and the section as a whole is intended to apply in other -> circumstances. -> -> It is not the purpose of this section to induce you to infringe any -> patents or other property right claims or to contest validity of any -> such claims; this section has the sole purpose of protecting the -> integrity of the free software distribution system, which is -> implemented by public license practices. Many people have made -> generous contributions to the wide range of software distributed -> through that system in reliance on consistent application of that -> system; it is up to the author/donor to decide if he or she is willing -> to distribute software through any other system and a licensee cannot -> impose that choice. -> -> This section is intended to make thoroughly clear what is believed to -> be a consequence of the rest of this License. -> -> 8. If the distribution and/or use of the Program is restricted in -> certain countries either by patents or by copyrighted interfaces, the -> original copyright holder who places the Program under this License -> may add an explicit geographical distribution limitation excluding -> those countries, so that distribution is permitted only in or among -> countries not thus excluded. In such case, this License incorporates -> the limitation as if written in the body of this License. -> -> 9. The Free Software Foundation may publish revised and/or new versions -> of the General Public License from time to time. Such new versions will -> be similar in spirit to the present version, but may differ in detail to -> address new problems or concerns. -> -> Each version is given a distinguishing version number. If the Program -> specifies a version number of this License which applies to it and "any -> later version", you have the option of following the terms and conditions -> either of that version or of any later version published by the Free -> Software Foundation. If the Program does not specify a version number of -> this License, you may choose any version ever published by the Free Software -> Foundation. -> -> 10. If you wish to incorporate parts of the Program into other free -> programs whose distribution conditions are different, write to the author -> to ask for permission. For software which is copyrighted by the Free -> Software Foundation, write to the Free Software Foundation; we sometimes -> make exceptions for this. Our decision will be guided by the two goals -> of preserving the free status of all derivatives of our free software and -> of promoting the sharing and reuse of software generally. -> -> NO WARRANTY -> -> 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -> FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -> OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -> PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -> OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -> MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -> TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -> PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -> REPAIR OR CORRECTION. -> -> 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -> WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -> REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -> INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -> OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -> TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -> YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -> PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -> POSSIBILITY OF SUCH DAMAGES. - ---------------------------------------- - ## normalize-path License: MIT By: Jon Schlinkert, Blaine Bublitz diff --git a/packages/vite/package.json b/packages/vite/package.json index a99ac5eeee70bc..689201587fd7b0 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -1,6 +1,6 @@ { "name": "vite", - "version": "3.0.0-beta.6", + "version": "3.0.2", "type": "module", "license": "MIT", "author": "Evan You", @@ -32,7 +32,7 @@ "types" ], "engines": { - "node": ">=14.18.0" + "node": "^14.18.0 || >=16.0.0" }, "repository": { "type": "git", @@ -68,8 +68,8 @@ }, "devDependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/parser": "^7.18.6", - "@babel/types": "^7.18.7", + "@babel/parser": "^7.18.9", + "@babel/types": "^7.18.9", "@jridgewell/trace-mapping": "^0.3.14", "@rollup/plugin-alias": "^3.1.9", "@rollup/plugin-commonjs": "^22.0.1", @@ -101,7 +101,6 @@ "micromatch": "^4.0.5", "mlly": "^0.5.4", "mrmime": "^1.0.1", - "node-forge": "^1.3.1", "okie": "^1.0.1", "open": "^8.4.0", "periscopic": "^3.0.4", @@ -119,8 +118,8 @@ "tsconfck": "^2.0.1", "tslib": "^2.4.0", "types": "link:./types", - "ufo": "^0.8.4", - "ws": "^8.8.0" + "ufo": "^0.8.5", + "ws": "^8.8.1" }, "peerDependencies": { "less": "*", diff --git a/packages/vite/src/client/client.ts b/packages/vite/src/client/client.ts index 509b5048da6d47..b2a62f0dd98eca 100644 --- a/packages/vite/src/client/client.ts +++ b/packages/vite/src/client/client.ts @@ -7,6 +7,7 @@ import '@vite/env' // injected by the hmr plugin when served declare const __BASE__: string +declare const __SERVER_HOST__: string declare const __HMR_PROTOCOL__: string | null declare const __HMR_HOSTNAME__: string | null declare const __HMR_PORT__: number | null @@ -20,6 +21,7 @@ console.debug('[vite] connecting...') const importMetaUrl = new URL(import.meta.url) // use server configuration, then fallback to inference +const serverHost = __SERVER_HOST__ const socketProtocol = __HMR_PROTOCOL__ || (location.protocol === 'https:' ? 'wss' : 'ws') const hmrPort = __HMR_PORT__ @@ -38,7 +40,19 @@ try { fallback = () => { // fallback to connecting directly to the hmr server // for servers which does not support proxying websocket - socket = setupWebSocket(socketProtocol, directSocketHost) + socket = setupWebSocket(socketProtocol, directSocketHost, () => { + const currentScriptHostURL = new URL(import.meta.url) + const currentScriptHost = + currentScriptHostURL.host + + currentScriptHostURL.pathname.replace(/@vite\/client$/, '') + console.error( + '[vite] failed to connect to websocket.\n' + + 'your current setup:\n' + + ` (browser) ${currentScriptHost} <--[HTTP]--> ${serverHost} (server)\n` + + ` (browser) ${socketHost} <--[WebSocket (failing)]--> ${directSocketHost} (server)\n` + + 'Check out your Vite / network configuration and https://vitejs.dev/config/server-options.html#server-hmr .' + ) + }) socket.addEventListener( 'open', () => { @@ -120,7 +134,11 @@ async function handleMessage(payload: HMRPayload) { sendMessageBuffer() // proxy(nginx, docker) hmr ws maybe caused timeout, // so send ping package let ws keep alive. - setInterval(() => socket.send('{"type":"ping"}'), __HMR_TIMEOUT__) + setInterval(() => { + if (socket.readyState === socket.OPEN) { + socket.send('{"type":"ping"}') + } + }, __HMR_TIMEOUT__) break case 'update': notifyListeners('vite:beforeUpdate', payload) @@ -280,7 +298,8 @@ async function waitForSuccessfulPing(hostAndPath: string, ms = 1000) { try { // A fetch on a websocket URL will return a successful promise with status 400, // but will reject a networking error. - await fetch(`${location.protocol}//${hostAndPath}`) + // When running on middleware mode, it returns status 426, and an cors error happens if mode is not no-cors + await fetch(`${location.protocol}//${hostAndPath}`, { mode: 'no-cors' }) break } catch (e) { // wait ms before attempting to ping again diff --git a/packages/vite/src/client/overlay.ts b/packages/vite/src/client/overlay.ts index 150c570fbc8aaf..f9a22b7db2c6b3 100644 --- a/packages/vite/src/client/overlay.ts +++ b/packages/vite/src/client/overlay.ts @@ -115,6 +115,9 @@ code { const fileRE = /(?:[a-zA-Z]:\\|\/).*?:\d+:\d+/g const codeframeRE = /^(?:>?\s+\d+\s+\|.*|\s+\|\s*\^.*)\r?\n/gm +// Allow `ErrorOverlay` to extend `HTMLElement` even in environments where +// `HTMLElement` was not originally defined. +const { HTMLElement = class {} as typeof globalThis.HTMLElement } = globalThis export class ErrorOverlay extends HTMLElement { root: ShadowRoot @@ -184,6 +187,7 @@ export class ErrorOverlay extends HTMLElement { } export const overlayId = 'vite-error-overlay' +const { customElements } = globalThis // Ensure `customElements` is defined before the next line. if (customElements && !customElements.get(overlayId)) { customElements.define(overlayId, ErrorOverlay) } diff --git a/packages/vite/src/node/__tests__/plugins/esbuild.spec.ts b/packages/vite/src/node/__tests__/plugins/esbuild.spec.ts index 5f063301799cff..d1c98348c5c453 100644 --- a/packages/vite/src/node/__tests__/plugins/esbuild.spec.ts +++ b/packages/vite/src/node/__tests__/plugins/esbuild.spec.ts @@ -21,7 +21,11 @@ describe('resolveEsbuildTranspileOptions', () => { format: 'esm', keepNames: true, minify: true, - treeShaking: true + treeShaking: true, + supported: { + 'dynamic-import': true, + 'import-meta': true + } }) }) @@ -62,7 +66,11 @@ describe('resolveEsbuildTranspileOptions', () => { minifyIdentifiers: false, minifySyntax: true, minifyWhitespace: true, - treeShaking: true + treeShaking: true, + supported: { + 'dynamic-import': true, + 'import-meta': true + } }) }) @@ -87,7 +95,11 @@ describe('resolveEsbuildTranspileOptions', () => { minifyIdentifiers: false, minifySyntax: false, minifyWhitespace: false, - treeShaking: false + treeShaking: false, + supported: { + 'dynamic-import': true, + 'import-meta': true + } }) }) @@ -114,7 +126,11 @@ describe('resolveEsbuildTranspileOptions', () => { minifyIdentifiers: true, minifySyntax: true, minifyWhitespace: false, - treeShaking: true + treeShaking: true, + supported: { + 'dynamic-import': true, + 'import-meta': true + } }) }) @@ -138,7 +154,11 @@ describe('resolveEsbuildTranspileOptions', () => { format: 'cjs', keepNames: true, minify: true, - treeShaking: true + treeShaking: true, + supported: { + 'dynamic-import': true, + 'import-meta': true + } }) }) @@ -167,7 +187,11 @@ describe('resolveEsbuildTranspileOptions', () => { minifyIdentifiers: true, minifySyntax: true, minifyWhitespace: false, - treeShaking: true + treeShaking: true, + supported: { + 'dynamic-import': true, + 'import-meta': true + } }) }) @@ -197,7 +221,11 @@ describe('resolveEsbuildTranspileOptions', () => { minifyIdentifiers: true, minifySyntax: false, minifyWhitespace: true, - treeShaking: true + treeShaking: true, + supported: { + 'dynamic-import': true, + 'import-meta': true + } }) }) }) diff --git a/packages/vite/src/node/__tests__/plugins/import.spec.ts b/packages/vite/src/node/__tests__/plugins/import.spec.ts index d7320a70094a4d..6c1f950da4f7f2 100644 --- a/packages/vite/src/node/__tests__/plugins/import.spec.ts +++ b/packages/vite/src/node/__tests__/plugins/import.spec.ts @@ -70,9 +70,9 @@ describe('transformCjsImport', () => { ) ).toBe( 'import __vite__cjsImport0_react from "./node_modules/.vite/deps/react.js"; ' + - 'const useState = __vite__cjsImport0_react["useState"]; ' + - 'const Component = __vite__cjsImport0_react["Component"]; ' + - 'export { useState, Component }' + 'const __vite__cjsExport_useState = __vite__cjsImport0_react["useState"]; ' + + 'const __vite__cjsExport_Component = __vite__cjsImport0_react["Component"]; ' + + 'export { __vite__cjsExport_useState as useState, __vite__cjsExport_Component as Component }' ) expect( @@ -84,9 +84,9 @@ describe('transformCjsImport', () => { ) ).toBe( 'import __vite__cjsImport0_react from "./node_modules/.vite/deps/react.js"; ' + - 'const useStateAlias = __vite__cjsImport0_react["useState"]; ' + - 'const ComponentAlias = __vite__cjsImport0_react["Component"]; ' + - 'export { useStateAlias, ComponentAlias }' + 'const __vite__cjsExport_useStateAlias = __vite__cjsImport0_react["useState"]; ' + + 'const __vite__cjsExport_ComponentAlias = __vite__cjsImport0_react["Component"]; ' + + 'export { __vite__cjsExport_useStateAlias as useStateAlias, __vite__cjsExport_ComponentAlias as ComponentAlias }' ) }) @@ -108,8 +108,8 @@ describe('transformCjsImport', () => { ) ).toBe( 'import __vite__cjsImport0_react from "./node_modules/.vite/deps/react.js"; ' + - 'const React = __vite__cjsImport0_react.__esModule ? __vite__cjsImport0_react.default : __vite__cjsImport0_react; ' + - 'export { React }' + 'const __vite__cjsExport_React = __vite__cjsImport0_react.__esModule ? __vite__cjsImport0_react.default : __vite__cjsImport0_react; ' + + 'export { __vite__cjsExport_React as React }' ) expect( diff --git a/packages/vite/src/node/__tests__/utils.spec.ts b/packages/vite/src/node/__tests__/utils.spec.ts index a4ffd2b7c917be..51990edf709da2 100644 --- a/packages/vite/src/node/__tests__/utils.spec.ts +++ b/packages/vite/src/node/__tests__/utils.spec.ts @@ -56,8 +56,7 @@ describe('resolveHostname', () => { expect(await resolveHostname(undefined)).toEqual({ host: 'localhost', - name: resolved ?? 'localhost', - implicit: true + name: resolved ?? 'localhost' }) }) @@ -66,24 +65,21 @@ describe('resolveHostname', () => { expect(await resolveHostname('localhost')).toEqual({ host: 'localhost', - name: resolved ?? 'localhost', - implicit: false + name: resolved ?? 'localhost' }) }) test('accepts 0.0.0.0', async () => { expect(await resolveHostname('0.0.0.0')).toEqual({ host: '0.0.0.0', - name: 'localhost', - implicit: false + name: 'localhost' }) }) test('accepts ::', async () => { expect(await resolveHostname('::')).toEqual({ host: '::', - name: 'localhost', - implicit: false + name: 'localhost' }) }) @@ -92,8 +88,7 @@ describe('resolveHostname', () => { await resolveHostname('0000:0000:0000:0000:0000:0000:0000:0000') ).toEqual({ host: '0000:0000:0000:0000:0000:0000:0000:0000', - name: 'localhost', - implicit: false + name: 'localhost' }) }) }) diff --git a/packages/vite/src/node/build.ts b/packages/vite/src/node/build.ts index 294ff48654d301..12f123413534a4 100644 --- a/packages/vite/src/node/build.ts +++ b/packages/vite/src/node/build.ts @@ -297,14 +297,15 @@ export function resolveBuildPlugins(config: ResolvedConfig): { post: Plugin[] } { const options = config.build - + const { commonjsOptions } = options + const usePluginCommonjs = + !Array.isArray(commonjsOptions?.include) || + commonjsOptions?.include.length !== 0 return { pre: [ ...(options.watch ? [ensureWatchPlugin()] : []), watchPackageDataPlugin(config), - ...(config.legacy?.buildRollupPluginCommonjs - ? [commonjsPlugin(options.commonjsOptions)] - : []), + ...(usePluginCommonjs ? [commonjsPlugin(options.commonjsOptions)] : []), dataURIPlugin(), assetImportMetaUrlPlugin(config), ...(options.rollupOptions.plugins @@ -398,7 +399,7 @@ async function doBuild( external = await cjsSsrResolveExternal(config, userExternal) } - if (isDepsOptimizerEnabled(config)) { + if (isDepsOptimizerEnabled(config, ssr)) { await initDepsOptimizer(config) } @@ -465,10 +466,10 @@ async function doBuild( ? `[name].${jsExt}` : libOptions ? resolveLibFilename(libOptions, format, config.root, jsExt) - : path.posix.join(options.assetsDir, `[name].[hash].js`), + : path.posix.join(options.assetsDir, `[name].[hash].${jsExt}`), chunkFileNames: libOptions ? `[name].[hash].${jsExt}` - : path.posix.join(options.assetsDir, `[name].[hash].js`), + : path.posix.join(options.assetsDir, `[name].[hash].${jsExt}`), assetFileNames: libOptions ? `[name].[ext]` : path.posix.join(options.assetsDir, `[name].[hash].[ext]`), @@ -739,7 +740,7 @@ async function cjsSsrResolveExternal( } catch (e) {} if (!knownImports) { // no dev deps optimization data, do a fresh scan - knownImports = await findKnownImports(config) + knownImports = await findKnownImports(config, false) // needs to use non-ssr } const ssrExternals = cjsSsrResolveExternals(config, knownImports) @@ -842,7 +843,7 @@ export function toOutputFilePathInString( toRelative: ( filename: string, hostType: string - ) => string | { runtime: string } + ) => string | { runtime: string } = toImportMetaURLBasedRelativePath ): string | { runtime: string } { const { renderBuiltUrl } = config.experimental let relative = config.base === '' || config.base === './' @@ -870,6 +871,17 @@ export function toOutputFilePathInString( return config.base + filename } +function toImportMetaURLBasedRelativePath( + filename: string, + importer: string +): { runtime: string } { + return { + runtime: `new URL(${JSON.stringify( + path.posix.relative(path.dirname(importer), filename) + )},import.meta.url).href` + } +} + export function toOutputFilePathWithoutRuntime( filename: string, type: 'asset' | 'public', diff --git a/packages/vite/src/node/certificate.ts b/packages/vite/src/node/certificate.ts deleted file mode 100644 index d8ce82d6b5365d..00000000000000 --- a/packages/vite/src/node/certificate.ts +++ /dev/null @@ -1,169 +0,0 @@ -// Simplified fork of selfsigned with inlined options and partial -// node-forge usage to achieve smaller bundle. See: -// https://github.com/jfromaniello/selfsigned/blob/da38146f8d02183c35f49f91659a744a243e8707/index.js -// -// this utility create untrusted certificate which still -// allows to access page after proceeding a wall with warning -// -// should be deprecated eventually and replaced with recipes -// about generating secure trusted certificates -// -// ## selfsigned -// License: MIT -// By: José F. Romaniello, Paolo Fragomeni, Charles Bushong -// Repository: git://github.com/jfromaniello/selfsigned.git -// MIT License -// Copyright (c) 2013 José F. Romaniello -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -// @ts-ignore -import forge from 'node-forge/lib/forge' -// @ts-ignore -import 'node-forge/lib/pki' - -// a hexString is considered negative if it's most significant bit is 1 -// because serial numbers use ones' complement notation -// this RFC in section 4.1.2.2 requires serial numbers to be positive -// http://www.ietf.org/rfc/rfc5280.txt -function toPositiveHex(hexString: string) { - let mostSignificativeHexAsInt = parseInt(hexString[0], 16) - if (mostSignificativeHexAsInt < 8) { - return hexString - } - - mostSignificativeHexAsInt -= 8 - return mostSignificativeHexAsInt.toString() + hexString.substring(1) -} - -export function createCertificate(): string { - const days = 30 - const keySize = 2048 - - const extensions = [ - // { - // name: 'basicConstraints', - // cA: true, - // }, - { - name: 'keyUsage', - keyCertSign: true, - digitalSignature: true, - nonRepudiation: true, - keyEncipherment: true, - dataEncipherment: true - }, - { - name: 'extKeyUsage', - serverAuth: true, - clientAuth: true, - codeSigning: true, - timeStamping: true - }, - { - name: 'subjectAltName', - altNames: [ - { - // type 2 is DNS - type: 2, - value: 'localhost' - }, - { - type: 2, - value: 'localhost.localdomain' - }, - { - type: 2, - value: 'lvh.me' - }, - { - type: 2, - value: '*.lvh.me' - }, - { - type: 2, - value: '[::1]' - }, - { - // type 7 is IP - type: 7, - ip: '127.0.0.1' - }, - { - type: 7, - ip: 'fe80::1' - } - ] - } - ] - - const attrs = [ - { - name: 'commonName', - value: 'example.org' - }, - { - name: 'countryName', - value: 'US' - }, - { - shortName: 'ST', - value: 'Virginia' - }, - { - name: 'localityName', - value: 'Blacksburg' - }, - { - name: 'organizationName', - value: 'Test' - }, - { - shortName: 'OU', - value: 'Test' - } - ] - - const keyPair = forge.pki.rsa.generateKeyPair(keySize) - - const cert = forge.pki.createCertificate() - - cert.serialNumber = toPositiveHex( - forge.util.bytesToHex(forge.random.getBytesSync(9)) - ) // the serial number can be decimal or hex (if preceded by 0x) - - cert.validity.notBefore = new Date() - cert.validity.notAfter = new Date() - cert.validity.notAfter.setDate(cert.validity.notBefore.getDate() + days) - - cert.setSubject(attrs) - cert.setIssuer(attrs) - - cert.publicKey = keyPair.publicKey - - cert.setExtensions(extensions) - - const algorithm = forge.md.sha256.create() - cert.sign(keyPair.privateKey, algorithm) - - const privateKeyPem = forge.pki.privateKeyToPem(keyPair.privateKey) - const certPem = forge.pki.certificateToPem(cert) - - return privateKeyPem + certPem -} diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts index 1dd6a50ebe2b87..55374774da6ecc 100644 --- a/packages/vite/src/node/config.ts +++ b/packages/vite/src/node/config.ts @@ -7,7 +7,6 @@ import colors from 'picocolors' import type { Alias, AliasOptions } from 'types/alias' import aliasPlugin from '@rollup/plugin-alias' import { build } from 'esbuild' -import type { Plugin as ESBuildPlugin } from 'esbuild' import type { RollupOptions } from 'rollup' import type { Plugin } from './plugin' import type { @@ -28,7 +27,6 @@ import { dynamicImport, isExternalUrl, isObject, - isTS, lookupFile, mergeAlias, mergeConfig, @@ -47,7 +45,7 @@ import type { InternalResolveOptions, ResolveOptions } from './plugins/resolve' import { resolvePlugin } from './plugins/resolve' import type { LogLevel, Logger } from './logger' import { createLogger } from './logger' -import type { DepOptimizationOptions } from './optimizer' +import type { DepOptimizationConfig, DepOptimizationOptions } from './optimizer' import type { JsonOptions } from './plugins/json' import type { PluginContainer } from './server/pluginContainer' import { createPluginContainer } from './server/pluginContainer' @@ -66,7 +64,10 @@ export type { RenderBuiltAssetUrl } from './build' export interface ConfigEnv { command: 'build' | 'serve' mode: string - ssrBuild: boolean + /** + * @experimental + */ + ssrBuild?: boolean } /** @@ -278,14 +279,6 @@ export interface ExperimentalOptions { } export interface LegacyOptions { - /** - * Revert vite build to the v2.9 strategy. Disable esbuild deps optimization and adds `@rollup/plugin-commonjs` - * - * @experimental - * @deprecated - * @default false - */ - buildRollupPluginCommonjs?: boolean /** * Revert vite build --ssr to the v2.9 strategy. Use CJS SSR build and v2.9 externalization heuristics * @@ -331,7 +324,7 @@ export type ResolvedConfig = Readonly< server: ResolvedServerOptions build: ResolvedBuildOptions preview: ResolvedPreviewOptions - ssr: ResolvedSSROptions | undefined + ssr: ResolvedSSROptions assetsInclude: (file: string) => boolean logger: Logger createResolver: (options?: Partial) => ResolveFn @@ -366,6 +359,10 @@ export async function resolveConfig( if (mode === 'production') { process.env.NODE_ENV = 'production' } + // production env would not work in serve, fallback to development + if (command === 'serve' && process.env.NODE_ENV === 'production') { + process.env.NODE_ENV = 'development' + } const configEnv = { mode, @@ -398,6 +395,23 @@ export async function resolveConfig( mode = inlineConfig.mode || config.mode || mode configEnv.mode = mode + // Some plugins that aren't intended to work in the bundling of workers (doing post-processing at build time for example). + // And Plugins may also have cached that could be corrupted by being used in these extra rollup calls. + // So we need to separate the worker plugin from the plugin that vite needs to run. + const rawWorkerUserPlugins = ( + (await asyncFlatten(config.worker?.plugins || [])) as Plugin[] + ).filter((p) => { + if (!p) { + return false + } else if (!p.apply) { + return true + } else if (typeof p.apply === 'function') { + return p.apply({ ...config, mode }, configEnv) + } else { + return p.apply === command + } + }) + // resolve plugins const rawUserPlugins = ( (await asyncFlatten(config.plugins || [])) as Plugin[] @@ -415,13 +429,6 @@ export async function resolveConfig( const [prePlugins, normalPlugins, postPlugins] = sortUserPlugins(rawUserPlugins) - // resolve worker - const resolvedWorkerOptions: ResolveWorkerOptions = { - format: config.worker?.format || 'iife', - plugins: [], - rollupOptions: config.worker?.rollupOptions || {} - } - // run config hooks const userPlugins = [...prePlugins, ...normalPlugins, ...postPlugins] for (const p of userPlugins) { @@ -433,6 +440,15 @@ export async function resolveConfig( } } + if (process.env.VITE_TEST_WITHOUT_PLUGIN_COMMONJS) { + config = mergeConfig(config, { + optimizeDeps: { disabled: false }, + ssr: { optimizeDeps: { disabled: false } } + }) + config.build ??= {} + config.build.commonjsOptions = { include: [] } + } + // resolve root const resolvedRoot = normalizePath( config.root ? path.resolve(config.root) : process.cwd() @@ -543,7 +559,9 @@ export async function resolveConfig( ] })) } - return (await container.resolveId(id, importer, { ssr }))?.id + return ( + await container.resolveId(id, importer, { ssr, scan: options?.scan }) + )?.id } } @@ -557,28 +575,44 @@ export async function resolveConfig( : '' const server = resolveServerOptions(resolvedRoot, config.server, logger) - let ssr = resolveSSROptions(config.ssr) - if (config.legacy?.buildSsrCjsExternalHeuristics) { - if (ssr) ssr.format = 'cjs' - else ssr = { target: 'node', format: 'cjs' } - } + const ssr = resolveSSROptions( + config.ssr, + config.legacy?.buildSsrCjsExternalHeuristics, + config.resolve?.preserveSymlinks + ) const middlewareMode = config?.server?.middlewareMode - config = mergeConfig(config, externalConfigCompat(config, configEnv)) const optimizeDeps = config.optimizeDeps || {} - if (process.env.VITE_TEST_LEGACY_CJS_PLUGIN) { - config.legacy = { - ...config.legacy, - buildRollupPluginCommonjs: true + const BASE_URL = resolvedBase + + // resolve worker + let workerConfig = mergeConfig({}, config) + const [workerPrePlugins, workerNormalPlugins, workerPostPlugins] = + sortUserPlugins(rawWorkerUserPlugins) + + // run config hooks + const workerUserPlugins = [ + ...workerPrePlugins, + ...workerNormalPlugins, + ...workerPostPlugins + ] + for (const p of workerUserPlugins) { + if (p.config) { + const res = await p.config(workerConfig, configEnv) + if (res) { + workerConfig = mergeConfig(workerConfig, res) + } } } + const resolvedWorkerOptions: ResolveWorkerOptions = { + format: workerConfig.worker?.format || 'iife', + plugins: [], + rollupOptions: workerConfig.worker?.rollupOptions || {} + } - const BASE_URL = resolvedBase - - const resolved: ResolvedConfig = { - ...config, + const resolvedConfig: ResolvedConfig = { configFile: configFile ? normalizePath(configFile) : undefined, configFileDependencies: configFileDependencies.map((name) => normalizePath(path.resolve(name)) @@ -613,6 +647,7 @@ export async function resolveConfig( packageCache: new Map(), createResolver, optimizeDeps: { + disabled: 'build', ...optimizeDeps, esbuildOptions: { preserveSymlinks: config.resolve?.preserveSymlinks, @@ -620,13 +655,51 @@ export async function resolveConfig( } }, worker: resolvedWorkerOptions, - appType: config.appType ?? middlewareMode === 'ssr' ? 'custom' : 'spa', + appType: config.appType ?? (middlewareMode === 'ssr' ? 'custom' : 'spa'), experimental: { importGlobRestoreExtension: false, hmrPartialAccept: false, ...config.experimental } } + const resolved: ResolvedConfig = { + ...config, + ...resolvedConfig + } + + ;(resolved.plugins as Plugin[]) = await resolvePlugins( + resolved, + prePlugins, + normalPlugins, + postPlugins + ) + + const workerResolved: ResolvedConfig = { + ...workerConfig, + ...resolvedConfig, + isWorker: true, + mainConfig: resolved + } + + resolvedConfig.worker.plugins = await resolvePlugins( + workerResolved, + workerPrePlugins, + workerNormalPlugins, + workerPostPlugins + ) + + // call configResolved hooks + await Promise.all( + userPlugins + .map((p) => p.configResolved?.(resolved)) + .concat( + resolvedConfig.worker.plugins.map((p) => + p.configResolved?.(workerResolved) + ) + ) + ) + + // validate config if (middlewareMode === 'ssr') { logger.warn( @@ -658,45 +731,6 @@ export async function resolveConfig( ) } - if (resolved.legacy?.buildRollupPluginCommonjs) { - const optimizerDisabled = resolved.optimizeDeps.disabled - if (!optimizerDisabled) { - resolved.optimizeDeps.disabled = 'build' - } else if (optimizerDisabled === 'dev') { - resolved.optimizeDeps.disabled = true // Also disabled during build - } - } - - // Some plugins that aren't intended to work in the bundling of workers (doing post-processing at build time for example). - // And Plugins may also have cached that could be corrupted by being used in these extra rollup calls. - // So we need to separate the worker plugin from the plugin that vite needs to run. - const [workerPrePlugins, workerNormalPlugins, workerPostPlugins] = - sortUserPlugins(config.worker?.plugins as Plugin[]) - const workerResolved: ResolvedConfig = { - ...resolved, - isWorker: true, - mainConfig: resolved - } - resolved.worker.plugins = await resolvePlugins( - workerResolved, - workerPrePlugins, - workerNormalPlugins, - workerPostPlugins - ) - // call configResolved worker plugins hooks - await Promise.all( - resolved.worker.plugins.map((p) => p.configResolved?.(workerResolved)) - ) - ;(resolved.plugins as Plugin[]) = await resolvePlugins( - resolved, - prePlugins, - normalPlugins, - postPlugins - ) - - // call configResolved hooks - await Promise.all(userPlugins.map((p) => p.configResolved?.(resolved))) - if (process.env.DEBUG) { debug(`using resolved config: %O`, { ...resolved, @@ -823,7 +857,6 @@ export async function loadConfigFromFile( const getTime = () => `${(performance.now() - start).toFixed(2)}ms` let resolvedPath: string | undefined - let dependencies: string[] = [] if (configFile) { // explicit config path is always resolved from cwd @@ -859,42 +892,13 @@ export async function loadConfigFromFile( } try { - let userConfig: UserConfigExport | undefined - - if (isESM) { - const fileUrl = pathToFileURL(resolvedPath) - const bundled = await bundleConfigFile(resolvedPath, true) - dependencies = bundled.dependencies - - if (isTS(resolvedPath)) { - // before we can register loaders without requiring users to run node - // with --experimental-loader themselves, we have to do a hack here: - // bundle the config file w/ ts transforms first, write it to disk, - // load it with native Node ESM, then delete the file. - fs.writeFileSync(resolvedPath + '.mjs', bundled.code) - try { - userConfig = (await dynamicImport(`${fileUrl}.mjs?t=${Date.now()}`)) - .default - } finally { - fs.unlinkSync(resolvedPath + '.mjs') - } - debug(`TS + native esm config loaded in ${getTime()}`, fileUrl) - } else { - // using Function to avoid this from being compiled away by TS/Rollup - // append a query so that we force reload fresh config in case of - // server restart - userConfig = (await dynamicImport(`${fileUrl}?t=${Date.now()}`)).default - debug(`native esm config loaded in ${getTime()}`, fileUrl) - } - } - - if (!userConfig) { - // Bundle config file and transpile it to cjs using esbuild. - const bundled = await bundleConfigFile(resolvedPath) - dependencies = bundled.dependencies - userConfig = await loadConfigFromBundledFile(resolvedPath, bundled.code) - debug(`bundled config file loaded in ${getTime()}`) - } + const bundled = await bundleConfigFile(resolvedPath, isESM) + const userConfig = await loadConfigFromBundledFile( + resolvedPath, + bundled.code, + isESM + ) + debug(`bundled config file loaded in ${getTime()}`) const config = await (typeof userConfig === 'function' ? userConfig(configEnv) @@ -905,7 +909,7 @@ export async function loadConfigFromFile( return { path: normalizePath(resolvedPath), config, - dependencies + dependencies: bundled.dependencies } } catch (e) { createLogger(logLevel).error( @@ -918,8 +922,10 @@ export async function loadConfigFromFile( async function bundleConfigFile( fileName: string, - isESM = false + isESM: boolean ): Promise<{ code: string; dependencies: string[] }> { + const dirnameVarName = '__vite_injected_original_dirname' + const filenameVarName = '__vite_injected_original_filename' const importMetaUrlVarName = '__vite_injected_original_import_meta_url' const result = await build({ absWorkingDir: process.cwd(), @@ -932,19 +938,48 @@ async function bundleConfigFile( sourcemap: 'inline', metafile: true, define: { + __dirname: dirnameVarName, + __filename: filenameVarName, 'import.meta.url': importMetaUrlVarName }, plugins: [ { name: 'externalize-deps', setup(build) { - build.onResolve({ filter: /.*/ }, (args) => { - const id = args.path + build.onResolve({ filter: /.*/ }, ({ path: id, importer }) => { + // externalize bare imports if (id[0] !== '.' && !path.isAbsolute(id)) { return { external: true } } + // bundle the rest and make sure that the we can also access + // it's third-party dependencies. externalize if not. + // monorepo/ + // ├─ package.json + // ├─ utils.js -----------> bundle (share same node_modules) + // ├─ vite-project/ + // │ ├─ vite.config.js --> entry + // │ ├─ package.json + // ├─ foo-project/ + // │ ├─ utils.js --------> external (has own node_modules) + // │ ├─ package.json + const idFsPath = path.resolve(path.dirname(importer), id) + const idPkgPath = lookupFile(idFsPath, [`package.json`], { + pathOnly: true + }) + if (idPkgPath) { + const idPkgDir = path.dirname(idPkgPath) + // if this file needs to go up one or more directory to reach the vite config, + // that means it has it's own node_modules (e.g. foo-project) + if (path.relative(idPkgDir, fileName).startsWith('..')) { + return { + // normalize actual import after bundled as a single vite config + path: idFsPath, + external: true + } + } + } }) } }, @@ -954,14 +989,16 @@ async function bundleConfigFile( build.onLoad({ filter: /\.[cm]?[jt]s$/ }, async (args) => { const contents = await fs.promises.readFile(args.path, 'utf8') const injectValues = - `const __dirname = ${JSON.stringify(path.dirname(args.path))};` + - `const __filename = ${JSON.stringify(args.path)};` + + `const ${dirnameVarName} = ${JSON.stringify( + path.dirname(args.path) + )};` + + `const ${filenameVarName} = ${JSON.stringify(args.path)};` + `const ${importMetaUrlVarName} = ${JSON.stringify( pathToFileURL(args.path).href )};` return { - loader: isTS(args.path) ? 'ts' : 'js', + loader: args.path.endsWith('ts') ? 'ts' : 'js', contents: injectValues + contents } }) @@ -983,110 +1020,59 @@ interface NodeModuleWithCompile extends NodeModule { const _require = createRequire(import.meta.url) async function loadConfigFromBundledFile( fileName: string, - bundledCode: string -): Promise { - const realFileName = fs.realpathSync(fileName) - const defaultLoader = _require.extensions['.js'] - _require.extensions['.js'] = (module: NodeModule, filename: string) => { - if (filename === realFileName) { - ;(module as NodeModuleWithCompile)._compile(bundledCode, filename) - } else { - defaultLoader(module, filename) + bundledCode: string, + isESM: boolean +): Promise { + // for esm, before we can register loaders without requiring users to run node + // with --experimental-loader themselves, we have to do a hack here: + // write it to disk, load it with native Node ESM, then delete the file. + if (isESM) { + const fileBase = `${fileName}.timestamp-${Date.now()}` + const fileNameTmp = `${fileBase}.mjs` + const fileUrl = `${pathToFileURL(fileBase)}.mjs` + fs.writeFileSync(fileNameTmp, bundledCode) + try { + return (await dynamicImport(fileUrl)).default + } finally { + fs.unlinkSync(fileNameTmp) + } + } + // for cjs, we can register a custom loader via `_require.extensions` + else { + const extension = path.extname(fileName) + const realFileName = fs.realpathSync(fileName) + const loaderExt = extension in _require.extensions ? extension : '.js' + const defaultLoader = _require.extensions[loaderExt]! + _require.extensions[loaderExt] = (module: NodeModule, filename: string) => { + if (filename === realFileName) { + ;(module as NodeModuleWithCompile)._compile(bundledCode, filename) + } else { + defaultLoader(module, filename) + } } + // clear cache in case of server restart + delete _require.cache[_require.resolve(fileName)] + const raw = _require(fileName) + _require.extensions[loaderExt] = defaultLoader + return raw.__esModule ? raw.default : raw } - // clear cache in case of server restart - delete _require.cache[_require.resolve(fileName)] - const raw = _require(fileName) - _require.extensions['.js'] = defaultLoader - return raw.__esModule ? raw.default : raw } -export function isDepsOptimizerEnabled(config: ResolvedConfig): boolean { - const { command, optimizeDeps } = config - const { disabled } = optimizeDeps +export function getDepOptimizationConfig( + config: ResolvedConfig, + ssr: boolean +): DepOptimizationConfig { + return ssr ? config.ssr.optimizeDeps : config.optimizeDeps +} +export function isDepsOptimizerEnabled( + config: ResolvedConfig, + ssr: boolean +): boolean { + const { command } = config + const { disabled } = getDepOptimizationConfig(config, ssr) return !( disabled === true || (command === 'build' && disabled === 'build') || - (command === 'serve' && optimizeDeps.disabled === 'dev') + (command === 'serve' && disabled === 'dev') ) } - -// esbuild doesn't transpile `require('foo')` into `import` statements if 'foo' is externalized -// https://github.com/evanw/esbuild/issues/566#issuecomment-735551834 -function esbuildCjsExternalPlugin(externals: string[]): ESBuildPlugin { - return { - name: 'cjs-external', - setup(build) { - const escape = (text: string) => - `^${text.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')}$` - const filter = new RegExp(externals.map(escape).join('|')) - - build.onResolve({ filter: /.*/, namespace: 'external' }, (args) => ({ - path: args.path, - external: true - })) - - build.onResolve({ filter }, (args) => ({ - path: args.path, - namespace: 'external' - })) - - build.onLoad({ filter: /.*/, namespace: 'external' }, (args) => ({ - contents: `export * from ${JSON.stringify(args.path)}` - })) - } - } -} - -// Support `rollupOptions.external` when `legacy.buildRollupPluginCommonjs` is disabled -function externalConfigCompat(config: UserConfig, { command }: ConfigEnv) { - // Only affects the build command - if (command !== 'build') { - return {} - } - - // Skip if using Rollup CommonJS plugin - if ( - config.legacy?.buildRollupPluginCommonjs || - config.optimizeDeps?.disabled === 'build' - ) { - return {} - } - - // Skip if no `external` configured - const external = config?.build?.rollupOptions?.external - if (!external) { - return {} - } - - let normalizedExternal = external - if (typeof external === 'string') { - normalizedExternal = [external] - } - - // TODO: decide whether to support RegExp and function options - // They're not supported yet because `optimizeDeps.exclude` currently only accepts strings - if ( - !Array.isArray(normalizedExternal) || - normalizedExternal.some((ext) => typeof ext !== 'string') - ) { - throw new Error( - `[vite] 'build.rollupOptions.external' can only be an array of strings or a string.\n` + - `You can turn on 'legacy.buildRollupPluginCommonjs' to support more advanced options.` - ) - } - - const additionalConfig: UserConfig = { - optimizeDeps: { - exclude: normalizedExternal as string[], - esbuildOptions: { - plugins: [ - // TODO: maybe it can be added globally/unconditionally? - esbuildCjsExternalPlugin(normalizedExternal as string[]) - ] - } - } - } - - return additionalConfig -} diff --git a/packages/vite/src/node/constants.ts b/packages/vite/src/node/constants.ts index 5a108652ef7ce6..b5fb126e97beaa 100644 --- a/packages/vite/src/node/constants.ts +++ b/packages/vite/src/node/constants.ts @@ -24,6 +24,7 @@ export const ESBUILD_MODULES_TARGET = [ export const DEFAULT_EXTENSIONS = [ '.mjs', '.js', + '.mts', '.ts', '.jsx', '.tsx', @@ -41,7 +42,7 @@ export const DEFAULT_CONFIG_FILES = [ export const JS_TYPES_RE = /\.(?:j|t)sx?$|\.mjs$/ -export const OPTIMIZABLE_ENTRY_RE = /\.(?:(m|c)?js|ts)$/ +export const OPTIMIZABLE_ENTRY_RE = /\.(?:[cm]?[jt]s)$/ export const SPECIAL_QUERY_RE = /[\?&](?:worker|sharedworker|raw|url)\b/ diff --git a/packages/vite/src/node/http.ts b/packages/vite/src/node/http.ts index d34e67d62aeb36..18ce37f6a327e1 100644 --- a/packages/vite/src/node/http.ts +++ b/packages/vite/src/node/http.ts @@ -1,4 +1,4 @@ -import fs, { promises as fsp } from 'node:fs' +import fs from 'node:fs' import path from 'node:path' import type { Server as HttpServer, @@ -134,9 +134,6 @@ export async function resolveHttpsConfig( key: readFileIfExists(key), pfx: readFileIfExists(pfx) }) - if (!httpsOption.key || !httpsOption.cert) { - httpsOption.cert = httpsOption.key = await getCertificate(cacheDir) - } return httpsOption } @@ -151,30 +148,6 @@ function readFileIfExists(value?: string | Buffer | any[]) { return value } -async function getCertificate(cacheDir: string) { - const cachePath = path.join(cacheDir, '_cert.pem') - - try { - const [stat, content] = await Promise.all([ - fsp.stat(cachePath), - fsp.readFile(cachePath, 'utf8') - ]) - - if (Date.now() - stat.ctime.valueOf() > 30 * 24 * 60 * 60 * 1000) { - throw new Error('cache is outdated.') - } - - return content - } catch { - const content = (await import('./certificate')).createCertificate() - fsp - .mkdir(cacheDir, { recursive: true }) - .then(() => fsp.writeFile(cachePath, content)) - .catch(() => {}) - return content - } -} - export async function httpServerStart( httpServer: HttpServer, serverOptions: { diff --git a/packages/vite/src/node/index.ts b/packages/vite/src/node/index.ts index e1a9de026ffc1e..7dfada6825780b 100644 --- a/packages/vite/src/node/index.ts +++ b/packages/vite/src/node/index.ts @@ -17,7 +17,8 @@ export type { ServerOptions, FileSystemServeOptions, ServerHook, - ResolvedServerOptions + ResolvedServerOptions, + ResolvedServerUrls } from './server' export type { BuildOptions, @@ -35,6 +36,7 @@ export type { export type { DepOptimizationMetadata, DepOptimizationOptions, + DepOptimizationConfig, DepOptimizationResult, DepOptimizationProcessing, OptimizedDepInfo, @@ -43,6 +45,7 @@ export type { } from './optimizer' export type { ResolvedSSROptions, + SsrDepOptimizationOptions, SSROptions, SSRFormat, SSRTarget diff --git a/packages/vite/src/node/logger.ts b/packages/vite/src/node/logger.ts index 597de2358f43e3..d0c5d29334c023 100644 --- a/packages/vite/src/node/logger.ts +++ b/packages/vite/src/node/logger.ts @@ -1,15 +1,9 @@ /* eslint no-console: 0 */ -import type { AddressInfo, Server } from 'node:net' -import os from 'node:os' import readline from 'readline' import colors from 'picocolors' import type { RollupError } from 'rollup' -import type { CommonServerOptions } from './http' -import type { Hostname } from './utils' -import { resolveHostname } from './utils' -import { loopbackHosts } from './constants' -import type { ResolvedConfig } from '.' +import type { ResolvedServerUrls } from './server' export type LogType = 'error' | 'warn' | 'info' export type LogLevel = LogType | 'silent' @@ -145,94 +139,23 @@ export function createLogger( return logger } -export async function printCommonServerUrls( - server: Server, - options: CommonServerOptions, - config: ResolvedConfig -): Promise { - const address = server.address() - const isAddressInfo = (x: any): x is AddressInfo => x?.address - if (isAddressInfo(address)) { - const hostname = await resolveHostname(options.host) - const protocol = options.https ? 'https' : 'http' - const base = config.base === './' || config.base === '' ? '/' : config.base - printServerUrls(hostname, protocol, address.port, base, config.logger.info) - } -} - -function printServerUrls( - hostname: Hostname, - protocol: string, - port: number, - base: string, +export function printServerUrls( + urls: ResolvedServerUrls, + optionsHost: string | boolean | undefined, info: Logger['info'] ): void { - const urls: Array<{ label: string; url: string; disabled?: boolean }> = [] - const notes: Array<{ label: string; message: string }> = [] - - if (hostname.host && loopbackHosts.has(hostname.host)) { - let hostnameName = hostname.name - if ( - hostnameName === '::1' || - hostnameName === '0000:0000:0000:0000:0000:0000:0000:0001' - ) { - hostnameName = `[${hostnameName}]` - } - - urls.push({ - label: 'Local', - url: colors.cyan( - `${protocol}://${hostnameName}:${colors.bold(port)}${base}` - ) - }) - - if (hostname.implicit) { - urls.push({ - label: 'Network', - url: `use ${colors.white(colors.bold('--host'))} to expose`, - disabled: true - }) - } - } else { - Object.values(os.networkInterfaces()) - .flatMap((nInterface) => nInterface ?? []) - .filter( - (detail) => - detail && - detail.address && - // Node < v18 - ((typeof detail.family === 'string' && detail.family === 'IPv4') || - // Node >= v18 - (typeof detail.family === 'number' && detail.family === 4)) - ) - .forEach((detail) => { - const host = detail.address.replace('127.0.0.1', hostname.name) - const url = `${protocol}://${host}:${colors.bold(port)}${base}` - const label = detail.address.includes('127.0.0.1') ? 'Local' : 'Network' - - urls.push({ label, url: colors.cyan(url) }) - }) + const colorUrl = (url: string) => + colors.cyan(url.replace(/:(\d+)\//, (_, port) => `:${colors.bold(port)}/`)) + for (const url of urls.local) { + info(` ${colors.green('➜')} ${colors.bold('Local')}: ${colorUrl(url)}`) } - - const length = Math.max( - ...[...urls, ...notes].map(({ label }) => label.length) - ) - const print = ( - iconWithColor: string, - label: string, - messageWithColor: string, - disabled?: boolean - ) => { - const message = ` ${iconWithColor} ${ - label ? colors.bold(label) + ':' : ' ' - } ${' '.repeat(length - label.length)}${messageWithColor}` - info(disabled ? colors.dim(message) : message) + for (const url of urls.network) { + info(` ${colors.green('➜')} ${colors.bold('Network')}: ${colorUrl(url)}`) + } + if (urls.network.length === 0 && optionsHost === undefined) { + const note = `use ${colors.white(colors.bold('--host'))} to expose` + info( + colors.dim(` ${colors.green('➜')} ${colors.bold('Network')}: ${note}`) + ) } - - urls.forEach(({ label, url: text, disabled }) => { - print(colors.green('➜'), label, text, disabled) - }) - notes.forEach(({ label, message: text }) => { - print(colors.white('❖'), label, text) - }) } diff --git a/packages/vite/src/node/optimizer/esbuildDepPlugin.ts b/packages/vite/src/node/optimizer/esbuildDepPlugin.ts index d41caca22d2d4a..57e67c2b47a166 100644 --- a/packages/vite/src/node/optimizer/esbuildDepPlugin.ts +++ b/packages/vite/src/node/optimizer/esbuildDepPlugin.ts @@ -2,6 +2,7 @@ import path from 'node:path' import { promises as fs } from 'node:fs' import type { ImportKind, Plugin } from 'esbuild' import { KNOWN_ASSET_TYPES } from '../constants' +import { getDepOptimizationConfig } from '..' import type { ResolvedConfig } from '..' import { flattenId, @@ -28,6 +29,8 @@ const externalTypes = [ 'stylus', 'pcss', 'postcss', + // wasm + 'wasm', // known SFC types 'vue', 'svelte', @@ -43,14 +46,15 @@ const externalTypes = [ export function esbuildDepPlugin( qualified: Record, exportsData: Record, + external: string[], config: ResolvedConfig, ssr: boolean ): Plugin { + const { extensions } = getDepOptimizationConfig(config, ssr) + // remove optimizable extensions from `externalTypes` list - const allExternalTypes = config.optimizeDeps.extensions - ? externalTypes.filter( - (type) => !config.optimizeDeps.extensions?.includes('.' + type) - ) + const allExternalTypes = extensions + ? externalTypes.filter((type) => !extensions?.includes('.' + type)) : externalTypes // default resolver which prefers ESM @@ -163,7 +167,7 @@ export function esbuildDepPlugin( build.onResolve( { filter: /^[\w@][^:]/ }, async ({ path: id, importer, kind }) => { - if (moduleListContains(config.optimizeDeps?.exclude, id)) { + if (moduleListContains(external, id)) { return { path: id, external: true @@ -301,3 +305,30 @@ module.exports = Object.create(new Proxy({}, { } } } + +// esbuild doesn't transpile `require('foo')` into `import` statements if 'foo' is externalized +// https://github.com/evanw/esbuild/issues/566#issuecomment-735551834 +export function esbuildCjsExternalPlugin(externals: string[]): Plugin { + return { + name: 'cjs-external', + setup(build) { + const escape = (text: string) => + `^${text.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')}$` + const filter = new RegExp(externals.map(escape).join('|')) + + build.onResolve({ filter: /.*/, namespace: 'external' }, (args) => ({ + path: args.path, + external: true + })) + + build.onResolve({ filter }, (args) => ({ + path: args.path, + namespace: 'external' + })) + + build.onLoad({ filter: /.*/, namespace: 'external' }, (args) => ({ + contents: `export * from ${JSON.stringify(args.path)}` + })) + } + } +} diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts index 4bed3a1d8ea514..b678d983353c8f 100644 --- a/packages/vite/src/node/optimizer/index.ts +++ b/packages/vite/src/node/optimizer/index.ts @@ -7,6 +7,7 @@ import type { BuildOptions as EsbuildBuildOptions } from 'esbuild' import { build } from 'esbuild' import { init, parse } from 'es-module-lexer' import { createFilter } from '@rollup/pluginutils' +import { getDepOptimizationConfig } from '../config' import type { ResolvedConfig } from '../config' import { arraify, @@ -24,7 +25,7 @@ import { } from '../utils' import { transformWithEsbuild } from '../plugins/esbuild' import { ESBUILD_MODULES_TARGET } from '../constants' -import { esbuildDepPlugin } from './esbuildDepPlugin' +import { esbuildCjsExternalPlugin, esbuildDepPlugin } from './esbuildDepPlugin' import { scanImports } from './scan' export { initDepsOptimizer, @@ -53,11 +54,7 @@ export type ExportsData = { export interface DepsOptimizer { metadata: DepOptimizationMetadata scanProcessing?: Promise - registerMissingImport: ( - id: string, - resolved: string, - ssr?: boolean - ) => OptimizedDepInfo + registerMissingImport: (id: string, resolved: string) => OptimizedDepInfo run: () => void isOptimizedDepFile: (id: string) => boolean @@ -71,18 +68,7 @@ export interface DepsOptimizer { options: DepOptimizationOptions } -export interface DepOptimizationOptions { - /** - * By default, Vite will crawl your `index.html` to detect dependencies that - * need to be pre-bundled. If `build.rollupOptions.input` is specified, Vite - * will crawl those entry points instead. - * - * If neither of these fit your needs, you can specify custom entries using - * this option - the value should be a fast-glob pattern or array of patterns - * (https://github.com/mrmlnc/fast-glob#basic-syntax) that are relative from - * vite project root. This will overwrite default entries inference. - */ - entries?: string | string[] +export interface DepOptimizationConfig { /** * Force optimize listed dependencies (must be resolvable import paths, * cannot be globs). @@ -127,7 +113,7 @@ export interface DepOptimizationOptions { * List of file extensions that can be optimized. A corresponding esbuild * plugin must exist to handle the specific extension. * - * By default, Vite can optimize `.mjs`, `.js`, and `.ts` files. This option + * By default, Vite can optimize `.mjs`, `.js`, `.ts`, and `.mts` files. This option * allows specifying additional extensions. * * @experimental @@ -136,11 +122,25 @@ export interface DepOptimizationOptions { /** * Disables dependencies optimizations, true disables the optimizer during * build and dev. Pass 'build' or 'dev' to only disable the optimizer in - * one of the modes. Deps optimization is enabled by default in both - * @default false + * one of the modes. Deps optimization is enabled by default in dev only. + * @default 'build' * @experimental */ disabled?: boolean | 'build' | 'dev' +} + +export type DepOptimizationOptions = DepOptimizationConfig & { + /** + * By default, Vite will crawl your `index.html` to detect dependencies that + * need to be pre-bundled. If `build.rollupOptions.input` is specified, Vite + * will crawl those entry points instead. + * + * If neither of these fit your needs, you can specify custom entries using + * this option - the value should be a fast-glob pattern or array of patterns + * (https://github.com/mrmlnc/fast-glob#basic-syntax) that are relative from + * vite project root. This will overwrite default entries inference. + */ + entries?: string | string[] /** * Force dep pre-optimization regardless of whether deps have changed. * @experimental @@ -214,7 +214,8 @@ export interface DepOptimizationMetadata { } /** - * Used by Vite CLI when running `vite optimize` + * Scan and optimize dependencies within a project. + * Used by Vite CLI when running `vite optimize`. */ export async function optimizeDeps( config: ResolvedConfig, @@ -223,22 +224,26 @@ export async function optimizeDeps( ): Promise { const log = asCommand ? config.logger.info : debug + const ssr = config.command === 'build' && !!config.build.ssr + const cachedMetadata = loadCachedDepOptimizationMetadata( config, + ssr, force, asCommand ) if (cachedMetadata) { return cachedMetadata } + const deps = await discoverProjectDependencies(config) const depsString = depsLogString(Object.keys(deps)) log(colors.green(`Optimizing dependencies:\n ${depsString}`)) - await addManuallyIncludedOptimizeDeps(deps, config) + await addManuallyIncludedOptimizeDeps(deps, config, ssr) - const depsInfo = toDiscoveredDependencies(config, deps, !!config.build.ssr) + const depsInfo = toDiscoveredDependencies(config, deps, ssr) const result = await runOptimizeDeps(config, depsInfo) @@ -250,11 +255,12 @@ export async function optimizeDeps( export async function optimizeServerSsrDeps( config: ResolvedConfig ): Promise { + const ssr = true const cachedMetadata = loadCachedDepOptimizationMetadata( config, + ssr, config.optimizeDeps.force, - false, - true // ssr + false ) if (cachedMetadata) { return cachedMetadata @@ -263,6 +269,8 @@ export async function optimizeServerSsrDeps( let alsoInclude: string[] | undefined let noExternalFilter: ((id: unknown) => boolean) | undefined + const { exclude } = getDepOptimizationConfig(config, ssr) + const noExternal = config.ssr?.noExternal if (noExternal) { alsoInclude = arraify(noExternal).filter( @@ -270,8 +278,8 @@ export async function optimizeServerSsrDeps( ) as string[] noExternalFilter = noExternal === true - ? (dep: unknown) => false - : createFilter(noExternal, config.optimizeDeps?.exclude, { + ? (dep: unknown) => true + : createFilter(undefined, exclude, { resolve: false }) } @@ -281,6 +289,7 @@ export async function optimizeServerSsrDeps( await addManuallyIncludedOptimizeDeps( deps, config, + ssr, alsoInclude, noExternalFilter ) @@ -296,9 +305,10 @@ export async function optimizeServerSsrDeps( export function initDepsOptimizerMetadata( config: ResolvedConfig, + ssr: boolean, timestamp?: string ): DepOptimizationMetadata { - const hash = getDepHash(config) + const hash = getDepHash(config, ssr) return { hash, browserHash: getOptimizedBrowserHash(hash, {}, timestamp), @@ -325,9 +335,9 @@ export function addOptimizedDepInfo( */ export function loadCachedDepOptimizationMetadata( config: ResolvedConfig, + ssr: boolean, force = config.optimizeDeps.force, - asCommand = false, - ssr = !!config.build.ssr + asCommand = false ): DepOptimizationMetadata | undefined { const log = asCommand ? config.logger.info : debug @@ -349,7 +359,7 @@ export function loadCachedDepOptimizationMetadata( ) } catch (e) {} // hash is consistent, no need to re-bundle - if (cachedMetadata && cachedMetadata.hash === getDepHash(config)) { + if (cachedMetadata && cachedMetadata.hash === getDepHash(config, ssr)) { log('Hash is consistent. Skipping. Use --force to override.') // Nothing to commit or cancel as we are using the cache, we only // need to resolve the processing promise so requests can move on @@ -396,7 +406,7 @@ export function toDiscoveredDependencies( timestamp?: string ): Record { const browserHash = getOptimizedBrowserHash( - getDepHash(config), + getDepHash(config, ssr), deps, timestamp ) @@ -408,7 +418,7 @@ export function toDiscoveredDependencies( file: getOptimizedDepPath(id, config, ssr), src, browserHash: browserHash, - exportsData: extractExportsData(src, config) + exportsData: extractExportsData(src, config, ssr) } } return discovered @@ -436,7 +446,8 @@ export function depsLogString(qualifiedIds: string[]): string { export async function runOptimizeDeps( resolvedConfig: ResolvedConfig, depsInfo: Record, - ssr: boolean = !!resolvedConfig.build.ssr + ssr: boolean = resolvedConfig.command === 'build' && + !!resolvedConfig.build.ssr ): Promise { const isBuild = resolvedConfig.command === 'build' const config: ResolvedConfig = { @@ -463,7 +474,7 @@ export async function runOptimizeDeps( JSON.stringify({ type: 'module' }) ) - const metadata = initDepsOptimizerMetadata(config) + const metadata = initDepsOptimizerMetadata(config, ssr) metadata.browserHash = getOptimizedBrowserHash( metadata.hash, @@ -504,13 +515,15 @@ export async function runOptimizeDeps( const idToExports: Record = {} const flatIdToExports: Record = {} - const { plugins = [], ...esbuildOptions } = - config.optimizeDeps?.esbuildOptions ?? {} + const optimizeDeps = getDepOptimizationConfig(config, ssr) + + const { plugins: pluginsFromConfig = [], ...esbuildOptions } = + optimizeDeps?.esbuildOptions ?? {} for (const id in depsInfo) { const src = depsInfo[id].src! const exportsData = await (depsInfo[id].exportsData ?? - extractExportsData(src, config)) + extractExportsData(src, config, ssr)) if (exportsData.jsxLoader) { // Ensure that optimization won't fail by defaulting '.js' to the JSX parser. // This is useful for packages such as Gatsby. @@ -538,6 +551,36 @@ export async function runOptimizeDeps( const platform = ssr && config.ssr?.target !== 'webworker' ? 'node' : 'browser' + const external = [...(optimizeDeps?.exclude ?? [])] + + if (isBuild) { + let rollupOptionsExternal = config?.build?.rollupOptions?.external + if (rollupOptionsExternal) { + if (typeof rollupOptionsExternal === 'string') { + rollupOptionsExternal = [rollupOptionsExternal] + } + // TODO: decide whether to support RegExp and function options + // They're not supported yet because `optimizeDeps.exclude` currently only accepts strings + if ( + !Array.isArray(rollupOptionsExternal) || + rollupOptionsExternal.some((ext) => typeof ext !== 'string') + ) { + throw new Error( + `[vite] 'build.rollupOptions.external' can only be an array of strings or a string when using esbuild optimization at build time.` + ) + } + external.push(...(rollupOptionsExternal as string[])) + } + } + + const plugins = [...pluginsFromConfig] + if (external.length) { + plugins.push(esbuildCjsExternalPlugin(external)) + } + plugins.push( + esbuildDepPlugin(flatIdDeps, flatIdToExports, external, config, ssr) + ) + const start = performance.now() const result = await build({ @@ -558,17 +601,14 @@ export async function runOptimizeDeps( } : undefined, target: isBuild ? config.build.target || undefined : ESBUILD_MODULES_TARGET, - external: config.optimizeDeps?.exclude, + external, logLevel: 'error', splitting: true, sourcemap: true, outdir: processingCacheDir, ignoreAnnotations: !isBuild, metafile: true, - plugins: [ - ...plugins, - esbuildDepPlugin(flatIdDeps, flatIdToExports, config, ssr) - ], + plugins, ...esbuildOptions, supported: { 'dynamic-import': true, @@ -599,7 +639,7 @@ export async function runOptimizeDeps( browserHash: metadata.browserHash, // After bundling we have more information and can warn the user about legacy packages // that require manual configuration - needsInterop: needsInterop(config, id, idToExports[id], output) + needsInterop: needsInterop(config, ssr, id, idToExports[id], output) }) } @@ -634,40 +674,55 @@ export async function runOptimizeDeps( } export async function findKnownImports( - config: ResolvedConfig + config: ResolvedConfig, + ssr: boolean ): Promise { const deps = (await scanImports(config)).deps - await addManuallyIncludedOptimizeDeps(deps, config) + await addManuallyIncludedOptimizeDeps(deps, config, ssr) return Object.keys(deps) } export async function addManuallyIncludedOptimizeDeps( deps: Record, config: ResolvedConfig, + ssr: boolean, extra: string[] = [], filter?: (id: string) => boolean ): Promise { - const optimizeDepsInclude = config.optimizeDeps?.include ?? [] + const { logger } = config + const optimizeDeps = getDepOptimizationConfig(config, ssr) + const optimizeDepsInclude = optimizeDeps?.include ?? [] if (optimizeDepsInclude.length || extra.length) { - const resolve = config.createResolver({ asSrc: false, scan: true }) + const unableToOptimize = (id: string, msg: string) => { + if (optimizeDepsInclude.includes(id)) { + logger.warn( + `${msg}: ${colors.cyan(id)}, present in '${ + ssr ? 'ssr.' : '' + }optimizeDeps.include'` + ) + } + } + const resolve = config.createResolver({ + asSrc: false, + scan: true, + ssrOptimizeCheck: ssr + }) for (const id of [...optimizeDepsInclude, ...extra]) { // normalize 'foo >bar` as 'foo > bar' to prevent same id being added // and for pretty printing const normalizedId = normalizeId(id) if (!deps[normalizedId] && filter?.(normalizedId) !== false) { - const entry = await resolve(id) + const entry = await resolve(id, undefined, undefined, ssr) if (entry) { - if (isOptimizable(entry, config.optimizeDeps)) { - deps[normalizedId] = entry - } else if (optimizeDepsInclude.includes(id)) { - config.logger.warn( - `Cannot optimize included dependency: ${colors.cyan(id)}` - ) + if (isOptimizable(entry, optimizeDeps)) { + if (!entry.endsWith('?__vite_skip_optimization')) { + deps[normalizedId] = entry + } + } else { + unableToOptimize(entry, 'Cannot optimize dependency') } } else { - throw new Error( - `Failed to resolve force included dependency: ${colors.cyan(id)}` - ) + unableToOptimize(id, 'Failed to resolve dependency') } } } @@ -694,7 +749,7 @@ export function depsFromOptimizedDepInfo( export function getOptimizedDepPath( id: string, config: ResolvedConfig, - ssr: boolean = !!config.build.ssr + ssr: boolean ): string { return normalizePath( path.resolve(getDepsCacheDir(config, ssr), flattenId(id) + '.js') @@ -865,12 +920,15 @@ function esbuildOutputFromId( export async function extractExportsData( filePath: string, - config: ResolvedConfig + config: ResolvedConfig, + ssr: boolean ): Promise { await init - const esbuildOptions = config.optimizeDeps?.esbuildOptions ?? {} - if (config.optimizeDeps.extensions?.some((ext) => filePath.endsWith(ext))) { + const optimizeDeps = getDepOptimizationConfig(config, ssr) + + const esbuildOptions = optimizeDeps?.esbuildOptions ?? {} + if (optimizeDeps.extensions?.some((ext) => filePath.endsWith(ext))) { // For custom supported extensions, build the entry file to transform it into JS, // and then parse with es-module-lexer. Note that the `bundle` option is not `true`, // so only the entry file is being transformed. @@ -933,12 +991,13 @@ const KNOWN_INTEROP_IDS = new Set(['moment']) function needsInterop( config: ResolvedConfig, + ssr: boolean, id: string, exportsData: ExportsData, output?: { exports: string[] } ): boolean { if ( - config.optimizeDeps?.needsInterop?.includes(id) || + getDepOptimizationConfig(config, ssr)?.needsInterop?.includes(id) || KNOWN_INTEROP_IDS.has(id) ) { return true @@ -950,7 +1009,7 @@ function needsInterop( } if (output) { - // if a peer dependency used require() on a ESM dependency, esbuild turns the + // if a peer dependency used require() on an ESM dependency, esbuild turns the // ESM dependency's entry chunk into a single default export... detect // such cases by checking exports mismatch, and force interop. const generatedExports: string[] = output.exports @@ -972,10 +1031,11 @@ function isSingleDefaultExport(exports: readonly string[]) { const lockfileFormats = ['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml'] -export function getDepHash(config: ResolvedConfig): string { +export function getDepHash(config: ResolvedConfig, ssr: boolean): string { let content = lookupFile(config.root, lockfileFormats) || '' // also take config into account // only a subset of config options that can affect dep optimization + const optimizeDeps = getDepOptimizationConfig(config, ssr) content += JSON.stringify( { mode: process.env.NODE_ENV || config.mode, @@ -985,13 +1045,11 @@ export function getDepHash(config: ResolvedConfig): string { assetsInclude: config.assetsInclude, plugins: config.plugins.map((p) => p.name), optimizeDeps: { - include: config.optimizeDeps?.include, - exclude: config.optimizeDeps?.exclude, + include: optimizeDeps?.include, + exclude: optimizeDeps?.exclude, esbuildOptions: { - ...config.optimizeDeps?.esbuildOptions, - plugins: config.optimizeDeps?.esbuildOptions?.plugins?.map( - (p) => p.name - ) + ...optimizeDeps?.esbuildOptions, + plugins: optimizeDeps?.esbuildOptions?.plugins?.map((p) => p.name) } } }, @@ -1044,13 +1102,15 @@ function findOptimizedDepInfoInRecord( export async function optimizedDepNeedsInterop( metadata: DepOptimizationMetadata, file: string, - config: ResolvedConfig + config: ResolvedConfig, + ssr: boolean ): Promise { const depInfo = optimizedDepInfoFromFile(metadata, file) if (depInfo?.src && depInfo.needsInterop === undefined) { - depInfo.exportsData ??= extractExportsData(depInfo.src, config) + depInfo.exportsData ??= extractExportsData(depInfo.src, config, ssr) depInfo.needsInterop = needsInterop( config, + ssr, depInfo.id, await depInfo.exportsData ) diff --git a/packages/vite/src/node/optimizer/optimizer.ts b/packages/vite/src/node/optimizer/optimizer.ts index eb438b9d9250a7..9bf03aa88005b0 100644 --- a/packages/vite/src/node/optimizer/optimizer.ts +++ b/packages/vite/src/node/optimizer/optimizer.ts @@ -1,6 +1,7 @@ import colors from 'picocolors' import _debug from 'debug' import { getHash } from '../utils' +import { getDepOptimizationConfig } from '..' import type { ResolvedConfig, ViteDevServer } from '..' import { addManuallyIncludedOptimizeDeps, @@ -40,10 +41,10 @@ const devSsrDepsOptimizerMap = new WeakMap() export function getDepsOptimizer( config: ResolvedConfig, - type: { ssr?: boolean } + ssr?: boolean ): DepsOptimizer | undefined { // Workers compilation shares the DepsOptimizer from the main build - const isDevSsr = type.ssr && config.command !== 'build' + const isDevSsr = ssr && config.command !== 'build' return (isDevSsr ? devSsrDepsOptimizerMap : depsOptimizerMap).get( config.mainConfig || config ) @@ -53,7 +54,9 @@ export async function initDepsOptimizer( config: ResolvedConfig, server?: ViteDevServer ): Promise { - if (!getDepsOptimizer(config, { ssr: false })) { + // Non Dev SSR Optimizer + const ssr = config.command === 'build' && !!config.build.ssr + if (!getDepsOptimizer(config, ssr)) { await createDepsOptimizer(config, server) } } @@ -63,7 +66,8 @@ export async function initDevSsrDepsOptimizer( config: ResolvedConfig, server: ViteDevServer ): Promise { - if (getDepsOptimizer(config, { ssr: true })) { + if (getDepsOptimizer(config, true)) { + // ssr return } if (creatingDevSsrOptimizer) { @@ -73,10 +77,11 @@ export async function initDevSsrDepsOptimizer( // Important: scanning needs to be done before starting the SSR dev optimizer // If ssrLoadModule is called before server.listen(), the main deps optimizer // will not be yet created - if (!getDepsOptimizer(config, { ssr: false })) { + const ssr = false + if (!getDepsOptimizer(config, ssr)) { await initDepsOptimizer(config, server) } - await getDepsOptimizer(config, { ssr: false })!.scanProcessing + await getDepsOptimizer(config, ssr)!.scanProcessing await createDevSsrDepsOptimizer(config) creatingDevSsrOptimizer = undefined @@ -90,15 +95,16 @@ async function createDepsOptimizer( ): Promise { const { logger } = config const isBuild = config.command === 'build' + const ssr = isBuild && !!config.build.ssr // safe as Dev SSR don't use this optimizer const sessionTimestamp = Date.now().toString() - const cachedMetadata = loadCachedDepOptimizationMetadata(config) + const cachedMetadata = loadCachedDepOptimizationMetadata(config, ssr) let handle: NodeJS.Timeout | undefined let metadata = - cachedMetadata || initDepsOptimizerMetadata(config, sessionTimestamp) + cachedMetadata || initDepsOptimizerMetadata(config, ssr, sessionTimestamp) const depsOptimizer: DepsOptimizer = { metadata, @@ -112,7 +118,7 @@ async function createDepsOptimizer( delayDepsOptimizerUntil, resetRegisteredIds, ensureFirstRun, - options: config.optimizeDeps + options: getDepOptimizationConfig(config, ssr) } depsOptimizerMap.set(config, depsOptimizer) @@ -160,12 +166,12 @@ async function createDepsOptimizer( // Initialize discovered deps with manually added optimizeDeps.include info const deps: Record = {} - await addManuallyIncludedOptimizeDeps(deps, config) + await addManuallyIncludedOptimizeDeps(deps, config, ssr) const discovered = await toDiscoveredDependencies( config, deps, - !!config.build.ssr, + ssr, sessionTimestamp ) @@ -177,55 +183,52 @@ async function createDepsOptimizer( newDepsDiscovered = true } - // TODO: We need the scan during build time, until preAliasPlugin - // is refactored to work without the scanned deps. We could skip - // this for build later. + if (!isBuild) { + // Important, the scanner is dev only + const scanPhaseProcessing = newDepOptimizationProcessing() + depsOptimizer.scanProcessing = scanPhaseProcessing.promise + // Ensure server listen is called before the scanner + setTimeout(async () => { + try { + debug(colors.green(`scanning for dependencies...`)) - runScanner() - } - - async function runScanner() { - const scanPhaseProcessing = newDepOptimizationProcessing() - depsOptimizer.scanProcessing = scanPhaseProcessing.promise + const deps = await discoverProjectDependencies(config) - try { - debug(colors.green(`scanning for dependencies...`)) + debug( + colors.green( + Object.keys(deps).length > 0 + ? `dependencies found by scanner: ${depsLogString( + Object.keys(deps) + )}` + : `no dependencies found by scanner` + ) + ) - const deps = await discoverProjectDependencies(config) + // Add these dependencies to the discovered list, as these are currently + // used by the preAliasPlugin to support aliased and optimized deps. + // This is also used by the CJS externalization heuristics in legacy mode + for (const id of Object.keys(deps)) { + if (!metadata.discovered[id]) { + addMissingDep(id, deps[id]) + } + } - debug( - colors.green( - Object.keys(deps).length > 0 - ? `dependencies found by scanner: ${depsLogString( - Object.keys(deps) - )}` - : `no dependencies found by scanner` - ) - ) + if (!isBuild) { + const knownDeps = prepareKnownDeps() - // Add these dependencies to the discovered list, as these are currently - // used by the preAliasPlugin to support aliased and optimized deps. - // This is also used by the CJS externalization heuristics in legacy mode - for (const id of Object.keys(deps)) { - if (!metadata.discovered[id]) { - addMissingDep(id, deps[id]) + // For dev, we run the scanner and the first optimization + // run on the background, but we wait until crawling has ended + // to decide if we send this result to the browser or we need to + // do another optimize step + postScanOptimizationResult = runOptimizeDeps(config, knownDeps) + } + } catch (e) { + logger.error(e.message) + } finally { + scanPhaseProcessing.resolve() + depsOptimizer.scanProcessing = undefined } - } - - if (!isBuild) { - const knownDeps = prepareKnownDeps() - - // For dev, we run the scanner and the first optimization - // run on the background, but we wait until crawling has ended - // to decide if we send this result to the browser or we need to - // do another optimize step - postScanOptimizationResult = runOptimizeDeps(config, knownDeps) - } - } catch (e) { - logger.error(e.message) - } finally { - scanPhaseProcessing.resolve() - depsOptimizer.scanProcessing = undefined + }, 0) } } @@ -481,14 +484,8 @@ async function createDepsOptimizer( function registerMissingImport( id: string, - resolved: string, - ssr?: boolean + resolved: string ): OptimizedDepInfo { - if (!isBuild && ssr) { - config.logger.error( - 'Vite internal error: ssr dep registered as a browser dep' - ) - } const optimized = metadata.optimized[id] if (optimized) { return optimized @@ -504,7 +501,7 @@ async function createDepsOptimizer( return missing } - missing = addMissingDep(id, resolved, ssr) + missing = addMissingDep(id, resolved) // Until the first optimize run is called, avoid triggering processing // We'll wait until the user codebase is eagerly processed by Vite so @@ -522,7 +519,7 @@ async function createDepsOptimizer( return missing } - function addMissingDep(id: string, resolved: string, ssr?: boolean) { + function addMissingDep(id: string, resolved: string) { newDepsDiscovered = true return addOptimizedDepInfo(metadata, 'discovered', { @@ -541,7 +538,7 @@ async function createDepsOptimizer( // loading of this pre-bundled dep needs to await for its processing // promise to be resolved processing: depOptimizationProcessing.promise, - exportsData: extractExportsData(resolved, config) + exportsData: extractExportsData(resolved, config, ssr) }) } @@ -748,7 +745,7 @@ async function createDevSsrDepsOptimizer( delayDepsOptimizerUntil: (id: string, done: () => Promise) => {}, resetRegisteredIds: () => {}, ensureFirstRun: () => {}, - options: config.optimizeDeps + options: config.ssr.optimizeDeps } devSsrDepsOptimizerMap.set(config, depsOptimizer) } diff --git a/packages/vite/src/node/optimizer/scan.ts b/packages/vite/src/node/optimizer/scan.ts index 5608472b4efe91..2b87ccdcbcad54 100644 --- a/packages/vite/src/node/optimizer/scan.ts +++ b/packages/vite/src/node/optimizer/scan.ts @@ -25,6 +25,8 @@ import type { PluginContainer } from '../server/pluginContainer' import { createPluginContainer } from '../server/pluginContainer' import { transformGlobImport } from '../plugins/importMetaGlob' +type ResolveIdOptions = Parameters[2] + const debug = createDebugger('vite:deps') const htmlTypesRE = /\.(html|vue|svelte|astro)$/ @@ -44,6 +46,8 @@ export async function scanImports(config: ResolvedConfig): Promise<{ deps: Record missing: Record }> { + // Only used to scan non-ssr code + const start = performance.now() let entries: string[] = [] @@ -161,7 +165,11 @@ function esbuildScanPlugin( ): Plugin { const seen = new Map() - const resolve = async (id: string, importer?: string) => { + const resolve = async ( + id: string, + importer?: string, + options?: ResolveIdOptions + ) => { const key = id + (importer && path.dirname(importer)) if (seen.has(key)) { return seen.get(key) @@ -170,6 +178,7 @@ function esbuildScanPlugin( id, importer && normalizePath(importer), { + ...options, scan: true } ) @@ -314,12 +323,18 @@ function esbuildScanPlugin( config.root, resolve ) - )?.s.toString() || transpiledContents + )?.s.toString() || transpiledContents, + pluginData: { + htmlType: { loader } + } } } else { scripts[key] = { loader, - contents + contents, + pluginData: { + htmlType: { loader } + } } } @@ -364,14 +379,18 @@ function esbuildScanPlugin( // avoid matching windows volume filter: /^[\w@][^:]/ }, - async ({ path: id, importer }) => { + async ({ path: id, importer, pluginData }) => { if (moduleListContains(exclude, id)) { return externalUnlessEntry({ path: id }) } if (depImports[id]) { return externalUnlessEntry({ path: id }) } - const resolved = await resolve(id, importer) + const resolved = await resolve(id, importer, { + custom: { + depScan: { loader: pluginData?.htmlType?.loader } + } + }) if (resolved) { if (shouldExternalizeDep(resolved, id)) { return externalUnlessEntry({ path: id }) @@ -404,10 +423,10 @@ function esbuildScanPlugin( // they are done after the bare import resolve because a package name // may end with these extensions - // css & json + // css & json & wasm build.onResolve( { - filter: /\.(css|less|sass|scss|styl|stylus|pcss|postcss|json)$/ + filter: /\.(css|less|sass|scss|styl|stylus|pcss|postcss|json|wasm)$/ }, externalUnlessEntry ) @@ -432,9 +451,13 @@ function esbuildScanPlugin( { filter: /.*/ }, - async ({ path: id, importer }) => { + async ({ path: id, importer, pluginData }) => { // use vite resolver to support urls and omitted extensions - const resolved = await resolve(id, importer) + const resolved = await resolve(id, importer, { + custom: { + depScan: { loader: pluginData?.htmlType?.loader } + } + }) if (resolved) { if (shouldExternalizeDep(resolved, id) || !isScannable(resolved)) { return externalUnlessEntry({ path: id }) diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts index 0403009d4b69c4..648b34f1d6d6f1 100644 --- a/packages/vite/src/node/plugins/asset.ts +++ b/packages/vite/src/node/plugins/asset.ts @@ -94,14 +94,6 @@ export function assetPlugin(config: ResolvedConfig): Plugin { let match: RegExpExecArray | null let s: MagicString | undefined - const toRelative = (filename: string, importer: string) => { - return { - runtime: `new URL(${JSON.stringify( - path.posix.relative(path.dirname(importer), filename) - )},import.meta.url).href` - } - } - // Urls added with JS using e.g. // imgElement.src = "__VITE_ASSET__5aa0ddc0__" are using quotes @@ -123,8 +115,7 @@ export function assetPlugin(config: ResolvedConfig): Plugin { 'asset', chunk.fileName, 'js', - config, - toRelative + config ) const replacementString = typeof replacement === 'string' @@ -147,8 +138,7 @@ export function assetPlugin(config: ResolvedConfig): Plugin { 'public', chunk.fileName, 'js', - config, - toRelative + config ) const replacementString = typeof replacement === 'string' diff --git a/packages/vite/src/node/plugins/clientInjections.ts b/packages/vite/src/node/plugins/clientInjections.ts index 4eb1654d09d7a8..c4472cb8f14b62 100644 --- a/packages/vite/src/node/plugins/clientInjections.ts +++ b/packages/vite/src/node/plugins/clientInjections.ts @@ -17,6 +17,14 @@ export function clientInjectionsPlugin(config: ResolvedConfig): Plugin { name: 'vite:client-inject', async transform(code, id, options) { if (id === normalizedClientEntry || id === normalizedEnvEntry) { + const resolvedServerHostname = ( + await resolveHostname(config.server.host) + ).name + const resolvedServerPort = config.server.port! + const devBase = config.base + + const serverHost = `${resolvedServerHostname}:${resolvedServerPort}${devBase}` + let hmrConfig = config.server.hmr hmrConfig = isObject(hmrConfig) ? hmrConfig : undefined const host = hmrConfig?.host || null @@ -31,10 +39,8 @@ export function clientInjectionsPlugin(config: ResolvedConfig): Plugin { port ||= 24678 } - const devBase = config.base - let directTarget = - hmrConfig?.host || (await resolveHostname(config.server.host)).name - directTarget += `:${hmrConfig?.port || config.server.port!}` + let directTarget = hmrConfig?.host || resolvedServerHostname + directTarget += `:${hmrConfig?.port || resolvedServerPort}` directTarget += devBase let hmrBase = devBase @@ -46,6 +52,7 @@ export function clientInjectionsPlugin(config: ResolvedConfig): Plugin { .replace(`__MODE__`, JSON.stringify(config.mode)) .replace(`__BASE__`, JSON.stringify(devBase)) .replace(`__DEFINES__`, serializeDefine(config.define || {})) + .replace(`__SERVER_HOST__`, JSON.stringify(serverHost)) .replace(`__HMR_PROTOCOL__`, JSON.stringify(protocol)) .replace(`__HMR_HOSTNAME__`, JSON.stringify(host)) .replace(`__HMR_PORT__`, JSON.stringify(port)) diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index ef0f7404763f73..b4429961ef479a 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -426,7 +426,11 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { code = `export default ${JSON.stringify(content)}` } } else { - code = `export default ''` + // if moduleCode exists return it **even if** it does not have `?used` + // this will disable tree-shake to work with `import './foo.module.css'` but this usually does not happen + // this is a limitation of the current approach by `?used` to make tree-shake work + // See #8936 for more details + code = modulesCode || `export default ''` } return { @@ -1245,18 +1249,25 @@ async function minifyCSS(css: string, config: ResolvedConfig) { function resolveEsbuildMinifyOptions( options: ESBuildOptions ): TransformOptions { + const base: TransformOptions = { + logLevel: options.logLevel, + logLimit: options.logLimit, + logOverride: options.logOverride + } + if ( options.minifyIdentifiers != null || options.minifySyntax != null || options.minifyWhitespace != null ) { return { + ...base, minifyIdentifiers: options.minifyIdentifiers ?? true, minifySyntax: options.minifySyntax ?? true, minifyWhitespace: options.minifyWhitespace ?? true } } else { - return { minify: true } + return { ...base, minify: true } } } diff --git a/packages/vite/src/node/plugins/esbuild.ts b/packages/vite/src/node/plugins/esbuild.ts index 42e5bbac76316a..9a95c1be816580 100644 --- a/packages/vite/src/node/plugins/esbuild.ts +++ b/packages/vite/src/node/plugins/esbuild.ts @@ -78,6 +78,8 @@ export async function transformWithEsbuild( if (ext === 'cjs' || ext === 'mjs') { loader = 'js' + } else if (ext === 'cts' || ext === 'mts') { + loader = 'ts' } else { loader = ext as Loader } @@ -170,7 +172,7 @@ export async function transformWithEsbuild( export function esbuildPlugin(options: ESBuildOptions = {}): Plugin { const filter = createFilter( - options.include || /\.(tsx?|jsx)$/, + options.include || /\.(m?ts|[jt]sx)$/, options.exclude || /\.js$/ ) @@ -182,7 +184,11 @@ export function esbuildPlugin(options: ESBuildOptions = {}): Plugin { minifyIdentifiers: false, minifySyntax: false, minifyWhitespace: false, - treeShaking: false + treeShaking: false, + // keepNames is not needed when minify is disabled. + // Also transforming multiple times with keepNames enabled breaks + // tree-shaking. (#9164) + keepNames: false } return { @@ -298,10 +304,19 @@ export function resolveEsbuildTranspileOptions( // pure annotations and break tree-shaking // https://github.com/vuejs/core/issues/2860#issuecomment-926882793 const isEsLibBuild = config.build.lib && format === 'es' + const esbuildOptions = config.esbuild || {} const options: TransformOptions = { - ...config.esbuild, + ...esbuildOptions, target: target || undefined, - format: rollupToEsbuildFormatMap[format] + format: rollupToEsbuildFormatMap[format], + // the final build should always support dynamic import and import.meta. + // if they need to be polyfilled, plugin-legacy should be used. + // plugin-legacy detects these two features when checking for modern code. + supported: { + 'dynamic-import': true, + 'import-meta': true, + ...esbuildOptions.supported + } } // If no minify, disable all minify options @@ -437,11 +452,14 @@ function reloadOnTsconfigChange(changedFile: string) { // reset tsconfck so that recompile works with up2date configs initTSConfck(server.config).finally(() => { - // force full reload - server.ws.send({ - type: 'full-reload', - path: '*' - }) + // server may not be available if vite config is updated at the same time + if (server) { + // force full reload + server.ws.send({ + type: 'full-reload', + path: '*' + }) + } }) } } diff --git a/packages/vite/src/node/plugins/importAnalysis.ts b/packages/vite/src/node/plugins/importAnalysis.ts index 5af046908ff0fa..f04cb8625f864b 100644 --- a/packages/vite/src/node/plugins/importAnalysis.ts +++ b/packages/vite/src/node/plugins/importAnalysis.ts @@ -9,6 +9,7 @@ import { parse as parseJS } from 'acorn' import type { Node } from 'estree' import { findStaticImports, parseStaticImport } from 'mlly' import { makeLegalIdentifier } from '@rollup/pluginutils' +import { getDepOptimizationConfig } from '..' import type { ViteDevServer } from '..' import { CLIENT_DIR, @@ -214,7 +215,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { ) } - const depsOptimizer = getDepsOptimizer(config, { ssr }) + const depsOptimizer = getDepsOptimizer(config, ssr) const { moduleGraph } = server // since we are already in the transform phase of the importer, it must @@ -267,7 +268,9 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { } let importerFile = importer - if (moduleListContains(config.optimizeDeps?.exclude, url)) { + + const optimizeDeps = getDepOptimizationConfig(config, ssr) + if (moduleListContains(optimizeDeps?.exclude, url)) { if (depsOptimizer) { await depsOptimizer.scanProcessing @@ -291,7 +294,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { if (ssr) { return [url, url] } - this.error( + return this.error( `Failed to resolve import "${url}" from "${path.relative( process.cwd(), importerFile @@ -384,10 +387,12 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { s: start, e: end, ss: expStart, + se: expEnd, d: dynamicIndex, // #2083 User may use escape path, // so use imports[index].n to get the unescaped string - n: specifier + n: specifier, + a: assertIndex } = imports[index] const rawUrl = source.slice(start, end) @@ -424,6 +429,11 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { const isDynamicImport = dynamicIndex > -1 + // strip import assertions as we can process them ourselves + if (!isDynamicImport && assertIndex > -1) { + str().remove(end + 1, expEnd) + } + // static import or valid string in dynamic import // If resolvable, let's resolve it if (specifier) { @@ -485,7 +495,8 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { const needsInterop = await optimizedDepNeedsInterop( depsOptimizer.metadata, file, - config + config, + ssr ) if (needsInterop === undefined) { @@ -813,6 +824,7 @@ export function transformCjsImport( spec.exported.type === 'Identifier' ) { // for ExportSpecifier, local name is same as imported name + // prefix the variable name to avoid clashing with other local variables const importedName = spec.local.name // we want to specify exported name as variable and re-export it const exportedName = spec.exported.name @@ -822,8 +834,11 @@ export function transformCjsImport( ) importNames.push({ importedName, localName: defaultExports }) } else { - importNames.push({ importedName, localName: exportedName }) - exportNames.push(exportedName) + const localName = makeLegalIdentifier( + `__vite__cjsExport_${exportedName}` + ) + importNames.push({ importedName, localName }) + exportNames.push(`${localName} as ${exportedName}`) } } } diff --git a/packages/vite/src/node/plugins/importAnalysisBuild.ts b/packages/vite/src/node/plugins/importAnalysisBuild.ts index b83ae46451c8f7..f392cfda538584 100644 --- a/packages/vite/src/node/plugins/importAnalysisBuild.ts +++ b/packages/vite/src/node/plugins/importAnalysisBuild.ts @@ -14,6 +14,7 @@ import { moduleListContains } from '../utils' import type { Plugin } from '../plugin' +import { getDepOptimizationConfig } from '../config' import type { ResolvedConfig } from '../config' import { genSourceMapUrl } from '../server/sourcemap' import { getDepsOptimizer, optimizedDepNeedsInterop } from '../optimizer' @@ -155,7 +156,7 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin { } const { root } = config - const depsOptimizer = getDepsOptimizer(config, { ssr }) + const depsOptimizer = getDepsOptimizer(config, ssr) const normalizeUrl = async ( url: string, @@ -163,7 +164,8 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin { ): Promise<[string, string]> => { let importerFile = importer - if (moduleListContains(config.optimizeDeps?.exclude, url)) { + const optimizeDeps = getDepOptimizationConfig(config, ssr) + if (moduleListContains(optimizeDeps?.exclude, url)) { if (depsOptimizer) { await depsOptimizer.scanProcessing @@ -187,7 +189,7 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin { if (ssr) { return [url, url] } - this.error( + return this.error( `Failed to resolve import "${url}" from "${path.relative( process.cwd(), importerFile @@ -223,11 +225,17 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin { ss: expStart, se: expEnd, n: specifier, - d: dynamicIndex + d: dynamicIndex, + a: assertIndex } = imports[index] const isDynamicImport = dynamicIndex > -1 + // strip import assertions as we can process them ourselves + if (!isDynamicImport && assertIndex > -1) { + str().remove(end + 1, expEnd) + } + if (isDynamicImport && insertPreload) { needPreloadHelper = true str().prependLeft(expStart, `${preloadMethod}(() => `) @@ -260,7 +268,8 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin { const needsInterop = await optimizedDepNeedsInterop( depsOptimizer.metadata, file, - config + config, + ssr ) let rewriteDone = false diff --git a/packages/vite/src/node/plugins/importMetaGlob.ts b/packages/vite/src/node/plugins/importMetaGlob.ts index 7f3695178fdce9..6943bf24c56702 100644 --- a/packages/vite/src/node/plugins/importMetaGlob.ts +++ b/packages/vite/src/node/plugins/importMetaGlob.ts @@ -5,6 +5,7 @@ import type { ArrayExpression, CallExpression, Literal, + MemberExpression, Node, SequenceExpression } from 'estree' @@ -118,7 +119,7 @@ export async function parseImportGlob( return e } - let ast: CallExpression | SequenceExpression + let ast: CallExpression | SequenceExpression | MemberExpression let lastTokenPos: number | undefined try { @@ -157,6 +158,10 @@ export async function parseImportGlob( if (ast.type === 'SequenceExpression') ast = ast.expressions[0] as CallExpression + // immediate property access, call expression is nested + // import.meta.glob(...)['prop'] + if (ast.type === 'MemberExpression') ast = ast.object as CallExpression + if (ast.type !== 'CallExpression') throw err(`Expect CallExpression, got ${ast.type}`) diff --git a/packages/vite/src/node/plugins/index.ts b/packages/vite/src/node/plugins/index.ts index 0bab69f50eeb98..a2fbebcc75b66e 100644 --- a/packages/vite/src/node/plugins/index.ts +++ b/packages/vite/src/node/plugins/index.ts @@ -33,7 +33,6 @@ export async function resolvePlugins( ): Promise { const isBuild = config.command === 'build' const isWatch = isBuild && !!config.build.watch - const buildPlugins = isBuild ? (await import('../build')).resolveBuildPlugins(config) : { pre: [], post: [] } @@ -47,7 +46,8 @@ export async function resolvePlugins( config.build.polyfillModulePreload ? modulePreloadPolyfillPlugin(config) : null, - ...(isDepsOptimizerEnabled(config) + ...(isDepsOptimizerEnabled(config, false) || + isDepsOptimizerEnabled(config, true) ? [ isBuild ? optimizedDepsBuildPlugin(config) @@ -62,8 +62,7 @@ export async function resolvePlugins( packageCache: config.packageCache, ssrConfig: config.ssr, asSrc: true, - getDepsOptimizer: (type: { ssr?: boolean }) => - getDepsOptimizer(config, type), + getDepsOptimizer: (ssr: boolean) => getDepsOptimizer(config, ssr), shouldExternalize: isBuild && config.build.ssr && config.ssr?.format !== 'cjs' ? (id) => shouldExternalizeForSSR(id, config) @@ -86,7 +85,7 @@ export async function resolvePlugins( wasmFallbackPlugin(), definePlugin(config), cssPostPlugin(config), - config.build.ssr ? ssrRequireHookPlugin(config) : null, + isBuild && config.build.ssr ? ssrRequireHookPlugin(config) : null, isBuild && buildHtmlPlugin(config), workerImportMetaUrlPlugin(config), ...buildPlugins.pre, diff --git a/packages/vite/src/node/plugins/optimizedDeps.ts b/packages/vite/src/node/plugins/optimizedDeps.ts index dff944c3d224e2..98139519b88a47 100644 --- a/packages/vite/src/node/plugins/optimizedDeps.ts +++ b/packages/vite/src/node/plugins/optimizedDeps.ts @@ -18,7 +18,7 @@ export function optimizedDepsPlugin(config: ResolvedConfig): Plugin { name: 'vite:optimized-deps', async resolveId(id, source, { ssr }) { - if (getDepsOptimizer(config, { ssr })?.isOptimizedDepFile(id)) { + if (getDepsOptimizer(config, ssr)?.isOptimizedDepFile(id)) { return id } }, @@ -29,7 +29,7 @@ export function optimizedDepsPlugin(config: ResolvedConfig): Plugin { async load(id, options) { const ssr = options?.ssr === true - const depsOptimizer = getDepsOptimizer(config, { ssr }) + const depsOptimizer = getDepsOptimizer(config, ssr) if (depsOptimizer?.isOptimizedDepFile(id)) { const metadata = depsOptimizer.metadata const file = cleanUrl(id) @@ -85,29 +85,26 @@ export function optimizedDepsBuildPlugin(config: ResolvedConfig): Plugin { if (!config.isWorker) { // This will be run for the current active optimizer, during build // it will be the SSR optimizer if config.build.ssr is defined - getDepsOptimizer(config, { ssr: undefined })?.resetRegisteredIds() + getDepsOptimizer(config)?.resetRegisteredIds() } }, async resolveId(id, importer, { ssr }) { - if (getDepsOptimizer(config, { ssr })?.isOptimizedDepFile(id)) { + if (getDepsOptimizer(config, ssr)?.isOptimizedDepFile(id)) { return id } }, transform(_code, id, options) { const ssr = options?.ssr === true - getDepsOptimizer(config, { ssr })?.delayDepsOptimizerUntil( - id, - async () => { - await this.load({ id }) - } - ) + getDepsOptimizer(config, ssr)?.delayDepsOptimizerUntil(id, async () => { + await this.load({ id }) + }) }, async load(id, options) { const ssr = options?.ssr === true - const depsOptimizer = getDepsOptimizer(config, { ssr }) + const depsOptimizer = getDepsOptimizer(config, ssr) if (!depsOptimizer?.isOptimizedDepFile(id)) { return } diff --git a/packages/vite/src/node/plugins/preAlias.ts b/packages/vite/src/node/plugins/preAlias.ts index 2623a9d4ec97bc..9eb4cfeeffa85d 100644 --- a/packages/vite/src/node/plugins/preAlias.ts +++ b/packages/vite/src/node/plugins/preAlias.ts @@ -1,6 +1,14 @@ -import type { Alias, AliasOptions, ResolvedConfig } from '..' +import fs from 'node:fs' +import path from 'node:path' +import type { + Alias, + AliasOptions, + DepOptimizationOptions, + ResolvedConfig +} from '..' import type { Plugin } from '../plugin' -import { bareImportRE } from '../utils' +import { createIsConfiguredAsSsrExternal } from '../ssr/ssrExternal' +import { bareImportRE, isOptimizable, moduleListContains } from '../utils' import { getDepsOptimizer } from '../optimizer' import { tryOptimizedResolve } from './resolve' @@ -9,25 +17,81 @@ import { tryOptimizedResolve } from './resolve' */ export function preAliasPlugin(config: ResolvedConfig): Plugin { const findPatterns = getAliasPatterns(config.resolve.alias) + const isConfiguredAsExternal = createIsConfiguredAsSsrExternal(config) + const isBuild = config.command === 'build' return { name: 'vite:pre-alias', async resolveId(id, importer, options) { const ssr = options?.ssr === true - const depsOptimizer = getDepsOptimizer(config, { ssr }) + const depsOptimizer = getDepsOptimizer(config, ssr) if ( importer && depsOptimizer && bareImportRE.test(id) && - !options?.scan + !options?.scan && + id !== '@vite/client' && + id !== '@vite/env' ) { if (findPatterns.find((pattern) => matches(pattern, id))) { - return await tryOptimizedResolve(depsOptimizer, id, importer) + const optimizedId = await tryOptimizedResolve( + depsOptimizer, + id, + importer + ) + if (optimizedId) { + return optimizedId // aliased dep already optimized + } + + const resolved = await this.resolve(id, importer, { + skipSelf: true, + ...options + }) + if (resolved && !depsOptimizer.isOptimizedDepFile(resolved.id)) { + const optimizeDeps = depsOptimizer.options + const resolvedId = resolved.id + const isVirtual = resolvedId === id || resolvedId.includes('\0') + if ( + !isVirtual && + fs.existsSync(resolvedId) && + !moduleListContains(optimizeDeps.exclude, id) && + path.isAbsolute(resolvedId) && + (resolvedId.includes('node_modules') || + optimizeDeps.include?.includes(id)) && + isOptimizable(resolvedId, optimizeDeps) && + !(isBuild && ssr && isConfiguredAsExternal(id)) && + (!ssr || optimizeAliasReplacementForSSR(resolvedId, optimizeDeps)) + ) { + // aliased dep has not yet been optimized + const optimizedInfo = depsOptimizer!.registerMissingImport( + id, + resolvedId + ) + return { id: depsOptimizer!.getOptimizedDepId(optimizedInfo) } + } + } + return resolved } } } } } +function optimizeAliasReplacementForSSR( + id: string, + optimizeDeps: DepOptimizationOptions +) { + if (optimizeDeps.include?.includes(id)) { + return true + } + // In the regular resolution, the default for non-external modules is to + // be optimized if they are CJS. Here, we don't have the package id but + // only the replacement file path. We could find the package.json from + // the id and respect the same default in the future. + // Default to not optimize an aliased replacement for now, forcing the + // user to explicitly add it to the ssr.optimizeDeps.include list. + return false +} + // In sync with rollup plugin alias logic function matches(pattern: string | RegExp, importee: string) { if (pattern instanceof RegExp) { diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index a18a30d72ee073..d82e1dc6bc63ac 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -28,6 +28,7 @@ import { isObject, isPossibleTsOutput, isTsRequest, + isWindows, nestedResolveFrom, normalizePath, resolveFrom, @@ -82,8 +83,10 @@ export interface InternalResolveOptions extends ResolveOptions { tryEsmOnly?: boolean // True when resolving during the scan phase to discover dependencies scan?: boolean + // Appends ?__vite_skip_optimization to the resolved id if shouldn't be optimized + ssrOptimizeCheck?: boolean // Resolve using esbuild deps optimization - getDepsOptimizer?: (type: { ssr?: boolean }) => DepsOptimizer | undefined + getDepsOptimizer?: (ssr: boolean) => DepsOptimizer | undefined shouldExternalize?: (id: string) => boolean | undefined } @@ -106,7 +109,7 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin { // We need to delay depsOptimizer until here instead of passing it as an option // the resolvePlugin because the optimizer is created on server listen during dev - const depsOptimizer = resolveOptions.getDepsOptimizer?.({ ssr }) + const depsOptimizer = resolveOptions.getDepsOptimizer?.(ssr) if (id.startsWith(browserExternalId)) { return id @@ -130,7 +133,10 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin { } if (importer) { - if (isTsRequest(importer)) { + if ( + isTsRequest(importer) || + resolveOpts.custom?.depScan?.loader?.startsWith('ts') + ) { options.isFromTsImporter = true } else { const moduleLang = this.getModuleInfo(importer)?.meta?.vite?.lang @@ -238,6 +244,17 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin { } } + // drive relative fs paths (only windows) + if (isWindows && id.startsWith('/')) { + const basedir = importer ? path.dirname(importer) : process.cwd() + const fsPath = path.resolve(basedir, id) + if ((res = tryFsResolve(fsPath, options))) { + isDebug && + debug(`[drive-relative] ${colors.cyan(id)} -> ${colors.dim(res)}`) + return res + } + } + // absolute fs paths if ( isNonDriveRelativeAbsolutePath(id) && @@ -639,6 +656,10 @@ export function tryNodeResolve( if (!externalize) { return resolved } + // dont external symlink packages + if (!resolved.id.includes('node_modules')) { + return + } const resolvedExt = path.extname(resolved.id) let resolvedId = id if (isDeepImport) { @@ -665,32 +686,57 @@ export function tryNodeResolve( }) } + const ext = path.extname(resolved) + const isCJS = ext === '.cjs' || (ext === '.js' && pkg.data.type !== 'module') + if ( - !resolved.includes('node_modules') || // linked - !depsOptimizer || // resolving before listening to the server - options.scan // initial esbuild scan phase + !options.ssrOptimizeCheck && + (!resolved.includes('node_modules') || // linked + !depsOptimizer || // resolving before listening to the server + options.scan) // initial esbuild scan phase ) { return { id: resolved } } + // if we reach here, it's a valid dep import that hasn't been optimized. const isJsType = OPTIMIZABLE_ENTRY_RE.test(resolved) - const exclude = depsOptimizer.options.exclude - if ( + let exclude = depsOptimizer?.options.exclude + let include = depsOptimizer?.options.exclude + if (options.ssrOptimizeCheck) { + // we don't have the depsOptimizer + exclude = options.ssrConfig?.optimizeDeps?.exclude + include = options.ssrConfig?.optimizeDeps?.exclude + } + + const skipOptimization = !isJsType || importer?.includes('node_modules') || exclude?.includes(pkgId) || exclude?.includes(nestedPath) || SPECIAL_QUERY_RE.test(resolved) || - (!isBuild && ssr) - ) { + (!isBuild && ssr) || + // Only optimize non-external CJS deps during SSR by default + (ssr && + !isCJS && + !(include?.includes(pkgId) || include?.includes(nestedPath))) + + if (options.ssrOptimizeCheck) { + return { + id: skipOptimization + ? injectQuery(resolved, `__vite_skip_optimization`) + : resolved + } + } + + if (skipOptimization) { // excluded from optimization // Inject a version query to npm deps so that the browser // can cache it without re-validation, but only do so for known js types. // otherwise we may introduce duplicated modules for externalized files // from pre-bundled deps. if (!isBuild) { - const versionHash = depsOptimizer.metadata.browserHash + const versionHash = depsOptimizer!.metadata.browserHash if (versionHash && isJsType) { resolved = injectQuery(resolved, `v=${versionHash}`) } @@ -698,8 +744,8 @@ export function tryNodeResolve( } else { // this is a missing import, queue optimize-deps re-run and // get a resolved its optimized info - const optimizedInfo = depsOptimizer.registerMissingImport(id, resolved, ssr) - resolved = depsOptimizer.getOptimizedDepId(optimizedInfo) + const optimizedInfo = depsOptimizer!.registerMissingImport(id, resolved) + resolved = depsOptimizer!.getOptimizedDepId(optimizedInfo) } if (isBuild) { diff --git a/packages/vite/src/node/plugins/worker.ts b/packages/vite/src/node/plugins/worker.ts index cf62c91f0f24f9..fe2f209b915b60 100644 --- a/packages/vite/src/node/plugins/worker.ts +++ b/packages/vite/src/node/plugins/worker.ts @@ -144,15 +144,6 @@ function emitSourcemapForWorkerEntry( return chunk } -// TODO:base review why we aren't using import.meta.url here -function toStaticRelativePath(filename: string, importer: string) { - let outputFilepath = path.posix.relative(path.dirname(importer), filename) - if (!outputFilepath.startsWith('.')) { - outputFilepath = './' + outputFilepath - } - return outputFilepath -} - export const workerAssetUrlRE = /__VITE_WORKER_ASSET__([a-z\d]{8})__/g function encodeWorkerAssetFileName( @@ -270,7 +261,7 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin { : 'module' const workerOptions = workerType === 'classic' ? '' : ',{type: "module"}' if (isBuild) { - getDepsOptimizer(config, { ssr })?.registerWorkersSource(id) + getDepsOptimizer(config, ssr)?.registerWorkersSource(id) if (query.inline != null) { const chunk = await bundleWorkerEntry(config, id, query) // inline as blob data url @@ -343,8 +334,7 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin { 'asset', chunk.fileName, 'js', - config, - toStaticRelativePath + config ) const replacementString = typeof replacement === 'string' diff --git a/packages/vite/src/node/plugins/workerImportMetaUrl.ts b/packages/vite/src/node/plugins/workerImportMetaUrl.ts index 86b8e377a40c71..5fbd7d4883382f 100644 --- a/packages/vite/src/node/plugins/workerImportMetaUrl.ts +++ b/packages/vite/src/node/plugins/workerImportMetaUrl.ts @@ -118,7 +118,7 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin { let url: string if (isBuild) { - getDepsOptimizer(config, { ssr })?.registerWorkersSource(id) + getDepsOptimizer(config, ssr)?.registerWorkersSource(id) url = await workerFileToUrl(config, file, query) } else { url = await fileToUrl(cleanUrl(file), config, this) diff --git a/packages/vite/src/node/preview.ts b/packages/vite/src/node/preview.ts index 5820a3bc6cdb91..7b2cc4bb1729b4 100644 --- a/packages/vite/src/node/preview.ts +++ b/packages/vite/src/node/preview.ts @@ -4,14 +4,14 @@ import sirv from 'sirv' import connect from 'connect' import type { Connect } from 'types/connect' import corsMiddleware from 'cors' -import type { ResolvedServerOptions } from './server' +import type { ResolvedServerOptions, ResolvedServerUrls } from './server' import type { CommonServerOptions } from './http' import { httpServerStart, resolveHttpServer, resolveHttpsConfig } from './http' import { openBrowser } from './server/openBrowser' import compression from './server/middlewares/compression' import { proxyMiddleware } from './server/middlewares/proxy' -import { resolveHostname } from './utils' -import { printCommonServerUrls } from './logger' +import { resolveHostname, resolveServerUrls } from './utils' +import { printServerUrls } from './logger' import { resolveConfig } from '.' import type { InlineConfig, ResolvedConfig } from '.' @@ -47,10 +47,16 @@ export interface PreviewServer { * native Node http server instance */ httpServer: http.Server + /** + * The resolved urls Vite prints on the + * + * @experimental + */ + resolvedUrls: ResolvedServerUrls /** * Print server urls */ - printUrls: () => Promise + printUrls(): void } export type PreviewServerHook = (server: { @@ -127,6 +133,12 @@ export async function preview( logger }) + const resolvedUrls = await resolveServerUrls( + httpServer, + config.preview, + config + ) + if (options.open) { const path = typeof options.open === 'string' ? options.open : previewBase openBrowser( @@ -141,8 +153,9 @@ export async function preview( return { config, httpServer, - async printUrls() { - await printCommonServerUrls(httpServer, config.preview, config) + resolvedUrls, + printUrls() { + printServerUrls(resolvedUrls, options.host, logger.info) } } } diff --git a/packages/vite/src/node/server/__tests__/pluginContainer.spec.ts b/packages/vite/src/node/server/__tests__/pluginContainer.spec.ts index c6f81e9107ef0b..94acc70304e86e 100644 --- a/packages/vite/src/node/server/__tests__/pluginContainer.spec.ts +++ b/packages/vite/src/node/server/__tests__/pluginContainer.spec.ts @@ -100,6 +100,52 @@ describe('plugin container', () => { expect.assertions(1) }) + + it('can pass custom resolve opts between plugins', async () => { + const entryUrl = '/x.js' + + const plugin1: Plugin = { + name: 'p1', + resolveId(id) { + if (id === entryUrl) { + return this.resolve('foobar', 'notreal', { + custom: { p1: 'success' }, + isEntry: true + }) + } + } + } + + const plugin2: Plugin = { + name: 'p2', + resolveId(id, importer, opts) { + if (id === 'foobar') { + expect(importer).toBe('notreal') + expect(opts).toEqual( + expect.objectContaining({ + custom: { p1: 'success' }, + isEntry: true + }) + ) + return entryUrl + } + }, + load(id) { + if (id === entryUrl) { + return null + } + } + } + + const container = await getPluginContainer({ + plugins: [plugin1, plugin2] + }) + + await moduleGraph.ensureEntryFromUrl(entryUrl, false) + await container.load(entryUrl) + + expect.assertions(2) + }) }) }) diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index 9c722ed667a4e7..a8222be65ae7b2 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -19,7 +19,8 @@ import { isParentDirectory, mergeConfig, normalizePath, - resolveHostname + resolveHostname, + resolveServerUrls } from '../utils' import { ssrLoadModule } from '../ssr/ssrModuleLoader' import { cjsSsrResolveExternals } from '../ssr/ssrExternal' @@ -35,7 +36,7 @@ import { } from '../optimizer' import { CLIENT_DIR } from '../constants' import type { Logger } from '../logger' -import { printCommonServerUrls } from '../logger' +import { printServerUrls } from '../logger' import { invalidatePackageData } from '../packages' import type { PluginContainer } from './pluginContainer' import { createPluginContainer } from './pluginContainer' @@ -184,6 +185,13 @@ export interface ViteDevServer { * and hmr state. */ moduleGraph: ModuleGraph + /** + * The resolved urls Vite prints on the CLI. null in middleware mode or + * before `server.listen` is called. + * + * @experimental + */ + resolvedUrls: ResolvedServerUrls | null /** * Programmatically resolve, load and transform a URL and get the result * without going through the http request pipeline. @@ -234,7 +242,7 @@ export interface ViteDevServer { /** * Print server urls */ - printUrls(): Promise + printUrls(): void /** * Restart the server. * @@ -271,6 +279,11 @@ export interface ViteDevServer { > } +export interface ResolvedServerUrls { + local: string[] + network: string[] +} + export async function createServer( inlineConfig: InlineConfig = {} ): Promise { @@ -319,8 +332,9 @@ export async function createServer( pluginContainer: container, ws, moduleGraph, + resolvedUrls: null, // will be set on listen ssrTransform(code: string, inMap: SourceMap | null, url: string) { - return ssrTransform(code, inMap, url, { + return ssrTransform(code, inMap, url, code, { json: { stringify: server.config.json?.stringify } }) }, @@ -329,7 +343,7 @@ export async function createServer( }, transformIndexHtml: null!, // to be immediately set async ssrLoadModule(url, opts?: { fixStacktrace?: boolean }) { - if (isDepsOptimizerEnabled(config)) { + if (isDepsOptimizerEnabled(config, true)) { await initDevSsrDepsOptimizer(config, server) } await updateCjsSsrExternals(server) @@ -350,8 +364,16 @@ export async function createServer( ssrRewriteStacktrace(stack: string) { return ssrRewriteStacktrace(stack, moduleGraph) }, - listen(port?: number, isRestart?: boolean) { - return startServer(server, port, isRestart) + async listen(port?: number, isRestart?: boolean) { + await startServer(server, port, isRestart) + if (httpServer) { + server.resolvedUrls = await resolveServerUrls( + httpServer, + config.server, + config + ) + } + return server }, async close() { if (!middlewareMode) { @@ -360,19 +382,27 @@ export async function createServer( process.stdin.off('end', exitProcess) } } - await Promise.all([ watcher.close(), ws.close(), container.close(), closeHttpServer() ]) + server.resolvedUrls = null }, - async printUrls() { - if (httpServer) { - await printCommonServerUrls(httpServer, config.server, config) - } else { + printUrls() { + if (server.resolvedUrls) { + printServerUrls( + server.resolvedUrls, + serverConfig.host, + config.logger.info + ) + } else if (middlewareMode) { throw new Error('cannot print server URLs in middleware mode.') + } else { + throw new Error( + 'cannot print server URLs before server.listen is called.' + ) } }, async restart(forceOptimize?: boolean) { @@ -539,7 +569,8 @@ export async function createServer( } initingServer = (async function () { await container.buildStart({}) - if (isDepsOptimizerEnabled(config)) { + if (isDepsOptimizerEnabled(config, false)) { + // non-ssr await initDepsOptimizer(config, server) } initingServer = undefined @@ -571,7 +602,7 @@ async function startServer( server: ViteDevServer, inlinePort?: number, isRestart: boolean = false -): Promise { +): Promise { const httpServer = server.httpServer if (!httpServer) { throw new Error('Cannot call server.listen in middleware mode.') @@ -621,8 +652,6 @@ async function startServer( server.config.logger ) } - - return server } function createServerCloseFn(server: http.Server | null) { @@ -776,7 +805,7 @@ async function updateCjsSsrExternals(server: ViteDevServer) { // This is part of the v2 externalization heuristics and it is kept // for backwards compatibility in case user needs to fallback to the // legacy scheme. It may be removed in a future v3 minor. - const depsOptimizer = getDepsOptimizer(server.config, { ssr: false }) + const depsOptimizer = getDepsOptimizer(server.config, false) // non-ssr if (depsOptimizer) { await depsOptimizer.scanProcessing diff --git a/packages/vite/src/node/server/middlewares/proxy.ts b/packages/vite/src/node/server/middlewares/proxy.ts index 7fc576ba91252c..9f07a3c6e7bc24 100644 --- a/packages/vite/src/node/server/middlewares/proxy.ts +++ b/packages/vite/src/node/server/middlewares/proxy.ts @@ -1,4 +1,5 @@ import type * as http from 'node:http' +import type * as net from 'node:net' import httpProxy from 'http-proxy' import type { Connect } from 'types/connect' import type { HttpProxy } from 'types/http-proxy' @@ -43,16 +44,31 @@ export function proxyMiddleware( } const proxy = httpProxy.createProxyServer(opts) as HttpProxy.Server - proxy.on('error', (err, req, res) => { - config.logger.error(`${colors.red(`http proxy error:`)}\n${err.stack}`, { - timestamp: true, - error: err - }) - res - .writeHead(500, { - 'Content-Type': 'text/plain' + proxy.on('error', (err, req, originalRes) => { + // When it is ws proxy, res is net.Socket + const res = originalRes as http.ServerResponse | net.Socket + if ('req' in res) { + config.logger.error( + `${colors.red(`http proxy error:`)}\n${err.stack}`, + { + timestamp: true, + error: err + } + ) + if (!res.headersSent && !res.writableEnded) { + res + .writeHead(500, { + 'Content-Type': 'text/plain' + }) + .end() + } + } else { + config.logger.error(`${colors.red(`ws proxy error:`)}\n${err.stack}`, { + timestamp: true, + error: err }) - .end() + res.end() + } }) if (opts.configure) { diff --git a/packages/vite/src/node/server/middlewares/static.ts b/packages/vite/src/node/server/middlewares/static.ts index 9f18b6391face0..1c71529ef72e79 100644 --- a/packages/vite/src/node/server/middlewares/static.ts +++ b/packages/vite/src/node/server/middlewares/static.ts @@ -80,36 +80,40 @@ export function serveStaticMiddleware( return next() } - const url = decodeURIComponent(req.url!) + const url = new URL(req.url!, 'http://example.com') + const pathname = decodeURIComponent(url.pathname) // apply aliases to static requests as well - let redirected: string | undefined + let redirectedPathname: string | undefined for (const { find, replacement } of server.config.resolve.alias) { const matches = - typeof find === 'string' ? url.startsWith(find) : find.test(url) + typeof find === 'string' + ? pathname.startsWith(find) + : find.test(pathname) if (matches) { - redirected = url.replace(find, replacement) + redirectedPathname = pathname.replace(find, replacement) break } } - if (redirected) { + if (redirectedPathname) { // dir is pre-normalized to posix style - if (redirected.startsWith(dir)) { - redirected = redirected.slice(dir.length) + if (redirectedPathname.startsWith(dir)) { + redirectedPathname = redirectedPathname.slice(dir.length) } } - const resolvedUrl = redirected || url - let fileUrl = path.resolve(dir, resolvedUrl.replace(/^\//, '')) - if (resolvedUrl.endsWith('/') && !fileUrl.endsWith('/')) { + const resolvedPathname = redirectedPathname || pathname + let fileUrl = path.resolve(dir, resolvedPathname.replace(/^\//, '')) + if (resolvedPathname.endsWith('/') && !fileUrl.endsWith('/')) { fileUrl = fileUrl + '/' } if (!ensureServingAccess(fileUrl, server, res, next)) { return } - if (redirected) { - req.url = redirected + if (redirectedPathname) { + url.pathname = encodeURIComponent(redirectedPathname) + req.url = url.href.slice(url.origin.length) } serve(req, res, next) @@ -123,16 +127,17 @@ export function serveRawFsMiddleware( // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...` return function viteServeRawFsMiddleware(req, res, next) { - let url = decodeURIComponent(req.url!) + const url = new URL(req.url!, 'http://example.com') // In some cases (e.g. linked monorepos) files outside of root will // reference assets that are also out of served root. In such cases // the paths are rewritten to `/@fs/` prefixed paths and must be served by // searching based from fs root. - if (url.startsWith(FS_PREFIX)) { + if (url.pathname.startsWith(FS_PREFIX)) { + const pathname = decodeURIComponent(url.pathname) // restrict files outside of `fs.allow` if ( !ensureServingAccess( - slash(path.resolve(fsPathFromId(url))), + slash(path.resolve(fsPathFromId(pathname))), server, res, next @@ -141,10 +146,11 @@ export function serveRawFsMiddleware( return } - url = url.slice(FS_PREFIX.length) - if (isWindows) url = url.replace(/^[A-Z]:/i, '') + let newPathname = pathname.slice(FS_PREFIX.length) + if (isWindows) newPathname = newPathname.replace(/^[A-Z]:/i, '') - req.url = url + url.pathname = encodeURIComponent(newPathname) + req.url = url.href.slice(url.origin.length) serveFromRoot(req, res, next) } else { next() @@ -187,7 +193,7 @@ function ensureServingAccess( const hintMessage = ` ${server.config.server.fs.allow.map((i) => `- ${i}`).join('\n')} -Refer to docs https://vitejs.dev/config/#server-fs-allow for configurations and more details.` +Refer to docs https://vitejs.dev/config/server-options.html#server-fs-allow for configurations and more details.` server.config.logger.error(urlMessage) server.config.logger.warnOnce(hintMessage + '\n') diff --git a/packages/vite/src/node/server/middlewares/transform.ts b/packages/vite/src/node/server/middlewares/transform.ts index a7ff3a33768620..1bba1711e1b326 100644 --- a/packages/vite/src/node/server/middlewares/transform.ts +++ b/packages/vite/src/node/server/middlewares/transform.ts @@ -71,11 +71,8 @@ export function transformMiddleware( const isSourceMap = withoutQuery.endsWith('.map') // since we generate source map references, handle those requests here if (isSourceMap) { - if ( - getDepsOptimizer(server.config, { ssr: false })?.isOptimizedDepUrl( - url - ) - ) { + const depsOptimizer = getDepsOptimizer(server.config, false) // non-ssr + if (depsOptimizer?.isOptimizedDepUrl(url)) { // If the browser is requesting a source map for an optimized dep, it // means that the dependency has already been pre-bundled and loaded const mapFile = url.startsWith(FS_PREFIX) @@ -189,12 +186,10 @@ export function transformMiddleware( html: req.headers.accept?.includes('text/html') }) if (result) { + const depsOptimizer = getDepsOptimizer(server.config, false) // non-ssr const type = isDirectCSSRequest(url) ? 'css' : 'js' const isDep = - DEP_VERSION_RE.test(url) || - getDepsOptimizer(server.config, { ssr: false })?.isOptimizedDepUrl( - url - ) + DEP_VERSION_RE.test(url) || depsOptimizer?.isOptimizedDepUrl(url) return send(req, res, result.code, type, { etag: result.etag, // allow browser to cache npm deps! diff --git a/packages/vite/src/node/server/moduleGraph.ts b/packages/vite/src/node/server/moduleGraph.ts index 45fea171ddcc1e..4bbd79cd5cc2f6 100644 --- a/packages/vite/src/node/server/moduleGraph.ts +++ b/packages/vite/src/node/server/moduleGraph.ts @@ -1,5 +1,4 @@ import { extname } from 'node:path' -import { parse as parseUrl } from 'node:url' import type { ModuleInfo, PartialResolvedId } from 'rollup' import { isDirectCSSRequest } from '../plugins/css' import { @@ -237,10 +236,16 @@ export class ModuleGraph { url = removeImportQuery(removeTimestampQuery(url)) const resolved = await this.resolveId(url, !!ssr) const resolvedId = resolved?.id || url - const ext = extname(cleanUrl(resolvedId)) - const { pathname, search, hash } = parseUrl(url) - if (ext && !pathname!.endsWith(ext)) { - url = pathname + ext + (search || '') + (hash || '') + if ( + url !== resolvedId && + !url.includes('\0') && + !url.startsWith(`virtual:`) + ) { + const ext = extname(cleanUrl(resolvedId)) + const { pathname, search, hash } = new URL(url, 'relative://') + if (ext && !pathname!.endsWith(ext)) { + url = pathname + ext + search + hash + } } return [url, resolvedId, resolved?.meta] } diff --git a/packages/vite/src/node/server/pluginContainer.ts b/packages/vite/src/node/server/pluginContainer.ts index 0a708ed62c4e6c..fc1523fc7888a0 100644 --- a/packages/vite/src/node/server/pluginContainer.ts +++ b/packages/vite/src/node/server/pluginContainer.ts @@ -34,6 +34,7 @@ import { join, resolve } from 'node:path' import { performance } from 'node:perf_hooks' import { createRequire } from 'node:module' import type { + CustomPluginOptions, EmittedFile, InputOptions, LoadResult, @@ -91,6 +92,7 @@ export interface PluginContainer { id: string, importer?: string, options?: { + custom?: CustomPluginOptions skip?: Set ssr?: boolean /** @@ -258,7 +260,11 @@ export async function createPluginContainer( async resolve( id: string, importer?: string, - options?: { skipSelf?: boolean } + options?: { + custom?: CustomPluginOptions + isEntry?: boolean + skipSelf?: boolean + } ) { let skip: Set | undefined if (options?.skipSelf && this._activePlugin) { @@ -266,6 +272,8 @@ export async function createPluginContainer( skip.add(this._activePlugin) } let out = await container.resolveId(id, importer, { + custom: options?.custom, + isEntry: !!options?.isEntry, skip, ssr: this.ssr, scan: this._scan @@ -528,7 +536,6 @@ export async function createPluginContainer( const skip = options?.skip const ssr = options?.ssr const scan = !!options?.scan - const isEntry = !!options?.isEntry const ctx = new Context() ctx.ssr = !!ssr ctx._scan = scan @@ -548,7 +555,12 @@ export async function createPluginContainer( ctx as any, rawId, importer, - { ssr, scan, isEntry } + { + custom: options?.custom, + isEntry: !!options?.isEntry, + ssr, + scan + } ) if (!result) continue diff --git a/packages/vite/src/node/server/transformRequest.ts b/packages/vite/src/node/server/transformRequest.ts index 574e69b27524a5..8714a547f60783 100644 --- a/packages/vite/src/node/server/transformRequest.ts +++ b/packages/vite/src/node/server/transformRequest.ts @@ -145,7 +145,7 @@ async function doTransform( const result = loadAndTransform(id, url, server, options, timestamp) - getDepsOptimizer(config, { ssr })?.delayDepsOptimizerUntil(id, () => result) + getDepsOptimizer(config, ssr)?.delayDepsOptimizerUntil(id, () => result) return result } @@ -235,6 +235,7 @@ async function loadAndTransform( inMap: map, ssr }) + const originalCode = code if ( transformResult == null || (isObject(transformResult) && transformResult.code == null) @@ -258,7 +259,7 @@ async function loadAndTransform( } const result = ssr - ? await ssrTransform(code, map as SourceMap, url, { + ? await ssrTransform(code, map as SourceMap, url, originalCode, { json: { stringify: !!server.config.json?.stringify } }) : ({ diff --git a/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts b/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts index fbf7bb7bbd22ad..cc5b19522ef9a5 100644 --- a/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts +++ b/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts @@ -3,15 +3,14 @@ import { transformWithEsbuild } from '../../plugins/esbuild' import { traverseHtml } from '../../plugins/html' import { ssrTransform } from '../ssrTransform' +const ssrTransformSimple = async (code: string, url = '') => + ssrTransform(code, null, url, code) +const ssrTransformSimpleCode = async (code: string, url?: string) => + (await ssrTransformSimple(code, url))?.code + test('default import', async () => { expect( - ( - await ssrTransform( - `import foo from 'vue';console.log(foo.bar)`, - null, - null - ) - ).code + await ssrTransformSimpleCode(`import foo from 'vue';console.log(foo.bar)`) ).toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); console.log(__vite_ssr_import_0__.default.bar)" @@ -20,13 +19,9 @@ test('default import', async () => { test('named import', async () => { expect( - ( - await ssrTransform( - `import { ref } from 'vue';function foo() { return ref(0) }`, - null, - null - ) - ).code + await ssrTransformSimpleCode( + `import { ref } from 'vue';function foo() { return ref(0) }` + ) ).toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); function foo() { return __vite_ssr_import_0__.ref(0) }" @@ -35,13 +30,9 @@ test('named import', async () => { test('namespace import', async () => { expect( - ( - await ssrTransform( - `import * as vue from 'vue';function foo() { return vue.ref(0) }`, - null, - null - ) - ).code + await ssrTransformSimpleCode( + `import * as vue from 'vue';function foo() { return vue.ref(0) }` + ) ).toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); function foo() { return __vite_ssr_import_0__.ref(0) }" @@ -49,7 +40,7 @@ test('namespace import', async () => { }) test('export function declaration', async () => { - expect((await ssrTransform(`export function foo() {}`, null, null)).code) + expect(await ssrTransformSimpleCode(`export function foo() {}`)) .toMatchInlineSnapshot(` "function foo() {} Object.defineProperty(__vite_ssr_exports__, \\"foo\\", { enumerable: true, configurable: true, get(){ return foo }});" @@ -57,7 +48,7 @@ test('export function declaration', async () => { }) test('export class declaration', async () => { - expect((await ssrTransform(`export class foo {}`, null, null)).code) + expect(await ssrTransformSimpleCode(`export class foo {}`)) .toMatchInlineSnapshot(` "class foo {} Object.defineProperty(__vite_ssr_exports__, \\"foo\\", { enumerable: true, configurable: true, get(){ return foo }});" @@ -65,18 +56,17 @@ test('export class declaration', async () => { }) test('export var declaration', async () => { - expect((await ssrTransform(`export const a = 1, b = 2`, null, null)).code) + expect(await ssrTransformSimpleCode(`export const a = 1, b = 2`)) .toMatchInlineSnapshot(` - "const a = 1, b = 2 - Object.defineProperty(__vite_ssr_exports__, \\"a\\", { enumerable: true, configurable: true, get(){ return a }}); - Object.defineProperty(__vite_ssr_exports__, \\"b\\", { enumerable: true, configurable: true, get(){ return b }});" - `) + "const a = 1, b = 2 + Object.defineProperty(__vite_ssr_exports__, \\"a\\", { enumerable: true, configurable: true, get(){ return a }}); + Object.defineProperty(__vite_ssr_exports__, \\"b\\", { enumerable: true, configurable: true, get(){ return b }});" + `) }) test('export named', async () => { expect( - (await ssrTransform(`const a = 1, b = 2; export { a, b as c }`, null, null)) - .code + await ssrTransformSimpleCode(`const a = 1, b = 2; export { a, b as c }`) ).toMatchInlineSnapshot(` "const a = 1, b = 2; Object.defineProperty(__vite_ssr_exports__, \\"a\\", { enumerable: true, configurable: true, get(){ return a }}); @@ -86,8 +76,7 @@ test('export named', async () => { test('export named from', async () => { expect( - (await ssrTransform(`export { ref, computed as c } from 'vue'`, null, null)) - .code + await ssrTransformSimpleCode(`export { ref, computed as c } from 'vue'`) ).toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); @@ -98,13 +87,9 @@ test('export named from', async () => { test('named exports of imported binding', async () => { expect( - ( - await ssrTransform( - `import {createApp} from 'vue';export {createApp}`, - null, - null - ) - ).code + await ssrTransformSimpleCode( + `import {createApp} from 'vue';export {createApp}` + ) ).toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); @@ -114,13 +99,9 @@ test('named exports of imported binding', async () => { test('export * from', async () => { expect( - ( - await ssrTransform( - `export * from 'vue'\n` + `export * from 'react'`, - null, - null - ) - ).code + await ssrTransformSimpleCode( + `export * from 'vue'\n` + `export * from 'react'` + ) ).toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); __vite_ssr_exportAll__(__vite_ssr_import_0__); @@ -130,7 +111,7 @@ test('export * from', async () => { }) test('export * as from', async () => { - expect((await ssrTransform(`export * as foo from 'vue'`, null, null)).code) + expect(await ssrTransformSimpleCode(`export * as foo from 'vue'`)) .toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); @@ -140,148 +121,126 @@ test('export * as from', async () => { test('export default', async () => { expect( - (await ssrTransform(`export default {}`, null, null)).code + await ssrTransformSimpleCode(`export default {}`) ).toMatchInlineSnapshot(`"__vite_ssr_exports__.default = {}"`) }) test('import.meta', async () => { expect( - (await ssrTransform(`console.log(import.meta.url)`, null, null)).code + await ssrTransformSimpleCode(`console.log(import.meta.url)`) ).toMatchInlineSnapshot(`"console.log(__vite_ssr_import_meta__.url)"`) }) test('dynamic import', async () => { - const result = await ssrTransform( - `export const i = () => import('./foo')`, - null, - null + const result = await ssrTransformSimple( + `export const i = () => import('./foo')` ) - expect(result.code).toMatchInlineSnapshot(` + expect(result?.code).toMatchInlineSnapshot(` "const i = () => __vite_ssr_dynamic_import__('./foo') Object.defineProperty(__vite_ssr_exports__, \\"i\\", { enumerable: true, configurable: true, get(){ return i }});" `) - expect(result.deps).toEqual([]) - expect(result.dynamicDeps).toEqual(['./foo']) + expect(result?.deps).toEqual([]) + expect(result?.dynamicDeps).toEqual(['./foo']) }) test('do not rewrite method definition', async () => { - const result = await ssrTransform( - `import { fn } from 'vue';class A { fn() { fn() } }`, - null, - null + const result = await ssrTransformSimple( + `import { fn } from 'vue';class A { fn() { fn() } }` ) - expect(result.code).toMatchInlineSnapshot(` + expect(result?.code).toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); class A { fn() { __vite_ssr_import_0__.fn() } }" `) - expect(result.deps).toEqual(['vue']) + expect(result?.deps).toEqual(['vue']) }) test('do not rewrite when variable is in scope', async () => { - const result = await ssrTransform( - `import { fn } from 'vue';function A(){ const fn = () => {}; return { fn }; }`, - null, - null + const result = await ssrTransformSimple( + `import { fn } from 'vue';function A(){ const fn = () => {}; return { fn }; }` ) - expect(result.code).toMatchInlineSnapshot(` + expect(result?.code).toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); function A(){ const fn = () => {}; return { fn }; }" `) - expect(result.deps).toEqual(['vue']) + expect(result?.deps).toEqual(['vue']) }) // #5472 test('do not rewrite when variable is in scope with object destructuring', async () => { - const result = await ssrTransform( - `import { fn } from 'vue';function A(){ let {fn, test} = {fn: 'foo', test: 'bar'}; return { fn }; }`, - null, - null + const result = await ssrTransformSimple( + `import { fn } from 'vue';function A(){ let {fn, test} = {fn: 'foo', test: 'bar'}; return { fn }; }` ) - expect(result.code).toMatchInlineSnapshot(` + expect(result?.code).toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); function A(){ let {fn, test} = {fn: 'foo', test: 'bar'}; return { fn }; }" `) - expect(result.deps).toEqual(['vue']) + expect(result?.deps).toEqual(['vue']) }) // #5472 test('do not rewrite when variable is in scope with array destructuring', async () => { - const result = await ssrTransform( - `import { fn } from 'vue';function A(){ let [fn, test] = ['foo', 'bar']; return { fn }; }`, - null, - null + const result = await ssrTransformSimple( + `import { fn } from 'vue';function A(){ let [fn, test] = ['foo', 'bar']; return { fn }; }` ) - expect(result.code).toMatchInlineSnapshot(` + expect(result?.code).toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); function A(){ let [fn, test] = ['foo', 'bar']; return { fn }; }" `) - expect(result.deps).toEqual(['vue']) + expect(result?.deps).toEqual(['vue']) }) // #5727 test('rewrite variable in string interpolation in function nested arguments', async () => { - const result = await ssrTransform( - `import { fn } from 'vue';function A({foo = \`test\${fn}\`} = {}){ return {}; }`, - null, - null + const result = await ssrTransformSimple( + `import { fn } from 'vue';function A({foo = \`test\${fn}\`} = {}){ return {}; }` ) - expect(result.code).toMatchInlineSnapshot(` + expect(result?.code).toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); function A({foo = \`test\${__vite_ssr_import_0__.fn}\`} = {}){ return {}; }" `) - expect(result.deps).toEqual(['vue']) + expect(result?.deps).toEqual(['vue']) }) // #6520 test('rewrite variables in default value of destructuring params', async () => { - const result = await ssrTransform( - `import { fn } from 'vue';function A({foo = fn}){ return {}; }`, - null, - null + const result = await ssrTransformSimple( + `import { fn } from 'vue';function A({foo = fn}){ return {}; }` ) - expect(result.code).toMatchInlineSnapshot(` + expect(result?.code).toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); function A({foo = __vite_ssr_import_0__.fn}){ return {}; }" `) - expect(result.deps).toEqual(['vue']) + expect(result?.deps).toEqual(['vue']) }) test('do not rewrite when function declaration is in scope', async () => { - const result = await ssrTransform( - `import { fn } from 'vue';function A(){ function fn() {}; return { fn }; }`, - null, - null + const result = await ssrTransformSimple( + `import { fn } from 'vue';function A(){ function fn() {}; return { fn }; }` ) - expect(result.code).toMatchInlineSnapshot(` + expect(result?.code).toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); function A(){ function fn() {}; return { fn }; }" `) - expect(result.deps).toEqual(['vue']) + expect(result?.deps).toEqual(['vue']) }) test('do not rewrite catch clause', async () => { - const result = await ssrTransform( - `import {error} from './dependency';try {} catch(error) {}`, - null, - null + const result = await ssrTransformSimple( + `import {error} from './dependency';try {} catch(error) {}` ) - expect(result.code).toMatchInlineSnapshot(` + expect(result?.code).toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"./dependency\\"); try {} catch(error) {}" `) - expect(result.deps).toEqual(['./dependency']) + expect(result?.deps).toEqual(['./dependency']) }) // #2221 test('should declare variable for imported super class', async () => { expect( - ( - await ssrTransform( - `import { Foo } from './dependency';` + `class A extends Foo {}`, - null, - null - ) - ).code + await ssrTransformSimpleCode( + `import { Foo } from './dependency';` + `class A extends Foo {}` + ) ).toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"./dependency\\"); const Foo = __vite_ssr_import_0__.Foo; @@ -291,15 +250,11 @@ test('should declare variable for imported super class', async () => { // exported classes: should prepend the declaration at root level, before the // first class that uses the binding expect( - ( - await ssrTransform( - `import { Foo } from './dependency';` + - `export default class A extends Foo {}\n` + - `export class B extends Foo {}`, - null, - null - ) - ).code + await ssrTransformSimpleCode( + `import { Foo } from './dependency';` + + `export default class A extends Foo {}\n` + + `export class B extends Foo {}` + ) ).toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"./dependency\\"); const Foo = __vite_ssr_import_0__.Foo; @@ -313,28 +268,22 @@ test('should declare variable for imported super class', async () => { // #4049 test('should handle default export variants', async () => { // default anonymous functions - expect( - (await ssrTransform(`export default function() {}\n`, null, null)).code - ).toMatchInlineSnapshot(` + expect(await ssrTransformSimpleCode(`export default function() {}\n`)) + .toMatchInlineSnapshot(` "__vite_ssr_exports__.default = function() {} " `) // default anonymous class - expect((await ssrTransform(`export default class {}\n`, null, null)).code) + expect(await ssrTransformSimpleCode(`export default class {}\n`)) .toMatchInlineSnapshot(` "__vite_ssr_exports__.default = class {} " `) // default named functions expect( - ( - await ssrTransform( - `export default function foo() {}\n` + - `foo.prototype = Object.prototype;`, - null, - null - ) - ).code + await ssrTransformSimpleCode( + `export default function foo() {}\n` + `foo.prototype = Object.prototype;` + ) ).toMatchInlineSnapshot(` "function foo() {} foo.prototype = Object.prototype; @@ -342,13 +291,9 @@ test('should handle default export variants', async () => { `) // default named classes expect( - ( - await ssrTransform( - `export default class A {}\n` + `export class B extends A {}`, - null, - null - ) - ).code + await ssrTransformSimpleCode( + `export default class A {}\n` + `export class B extends A {}` + ) ).toMatchInlineSnapshot(` "class A {} class B extends A {} @@ -358,27 +303,30 @@ test('should handle default export variants', async () => { }) test('sourcemap source', async () => { - expect( - (await ssrTransform(`export const a = 1`, null, 'input.js')).map.sources - ).toStrictEqual(['input.js']) + const map = ( + await ssrTransform( + `export const a = 1`, + null, + 'input.js', + 'export const a = 1 /* */' + ) + )?.map + expect(map?.sources).toStrictEqual(['input.js']) + expect(map?.sourcesContent).toStrictEqual(['export const a = 1 /* */']) }) test('overwrite bindings', async () => { expect( - ( - await ssrTransform( - `import { inject } from 'vue';` + - `const a = { inject }\n` + - `const b = { test: inject }\n` + - `function c() { const { test: inject } = { test: true }; console.log(inject) }\n` + - `const d = inject\n` + - `function f() { console.log(inject) }\n` + - `function e() { const { inject } = { inject: true } }\n` + - `function g() { const f = () => { const inject = true }; console.log(inject) }\n`, - null, - null - ) - ).code + await ssrTransformSimpleCode( + `import { inject } from 'vue';` + + `const a = { inject }\n` + + `const b = { test: inject }\n` + + `function c() { const { test: inject } = { test: true }; console.log(inject) }\n` + + `const d = inject\n` + + `function f() { console.log(inject) }\n` + + `function e() { const { inject } = { inject: true } }\n` + + `function g() { const f = () => { const inject = true }; console.log(inject) }\n` + ) ).toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); const a = { inject: __vite_ssr_import_0__.inject } @@ -394,24 +342,20 @@ test('overwrite bindings', async () => { test('Empty array pattern', async () => { expect( - (await ssrTransform(`const [, LHS, RHS] = inMatch;`, null, null)).code + await ssrTransformSimpleCode(`const [, LHS, RHS] = inMatch;`) ).toMatchInlineSnapshot(`"const [, LHS, RHS] = inMatch;"`) }) test('function argument destructure', async () => { expect( - ( - await ssrTransform( - ` + await ssrTransformSimpleCode( + ` import { foo, bar } from 'foo' const a = ({ _ = foo() }) => {} function b({ _ = bar() }) {} function c({ _ = bar() + foo() }) {} -`, - null, - null - ) - ).code +` + ) ).toMatchInlineSnapshot(` " const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foo\\"); @@ -425,19 +369,15 @@ function c({ _ = bar() + foo() }) {} test('object destructure alias', async () => { expect( - ( - await ssrTransform( - ` + await ssrTransformSimpleCode( + ` import { n } from 'foo' const a = () => { const { type: n = 'bar' } = {} console.log(n) } -`, - null, - null - ) - ).code +` + ) ).toMatchInlineSnapshot(` " const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foo\\"); @@ -452,9 +392,8 @@ const a = () => { test('nested object destructure alias', async () => { expect( - ( - await ssrTransform( - ` + await ssrTransformSimpleCode( + ` import { remove, add, get, set, rest, objRest } from 'vue' function a() { @@ -479,11 +418,8 @@ get() set() rest() objRest() -`, - null, - null - ) - ).code +` + ) ).toMatchInlineSnapshot(` " const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); @@ -517,20 +453,16 @@ objRest() test('class props', async () => { expect( - ( - await ssrTransform( - ` + await ssrTransformSimpleCode( + ` import { remove, add } from 'vue' class A { remove = 1 add = null } -`, - null, - null - ) - ).code +` + ) ).toMatchInlineSnapshot(` " const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); @@ -548,9 +480,8 @@ class A { test('class methods', async () => { expect( - ( - await ssrTransform( - ` + await ssrTransformSimpleCode( + ` import foo from 'foo' const bar = 'bar' @@ -562,11 +493,8 @@ class A { #foo() {} bar(foo) {} } -`, - null, - null - ) - ).code +` + ) ).toMatchInlineSnapshot(` " const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"foo\\"); @@ -587,9 +515,8 @@ class A { test('declare scope', async () => { expect( - ( - await ssrTransform( - ` + await ssrTransformSimpleCode( + ` import { aaa, bbb, ccc, ddd } from 'vue' function foobar() { @@ -612,11 +539,8 @@ function foobar() { aaa() bbb() -`, - null, - null - ) - ).code +` + ) ).toMatchInlineSnapshot(` " const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"vue\\"); @@ -661,7 +585,7 @@ test('jsx', async () => { ` const id = '/foo.jsx' const result = await transformWithEsbuild(code, id) - expect((await ssrTransform(result.code, null, '/foo.jsx')).code) + expect(await ssrTransformSimpleCode(result.code, '/foo.jsx')) .toMatchInlineSnapshot(` "const __vite_ssr_import_0__ = await __vite_ssr_import__(\\"react\\"); @@ -676,17 +600,13 @@ test('jsx', async () => { test('continuous exports', async () => { expect( - ( - await ssrTransform( - ` + await ssrTransformSimpleCode( + ` export function fn1() { }export function fn2() { } - `, - null, - null - ) - ).code + ` + ) ).toMatchInlineSnapshot(` " function fn1() { @@ -710,28 +630,24 @@ export default (function getRandom() { }); `.trim() - expect((await ssrTransform(code, null, null)).code).toMatchInlineSnapshot(` + expect(await ssrTransformSimpleCode(code)).toMatchInlineSnapshot(` "__vite_ssr_exports__.default = (function getRandom() { return Math.random(); });" `) expect( - (await ssrTransform(`export default (class A {});`, null, null)).code + await ssrTransformSimpleCode(`export default (class A {});`) ).toMatchInlineSnapshot(`"__vite_ssr_exports__.default = (class A {});"`) }) // #8002 test('with hashbang', async () => { expect( - ( - await ssrTransform( - `#!/usr/bin/env node -console.log("it can parse the hashbang")`, - null, - null - ) - ).code + await ssrTransformSimpleCode( + `#!/usr/bin/env node +console.log("it can parse the hashbang")` + ) ).toMatchInlineSnapshot(` "#!/usr/bin/env node console.log(\\"it can parse the hashbang\\")" diff --git a/packages/vite/src/node/ssr/index.ts b/packages/vite/src/node/ssr/index.ts index 84f050ff8e41d4..7d2e4724f98b44 100644 --- a/packages/vite/src/node/ssr/index.ts +++ b/packages/vite/src/node/ssr/index.ts @@ -1,9 +1,13 @@ +import type { DepOptimizationConfig } from '../optimizer' + export type SSRTarget = 'node' | 'webworker' export type SSRFormat = 'esm' | 'cjs' +export type SsrDepOptimizationOptions = DepOptimizationConfig + export interface SSROptions { - external?: string[] noExternal?: string | RegExp | (string | RegExp)[] | true + external?: string[] /** * Define the target for the ssr build. The browser field in package.json * is ignored for node but used if webworker is the target @@ -18,22 +22,51 @@ export interface SSROptions { * @experimental */ format?: SSRFormat + /** + * Control over which dependencies are optimized during SSR and esbuild options + * During build: + * no external CJS dependencies are optimized by default + * During dev: + * explicit no external CJS dependencies are optimized by default + * @experimental + */ + optimizeDeps?: SsrDepOptimizationOptions } export interface ResolvedSSROptions extends SSROptions { target: SSRTarget format: SSRFormat + optimizeDeps: SsrDepOptimizationOptions } export function resolveSSROptions( - ssr: SSROptions | undefined -): ResolvedSSROptions | undefined { - if (ssr === undefined) { - return undefined + ssr: SSROptions | undefined, + buildSsrCjsExternalHeuristics?: boolean, + preserveSymlinks?: boolean +): ResolvedSSROptions { + ssr ??= {} + const optimizeDeps = ssr.optimizeDeps ?? {} + let format: SSRFormat = 'esm' + let target: SSRTarget = 'node' + if (buildSsrCjsExternalHeuristics) { + if (ssr) { + format = 'cjs' + } else { + target = 'node' + format = 'cjs' + } } return { - format: 'esm', - target: 'node', - ...ssr + format, + target, + ...ssr, + optimizeDeps: { + disabled: true, + ...optimizeDeps, + esbuildOptions: { + preserveSymlinks, + ...optimizeDeps.esbuildOptions + } + } } } diff --git a/packages/vite/src/node/ssr/ssrExternal.ts b/packages/vite/src/node/ssr/ssrExternal.ts index 59d396d2c78a55..74423748565acf 100644 --- a/packages/vite/src/node/ssr/ssrExternal.ts +++ b/packages/vite/src/node/ssr/ssrExternal.ts @@ -105,32 +105,60 @@ export function shouldExternalizeForSSR( return isSsrExternal(id) } -function createIsSsrExternal( +export function createIsConfiguredAsSsrExternal( config: ResolvedConfig ): (id: string) => boolean | undefined { - const processedIds = new Map() - - const { ssr, root } = config - + const { ssr } = config const noExternal = ssr?.noExternal const noExternalFilter = noExternal !== 'undefined' && typeof noExternal !== 'boolean' && createFilter(undefined, noExternal, { resolve: false }) - const isConfiguredAsExternal = (id: string) => { + // Returns true if it is configured as external, false if it is filtered + // by noExternal and undefined if it isn't affected by the explicit config + return (id: string) => { const { ssr } = config - if (!ssr || ssr.external?.includes(id)) { - return true - } - if (typeof noExternal === 'boolean') { - return !noExternal - } - if (noExternalFilter) { - return noExternalFilter(id) + if (ssr) { + const pkgName = getNpmPackageName(id) + if (!pkgName) { + return undefined + } + if ( + // If this id is defined as external, force it as external + // Note that individual package entries are allowed in ssr.external + ssr.external?.includes(id) + ) { + return true + } + if ( + // A package name in ssr.external externalizes every entry + ssr.external?.includes(pkgName) + ) { + // Return undefined here to avoid short-circuiting the isExternalizable check, + // that will filter this id out if it is not externalizable (e.g. a CSS file) + // We return here to make ssr.external take precedence over noExternal + return undefined + } + if (typeof noExternal === 'boolean') { + return !noExternal + } + if (noExternalFilter && !noExternalFilter(pkgName)) { + return false + } } - return true + return undefined } +} + +function createIsSsrExternal( + config: ResolvedConfig +): (id: string) => boolean | undefined { + const processedIds = new Map() + + const { ssr, root } = config + + const isConfiguredAsExternal = createIsConfiguredAsSsrExternal(config) const resolveOptions: InternalResolveOptions = { root, @@ -139,7 +167,7 @@ function createIsSsrExternal( isBuild: true } - const isValidPackageEntry = (id: string) => { + const isExternalizable = (id: string) => { if (!bareImportRE.test(id) || id.includes('\0')) { return false } @@ -158,10 +186,11 @@ function createIsSsrExternal( if (processedIds.has(id)) { return processedIds.get(id) } - const external = - !id.startsWith('.') && - !path.isAbsolute(id) && - (isBuiltin(id) || (isConfiguredAsExternal(id) && isValidPackageEntry(id))) + let external = false + if (!id.startsWith('.') && !path.isAbsolute(id)) { + external = + isBuiltin(id) || (isConfiguredAsExternal(id) ?? isExternalizable(id)) + } processedIds.set(id, external) return external } diff --git a/packages/vite/src/node/ssr/ssrModuleLoader.ts b/packages/vite/src/node/ssr/ssrModuleLoader.ts index ef07e0f2257ef0..8f61125c134d8c 100644 --- a/packages/vite/src/node/ssr/ssrModuleLoader.ts +++ b/packages/vite/src/node/ssr/ssrModuleLoader.ts @@ -137,7 +137,8 @@ async function instantiateModule( if (dep[0] !== '.' && dep[0] !== '/') { return nodeImport(dep, mod.file!, resolveOptions) } - dep = unwrapId(dep) + // convert to rollup URL because `pendingImports`, `moduleGraph.urlToModuleMap` requires that + dep = unwrapId(dep).replace(NULL_BYTE_PLACEHOLDER, '\0') if (!isCircular(dep) && !pendingImports.get(dep)?.some(isCircular)) { pendingDeps.push(dep) if (pendingDeps.length === 1) { @@ -194,7 +195,7 @@ async function instantiateModule( ssrImportKey, ssrDynamicImportKey, ssrExportAllKey, - result.code + `\n//# sourceURL=${mod.url}` + '"use strict";' + result.code + `\n//# sourceURL=${mod.url}` ) await initModule( context.global, diff --git a/packages/vite/src/node/ssr/ssrTransform.ts b/packages/vite/src/node/ssr/ssrTransform.ts index e6f0d8b3a4562c..2c38c53e74714e 100644 --- a/packages/vite/src/node/ssr/ssrTransform.ts +++ b/packages/vite/src/node/ssr/ssrTransform.ts @@ -38,12 +38,13 @@ export async function ssrTransform( code: string, inMap: SourceMap | null, url: string, + originalCode: string, options?: TransformOptions ): Promise { if (options?.json?.stringify && isJSONRequest(url)) { return ssrTransformJSON(code, inMap) } - return ssrTransformScript(code, inMap, url) + return ssrTransformScript(code, inMap, url, originalCode) } async function ssrTransformJSON( @@ -61,7 +62,8 @@ async function ssrTransformJSON( async function ssrTransformScript( code: string, inMap: SourceMap | null, - url: string + url: string, + originalCode: string ): Promise { const s = new MagicString(code) @@ -265,17 +267,23 @@ async function ssrTransformScript( let map = s.generateMap({ hires: true }) if (inMap && inMap.mappings && inMap.sources.length > 0) { - map = combineSourcemaps(url, [ - { - ...map, - sources: inMap.sources, - sourcesContent: inMap.sourcesContent - } as RawSourceMap, - inMap as RawSourceMap - ]) as SourceMap + map = combineSourcemaps( + url, + [ + { + ...map, + sources: inMap.sources, + sourcesContent: inMap.sourcesContent + } as RawSourceMap, + inMap as RawSourceMap + ], + false + ) as SourceMap } else { map.sources = [url] - map.sourcesContent = [code] + // needs to use originalCode instead of code + // because code might be already transformed even if map is null + map.sourcesContent = [originalCode] } return { diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index 6f7bef05752003..4398ec70f56121 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -7,6 +7,7 @@ import { URL, URLSearchParams, pathToFileURL } from 'node:url' import { builtinModules, createRequire } from 'node:module' import { promises as dns } from 'node:dns' import { performance } from 'node:perf_hooks' +import type { AddressInfo, Server } from 'node:net' import resolve from 'resolve' import type { FSWatcher } from 'chokidar' import remapping from '@ampproject/remapping' @@ -26,9 +27,13 @@ import { FS_PREFIX, OPTIMIZABLE_ENTRY_RE, VALID_ID_PREFIX, + loopbackHosts, wildcardHosts } from './constants' -import type { ResolvedConfig } from '.' +import type { DepOptimizationConfig } from './optimizer' +import type { ResolvedConfig } from './config' +import type { ResolvedServerUrls } from './server' +import type { CommonServerOptions } from '.' /** * Inlined to keep `@rollup/pluginutils` in devDependencies @@ -94,11 +99,12 @@ export function moduleListContains( export function isOptimizable( id: string, - optimizeDepsConfig: ResolvedConfig['optimizeDeps'] + optimizeDeps: DepOptimizationConfig ): boolean { + const { extensions } = optimizeDeps return ( OPTIMIZABLE_ENTRY_RE.test(id) || - (optimizeDepsConfig.extensions?.some((ext) => id.endsWith(ext)) ?? false) + (extensions?.some((ext) => id.endsWith(ext)) ?? false) ) } @@ -255,7 +261,7 @@ export const isDataUrl = (url: string): boolean => dataUrlRE.test(url) export const virtualModuleRE = /^virtual-module:.*/ export const virtualModulePrefix = 'virtual-module:' -const knownJsSrcRE = /\.((j|t)sx?|mjs|vue|marko|svelte|astro)($|\?)/ +const knownJsSrcRE = /\.((j|t)sx?|m[jt]s|vue|marko|svelte|astro)($|\?)/ export const isJSRequest = (url: string): boolean => { url = cleanUrl(url) if (knownJsSrcRE.test(url)) { @@ -768,8 +774,6 @@ export interface Hostname { host: string | undefined /** resolve to localhost when possible */ name: string - /** if it is using the default behavior */ - implicit: boolean } export async function resolveHostname( @@ -797,7 +801,60 @@ export async function resolveHostname( } } - return { host, name, implicit: optionsHost === undefined } + return { host, name } +} + +export async function resolveServerUrls( + server: Server, + options: CommonServerOptions, + config: ResolvedConfig +): Promise { + const address = server.address() + + const isAddressInfo = (x: any): x is AddressInfo => x?.address + if (!isAddressInfo(address)) { + return { local: [], network: [] } + } + + const local: string[] = [] + const network: string[] = [] + const hostname = await resolveHostname(options.host) + const protocol = options.https ? 'https' : 'http' + const port = address.port + const base = config.base === './' || config.base === '' ? '/' : config.base + + if (hostname.host && loopbackHosts.has(hostname.host)) { + let hostnameName = hostname.name + if ( + hostnameName === '::1' || + hostnameName === '0000:0000:0000:0000:0000:0000:0000:0001' + ) { + hostnameName = `[${hostnameName}]` + } + local.push(`${protocol}://${hostnameName}:${port}${base}`) + } else { + Object.values(os.networkInterfaces()) + .flatMap((nInterface) => nInterface ?? []) + .filter( + (detail) => + detail && + detail.address && + // Node < v18 + ((typeof detail.family === 'string' && detail.family === 'IPv4') || + // Node >= v18 + (typeof detail.family === 'number' && detail.family === 4)) + ) + .forEach((detail) => { + const host = detail.address.replace('127.0.0.1', hostname.name) + const url = `${protocol}://${host}:${port}${base}` + if (detail.address.includes('127.0.0.1')) { + local.push(url) + } else { + network.push(url) + } + }) + } + return { local, network } } export function arraify(target: T | T[]): T[] { @@ -1073,8 +1130,6 @@ export function stripBomTag(content: string): string { return content } -export const isTS = (filename: string): boolean => /\.[cm]?ts$/.test(filename) - const windowsDrivePathPrefixRE = /^[A-Za-z]:[/\\]/ /** diff --git a/playground/alias/index.html b/playground/alias/index.html index 909aaf6ef5411e..32a2fd171fc2b8 100644 --- a/playground/alias/index.html +++ b/playground/alias/index.html @@ -45,6 +45,8 @@

Alias

// aliased to an absolute URL in CJS, should be optimized import { isFunction } from '@vue/shared' + // also check name clash for aliased deps + export { isFunction } from '@vue/shared' console.log(isFunction(() => {})) diff --git a/playground/backend-integration/package.json b/playground/backend-integration/package.json index ead0c3a70d8e10..cd01caa7cf1a90 100644 --- a/playground/backend-integration/package.json +++ b/playground/backend-integration/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "sass": "^1.53.0", - "tailwindcss": "^3.1.4", + "tailwindcss": "^3.1.6", "fast-glob": "^3.2.11" } } diff --git a/playground/build-old/__tests__/build-old.spec.ts b/playground/build-old/__tests__/build-old.spec.ts new file mode 100644 index 00000000000000..085d1bbe75b986 --- /dev/null +++ b/playground/build-old/__tests__/build-old.spec.ts @@ -0,0 +1,11 @@ +import { describe, test } from 'vitest' +import { page } from '~utils' + +describe('syntax preserve', () => { + test('import.meta.url', async () => { + expect(await page.textContent('.import-meta-url')).toBe('string') + }) + test('dynamic import', async () => { + expect(await page.textContent('.dynamic-import')).toBe('success') + }) +}) diff --git a/playground/build-old/dynamic.js b/playground/build-old/dynamic.js new file mode 100644 index 00000000000000..739bb26e01b765 --- /dev/null +++ b/playground/build-old/dynamic.js @@ -0,0 +1 @@ +export default 'success' diff --git a/playground/build-old/index.html b/playground/build-old/index.html new file mode 100644 index 00000000000000..118332ac0a42fc --- /dev/null +++ b/playground/build-old/index.html @@ -0,0 +1,19 @@ +

Build Old

+ +

import meta url

+

+ +

dynamic import

+

+ + diff --git a/playground/build-old/package.json b/playground/build-old/package.json new file mode 100644 index 00000000000000..bb7f1b9b861538 --- /dev/null +++ b/playground/build-old/package.json @@ -0,0 +1,11 @@ +{ + "name": "test-build-old", + "private": true, + "version": "0.0.0", + "scripts": { + "dev": "vite", + "build": "vite build", + "debug": "node --inspect-brk ../../packages/vite/bin/vite", + "preview": "vite preview" + } +} diff --git a/playground/build-old/vite.config.js b/playground/build-old/vite.config.js new file mode 100644 index 00000000000000..aa85af55972eb1 --- /dev/null +++ b/playground/build-old/vite.config.js @@ -0,0 +1,8 @@ +import { defineConfig } from 'vite' + +export default defineConfig({ + build: { + // old browsers only + target: ['chrome60'] + } +}) diff --git a/playground/css/__tests__/css.spec.ts b/playground/css/__tests__/css.spec.ts index 5b7114c07f46cd..31425a19fc2c98 100644 --- a/playground/css/__tests__/css.spec.ts +++ b/playground/css/__tests__/css.spec.ts @@ -349,8 +349,7 @@ test('PostCSS dir-dependency', async () => { } }) -// skip because #8278 is reverted -test.skip('import dependency includes css import', async () => { +test('import dependency includes css import', async () => { expect(await getColor('.css-js-dep')).toBe('green') expect(await getColor('.css-js-dep-module')).toBe('green') }) @@ -437,9 +436,16 @@ test('PostCSS source.input.from includes query', async () => { ) }) -// skip because #8278 is reverted -test.skip('aliased css has content', async () => { +test('aliased css has content', async () => { expect(await getColor('.aliased')).toBe('blue') - expect(await page.textContent('.aliased-content')).toMatch('.aliased') + // skipped: currently not supported see #8936 + // expect(await page.textContent('.aliased-content')).toMatch('.aliased') expect(await getColor('.aliased-module')).toBe('blue') }) + +test.runIf(isBuild)('warning can be suppressed by esbuild.logOverride', () => { + serverLogs.forEach((log) => { + // no warning from esbuild css minifier + expect(log).not.toMatch('unsupported-css-property') + }) +}) diff --git a/playground/css/main.js b/playground/css/main.js index c9384b6a79013c..45e7730b868eb1 100644 --- a/playground/css/main.js +++ b/playground/css/main.js @@ -104,3 +104,5 @@ import aliasModule from '#alias-module' document .querySelector('.aliased-module') .classList.add(aliasModule.aliasedModule) + +import './unsupported.css' diff --git a/playground/css/unsupported.css b/playground/css/unsupported.css new file mode 100644 index 00000000000000..c17818a3ab33d7 --- /dev/null +++ b/playground/css/unsupported.css @@ -0,0 +1,3 @@ +.unsupported { + overflow-x: hidden; +} diff --git a/playground/css/vite.config.js b/playground/css/vite.config.js index c501213b47cded..704eb134e25880 100644 --- a/playground/css/vite.config.js +++ b/playground/css/vite.config.js @@ -7,6 +7,11 @@ module.exports = { build: { cssTarget: 'chrome61' }, + esbuild: { + logOverride: { + 'unsupported-css-property': 'silent' + } + }, resolve: { alias: { '@': __dirname, diff --git a/playground/fs-serve/__tests__/fs-serve.spec.ts b/playground/fs-serve/__tests__/fs-serve.spec.ts index 2111cac80cc4e7..142b4ac9ca3131 100644 --- a/playground/fs-serve/__tests__/fs-serve.spec.ts +++ b/playground/fs-serve/__tests__/fs-serve.spec.ts @@ -21,6 +21,11 @@ describe.runIf(isServe)('main', () => { expect(await page.textContent('.safe-fetch-status')).toBe('200') }) + test('safe fetch with query', async () => { + expect(await page.textContent('.safe-fetch-query')).toMatch('KEY=safe') + expect(await page.textContent('.safe-fetch-query-status')).toBe('200') + }) + test('safe fetch with special characters', async () => { expect( await page.textContent('.safe-fetch-subdir-special-characters') @@ -42,11 +47,21 @@ describe.runIf(isServe)('main', () => { expect(await page.textContent('.unsafe-fetch-8498-status')).toBe('403') }) + test('unsafe fetch with special characters 2 (#8498)', async () => { + expect(await page.textContent('.unsafe-fetch-8498-2')).toMatch('') + expect(await page.textContent('.unsafe-fetch-8498-2-status')).toBe('404') + }) + test('safe fs fetch', async () => { expect(await page.textContent('.safe-fs-fetch')).toBe(stringified) expect(await page.textContent('.safe-fs-fetch-status')).toBe('200') }) + test('safe fs fetch', async () => { + expect(await page.textContent('.safe-fs-fetch-query')).toBe(stringified) + expect(await page.textContent('.safe-fs-fetch-query-status')).toBe('200') + }) + test('safe fs fetch with special characters', async () => { expect(await page.textContent('.safe-fs-fetch-special-characters')).toBe( stringified @@ -64,6 +79,11 @@ describe.runIf(isServe)('main', () => { expect(await page.textContent('.unsafe-fs-fetch-8498-status')).toBe('403') }) + test('unsafe fs fetch with special characters 2 (#8498)', async () => { + expect(await page.textContent('.unsafe-fs-fetch-8498-2')).toBe('') + expect(await page.textContent('.unsafe-fs-fetch-8498-2-status')).toBe('404') + }) + test('nested entry', async () => { expect(await page.textContent('.nested-entry')).toBe('foobar') }) diff --git a/playground/fs-serve/root/src/index.html b/playground/fs-serve/root/src/index.html index 6939e0f4b09ed9..95b31e73d72ea6 100644 --- a/playground/fs-serve/root/src/index.html +++ b/playground/fs-serve/root/src/index.html @@ -7,6 +7,8 @@

Normal Import

Safe Fetch


 

+

+

 
 

Safe Fetch Subdirectory


@@ -19,10 +21,14 @@ 

Unsafe Fetch


 

 

+

+

 
 

Safe /@fs/ Fetch


 

+

+

 

 

 
@@ -31,6 +37,8 @@ 

Unsafe /@fs/ Fetch


 

 

+

+

 
 

Nested Entry


@@ -54,6 +62,17 @@ 

Denied

.then((data) => { text('.safe-fetch', JSON.stringify(data)) }) + + // inside allowed dir with query, safe fetch + fetch('/src/safe.txt?query') + .then((r) => { + text('.safe-fetch-query-status', r.status) + return r.text() + }) + .then((data) => { + text('.safe-fetch-query', JSON.stringify(data)) + }) + // inside allowed dir, safe fetch fetch('/src/subdir/safe.txt') .then((r) => { @@ -100,6 +119,19 @@

Denied

console.error(e) }) + // outside of allowed dir with special characters 2 #8498 + fetch('/src/%252e%252e%252funsafe%252etxt') + .then((r) => { + text('.unsafe-fetch-8498-2-status', r.status) + return r.text() + }) + .then((data) => { + text('.unsafe-fetch-8498-2', data) + }) + .catch((e) => { + console.error(e) + }) + // imported before, should be treated as safe fetch('/@fs/' + ROOT + '/safe.json') .then((r) => { @@ -110,6 +142,16 @@

Denied

text('.safe-fs-fetch', JSON.stringify(data)) }) + // imported before with query, should be treated as safe + fetch('/@fs/' + ROOT + '/safe.json?query') + .then((r) => { + text('.safe-fs-fetch-query-status', r.status) + return r.json() + }) + .then((data) => { + text('.safe-fs-fetch-query', JSON.stringify(data)) + }) + // not imported before, outside of root, treated as unsafe fetch('/@fs/' + ROOT + '/unsafe.json') .then((r) => { @@ -133,6 +175,18 @@

Denied

text('.unsafe-fs-fetch-8498', JSON.stringify(data)) }) + // outside root with special characters 2 #8498 + fetch( + '/@fs/' + ROOT + '/root/src/%252e%252e%252f%252e%252e%252funsafe%252ejson' + ) + .then((r) => { + text('.unsafe-fs-fetch-8498-2-status', r.status) + return r.json() + }) + .then((data) => { + text('.unsafe-fs-fetch-8498-2', JSON.stringify(data)) + }) + // not imported before, inside root with special characters, treated as safe fetch( '/@fs/' + diff --git a/playground/glob-import/__tests__/glob-import.spec.ts b/playground/glob-import/__tests__/glob-import.spec.ts index 7b9b0aa622381e..27c8dd716d0358 100644 --- a/playground/glob-import/__tests__/glob-import.spec.ts +++ b/playground/glob-import/__tests__/glob-import.spec.ts @@ -92,6 +92,12 @@ test('import glob raw', async () => { ) }) +test('import property access', async () => { + expect(await page.textContent('.property-access')).toBe( + JSON.stringify(rawResult['/dir/baz.json'], null, 2) + ) +}) + test('import relative glob raw', async () => { expect(await page.textContent('.relative-glob-raw')).toBe( JSON.stringify(relativeRawResult, null, 2) diff --git a/playground/glob-import/index.html b/playground/glob-import/index.html index ca00c065e7402d..a0ac2d866699ae 100644 --- a/playground/glob-import/index.html +++ b/playground/glob-import/index.html @@ -1,8 +1,17 @@ +

Glob import

+

Normal


+

Eager


+

node_modules


+

Raw


+

Property access

+

+

Relative raw


+

Side effect


 
 
@@ -63,6 +72,18 @@
   )
 
 
+
+
 
diff --git a/playground/import-assertion/package.json b/playground/import-assertion/package.json
new file mode 100644
index 00000000000000..68128c59993ffb
--- /dev/null
+++ b/playground/import-assertion/package.json
@@ -0,0 +1,14 @@
+{
+  "name": "test-import-assertion",
+  "private": true,
+  "version": "0.0.0",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build",
+    "debug": "node --inspect-brk ../../packages/vite/bin/vite",
+    "preview": "vite preview"
+  },
+  "dependencies": {
+    "@vitejs/import-assertion-dep": "file:./import-assertion-dep"
+  }
+}
diff --git a/playground/import-assertion/vite.config.js b/playground/import-assertion/vite.config.js
new file mode 100644
index 00000000000000..13a5b43e3c7946
--- /dev/null
+++ b/playground/import-assertion/vite.config.js
@@ -0,0 +1,12 @@
+import { defineConfig } from 'vite'
+
+export default defineConfig({
+  build: {
+    commonjsOptions: {
+      include: []
+    }
+  },
+  optimizeDeps: {
+    disabled: false
+  }
+})
diff --git a/playground/legacy/package.json b/playground/legacy/package.json
index 4d6549302951df..678d47745696b4 100644
--- a/playground/legacy/package.json
+++ b/playground/legacy/package.json
@@ -13,6 +13,6 @@
   "devDependencies": {
     "@vitejs/plugin-legacy": "workspace:*",
     "express": "^4.18.1",
-    "terser": "^5.14.1"
+    "terser": "^5.14.2"
   }
 }
diff --git a/playground/optimize-deps/__tests__/optimize-deps.spec.ts b/playground/optimize-deps/__tests__/optimize-deps.spec.ts
index b0af6debca526e..a62b4525e057be 100644
--- a/playground/optimize-deps/__tests__/optimize-deps.spec.ts
+++ b/playground/optimize-deps/__tests__/optimize-deps.spec.ts
@@ -105,14 +105,11 @@ test('vue + vuex', async () => {
 
 // When we use the Rollup CommonJS plugin instead of esbuild prebundling,
 // the esbuild plugins won't apply to dependencies
-test.skipIf(isBuild && process.env.VITE_TEST_LEGACY_CJS_PLUGIN)(
-  'esbuild-plugin',
-  async () => {
-    expect(await page.textContent('.esbuild-plugin')).toMatch(
-      `Hello from an esbuild plugin`
-    )
-  }
-)
+test('esbuild-plugin', async () => {
+  expect(await page.textContent('.esbuild-plugin')).toMatch(
+    `Hello from an esbuild plugin`
+  )
+})
 
 test('import from hidden dir', async () => {
   expect(await page.textContent('.hidden-dir')).toBe('hello!')
diff --git a/playground/optimize-deps/cjs.js b/playground/optimize-deps/cjs.js
index 53da284e0dc8d2..9a4651d6ad4008 100644
--- a/playground/optimize-deps/cjs.js
+++ b/playground/optimize-deps/cjs.js
@@ -6,6 +6,11 @@ import ReactDOM from 'react-dom/client'
 import { Socket } from 'phoenix'
 import clip from 'clipboard'
 
+// Test exporting a name that was already imported
+export { useState } from 'react'
+export { useState as anotherNameForUseState } from 'react'
+export { default as React } from 'react'
+
 if (typeof clip === 'function') {
   text('.cjs-clipboard', 'ok')
 }
diff --git a/playground/optimize-deps/package.json b/playground/optimize-deps/package.json
index 7fbb2b6577d69f..19184eb8af8c77 100644
--- a/playground/optimize-deps/package.json
+++ b/playground/optimize-deps/package.json
@@ -26,7 +26,7 @@
     "added-in-entries": "file:./added-in-entries",
     "lodash-es": "^4.17.21",
     "nested-exclude": "file:./nested-exclude",
-    "phoenix": "^1.6.10",
+    "phoenix": "^1.6.11",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
     "resolve-linked": "workspace:0.0.0",
diff --git a/playground/optimize-deps/vite.config.js b/playground/optimize-deps/vite.config.js
index 0b857173fe1e83..091f994e2c6aec 100644
--- a/playground/optimize-deps/vite.config.js
+++ b/playground/optimize-deps/vite.config.js
@@ -14,8 +14,8 @@ module.exports = {
       'node:url': 'url'
     }
   },
-
   optimizeDeps: {
+    disabled: false,
     include: [
       'dep-linked-include',
       'nested-exclude > nested-include',
@@ -44,7 +44,11 @@ module.exports = {
 
   build: {
     // to make tests faster
-    minify: false
+    minify: false,
+    // Avoid @rollup/plugin-commonjs
+    commonjsOptions: {
+      include: []
+    }
   },
 
   plugins: [
diff --git a/playground/preload/package.json b/playground/preload/package.json
index c72b346dece591..a42f414575cd22 100644
--- a/playground/preload/package.json
+++ b/playground/preload/package.json
@@ -10,11 +10,11 @@
   },
   "dependencies": {
     "vue": "^3.2.37",
-    "vue-router": "^4.0.16"
+    "vue-router": "^4.1.2"
   },
   "devDependencies": {
     "@vitejs/plugin-vue": "workspace:*",
-    "terser": "^5.14.1",
+    "terser": "^5.14.2",
     "dep-a": "file:./dep-a",
     "dep-including-a": "file:./dep-including-a"
   }
diff --git a/playground/react-emotion/package.json b/playground/react-emotion/package.json
index 7ef711da793e2c..c9b77a7374df8d 100644
--- a/playground/react-emotion/package.json
+++ b/playground/react-emotion/package.json
@@ -15,7 +15,7 @@
     "react-switch": "^7.0.0"
   },
   "devDependencies": {
-    "@babel/plugin-proposal-pipeline-operator": "^7.18.6",
+    "@babel/plugin-proposal-pipeline-operator": "^7.18.9",
     "@emotion/babel-plugin": "^11.9.2",
     "@vitejs/plugin-react": "workspace:*"
   },
diff --git a/playground/react-sourcemap/App.jsx b/playground/react-sourcemap/App.jsx
new file mode 100644
index 00000000000000..ec47ca46ad212e
--- /dev/null
+++ b/playground/react-sourcemap/App.jsx
@@ -0,0 +1,8 @@
+console.log('App.jsx 1') // for sourcemap
+function App() {
+  return 
foo
+} + +console.log('App.jsx 2') // for sourcemap + +export default App diff --git a/playground/react-sourcemap/__tests__/react-sourcemap.spec.ts b/playground/react-sourcemap/__tests__/react-sourcemap.spec.ts new file mode 100644 index 00000000000000..a1d35485760753 --- /dev/null +++ b/playground/react-sourcemap/__tests__/react-sourcemap.spec.ts @@ -0,0 +1,7 @@ +import { isBuild, serverLogs } from '~utils' + +test.runIf(isBuild)('should not output sourcemap warning', () => { + serverLogs.forEach((log) => { + expect(log).not.toMatch('Sourcemap is likely to be incorrect') + }) +}) diff --git a/playground/react-sourcemap/index.html b/playground/react-sourcemap/index.html new file mode 100644 index 00000000000000..d3ca9807c608ba --- /dev/null +++ b/playground/react-sourcemap/index.html @@ -0,0 +1,2 @@ +
+ diff --git a/playground/react-sourcemap/main.jsx b/playground/react-sourcemap/main.jsx new file mode 100644 index 00000000000000..705d3340097aeb --- /dev/null +++ b/playground/react-sourcemap/main.jsx @@ -0,0 +1,9 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import App from './App.jsx' + +ReactDOM.createRoot(document.getElementById('app')).render( + React.createElement(App) +) + +console.log('main.jsx') // for sourcemap diff --git a/playground/react-sourcemap/package.json b/playground/react-sourcemap/package.json new file mode 100644 index 00000000000000..91aa3331b877b4 --- /dev/null +++ b/playground/react-sourcemap/package.json @@ -0,0 +1,21 @@ +{ + "name": "test-react-sourcemap", + "private": true, + "version": "0.0.0", + "scripts": { + "dev": "vite", + "dev:classic": "cross-env USE_CLASSIC=1 vite", + "build": "vite build", + "build:classic": "cross-env USE_CLASSIC=1 vite build", + "debug": "node --inspect-brk ../../packages/vite/bin/vite", + "preview": "vite preview" + }, + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@vitejs/plugin-react": "workspace:*", + "cross-env": "^7.0.3" + } +} diff --git a/playground/react-sourcemap/vite.config.ts b/playground/react-sourcemap/vite.config.ts new file mode 100644 index 00000000000000..d8a2cc46b419b9 --- /dev/null +++ b/playground/react-sourcemap/vite.config.ts @@ -0,0 +1,15 @@ +import react from '@vitejs/plugin-react' +import type { UserConfig } from 'vite' + +const config: UserConfig = { + plugins: [ + react({ + jsxRuntime: process.env.USE_CLASSIC === '1' ? 'classic' : 'automatic' + }) + ], + build: { + sourcemap: true + } +} + +export default config diff --git a/playground/resolve/__tests__/resolve.spec.ts b/playground/resolve/__tests__/resolve.spec.ts index 79ab9dce6409c3..e95e6d78c409c5 100644 --- a/playground/resolve/__tests__/resolve.spec.ts +++ b/playground/resolve/__tests__/resolve.spec.ts @@ -1,4 +1,4 @@ -import { isBuild, page } from '~utils' +import { isBuild, isWindows, page } from '~utils' test('bom import', async () => { expect(await page.textContent('.utf8-bom')).toMatch('[success]') @@ -75,6 +75,14 @@ test('filename with dot', async () => { expect(await page.textContent('.dot')).toMatch('[success]') }) +test.runIf(isWindows)('drive-relative path', async () => { + expect(await page.textContent('.drive-relative')).toMatch('[success]') +}) + +test('absolute path', async () => { + expect(await page.textContent('.absolute')).toMatch('[success]') +}) + test('browser field', async () => { expect(await page.textContent('.browser')).toMatch('[success]') }) diff --git a/playground/resolve/absolute.js b/playground/resolve/absolute.js new file mode 100644 index 00000000000000..c0581888ebb90b --- /dev/null +++ b/playground/resolve/absolute.js @@ -0,0 +1 @@ +export default '[success] absolute' diff --git a/playground/resolve/drive-relative.js b/playground/resolve/drive-relative.js new file mode 100644 index 00000000000000..188ac36e661b35 --- /dev/null +++ b/playground/resolve/drive-relative.js @@ -0,0 +1 @@ +export default '[success] drive relative' diff --git a/playground/resolve/index.html b/playground/resolve/index.html index 1920ebb675d24c..674819fc0195a6 100644 --- a/playground/resolve/index.html +++ b/playground/resolve/index.html @@ -52,9 +52,27 @@

fail

+

+ A ts module can import another ESM module using its corresponding mjs file + name +

+

fail

+ +

+ A ts module can import another CommonJS module using its corresponding cjs + file name +

+

fail

+

Resolve file name containing dot

fail

+

Resolve drive-relative path (Windows only)

+

fail

+ +

Resolve absolute path

+

fail

+

Browser Field

fail

@@ -70,6 +88,9 @@

Monorepo linked dep

Plugin resolved virtual file

+

Plugin resolved virtual file (#9036)

+

+

Plugin resolved custom virtual file

@@ -89,6 +110,7 @@

resolve package that contains # in path

diff --git a/playground/vue/__tests__/vue.spec.ts b/playground/vue/__tests__/vue.spec.ts index b2243879f4d401..b2fbcf4e093cf5 100644 --- a/playground/vue/__tests__/vue.spec.ts +++ b/playground/vue/__tests__/vue.spec.ts @@ -25,6 +25,7 @@ test('template/script latest syntax support', async () => { test('import ts with .js extension with lang="ts"', async () => { expect(await page.textContent('.ts-import')).toBe('success') + expect(await page.textContent('.ts-import2')).toBe('success') }) test('should remove comments in prod', async () => { diff --git a/playground/vue/vite.config.ts b/playground/vue/vite.config.ts index f99a68ce8b6b10..c1561ce2c2bd47 100644 --- a/playground/vue/vite.config.ts +++ b/playground/vue/vite.config.ts @@ -5,7 +5,8 @@ import { vueI18nPlugin } from './CustomBlockPlugin' export default defineConfig({ resolve: { alias: { - '/@': __dirname + '/@': __dirname, + '@': __dirname } }, plugins: [ diff --git a/playground/worker/__tests__/iife/vite.config.js b/playground/worker/__tests__/iife/vite.config.js index 4204f532b7ac1c..47821e59505e02 100644 --- a/playground/worker/__tests__/iife/vite.config.js +++ b/playground/worker/__tests__/iife/vite.config.js @@ -1 +1 @@ -module.exports = require('../../vite.config') +module.exports = require('../../vite.config-iife') diff --git a/playground/worker/__tests__/relative-base/relative-base-worker.spec.ts b/playground/worker/__tests__/relative-base/relative-base-worker.spec.ts index ef8accdad72d99..89c042ba322b27 100644 --- a/playground/worker/__tests__/relative-base/relative-base-worker.spec.ts +++ b/playground/worker/__tests__/relative-base/relative-base-worker.spec.ts @@ -68,8 +68,8 @@ describe.runIf(isBuild)('build', () => { expect(workerContent).not.toMatch(`import`) expect(workerContent).not.toMatch(`export`) // chunk - expect(content).toMatch(`new Worker("../worker-entries/`) - expect(content).toMatch(`new SharedWorker("../worker-entries/`) + expect(content).toMatch(`new Worker(""+new URL("../worker-entries/`) + expect(content).toMatch(`new SharedWorker(""+new URL("../worker-entries/`) // inlined expect(content).toMatch(`(window.URL||window.webkitURL).createObjectURL`) expect(content).toMatch(`window.Blob`) diff --git a/playground/worker/package.json b/playground/worker/package.json index a4ee96e1620538..701fca25628e76 100644 --- a/playground/worker/package.json +++ b/playground/worker/package.json @@ -3,9 +3,9 @@ "private": true, "version": "0.0.0", "scripts": { - "dev": "vite", - "build": "vite build", - "preview": "vite preview", + "dev": "vite --config ./vite.config-iife.js", + "build": "vite --config ./vite.config-iife.js build", + "preview": "vite --config ./vite.config-iife.js preview", "dev:es": "vite --config ./vite.config-es.js dev", "build:es": "vite --config ./vite.config-es.js build", "preview:es": "vite --config ./vite.config-es.js preview", diff --git a/playground/worker/vite.config.js b/playground/worker/vite.config-iife.js similarity index 56% rename from playground/worker/vite.config.js rename to playground/worker/vite.config-iife.js index d62d6c4f6d6d36..3a0578c329f8ea 100644 --- a/playground/worker/vite.config.js +++ b/playground/worker/vite.config-iife.js @@ -5,12 +5,29 @@ module.exports = vite.defineConfig({ base: '/iife/', worker: { format: 'iife', - plugins: [vueJsx()], + plugins: [ + vueJsx(), + { + name: 'config-test', + config() { + return { + worker: { + rollupOptions: { + output: { + entryFileNames: 'assets/worker_entry.[name].js' + } + } + } + } + } + } + ], rollupOptions: { output: { assetFileNames: 'assets/worker_asset.[name].[ext]', chunkFileNames: 'assets/worker_chunk.[name].js', - entryFileNames: 'assets/worker_entry.[name].js' + // should fix by config-test plugin + entryFileNames: 'assets/worker_.[name].js' } } }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d63fd7c1ce006c..74c0cc0cb09e17 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,15 +10,15 @@ importers: .: specifiers: - '@babel/types': ^7.18.7 - '@microsoft/api-extractor': ^7.28.2 + '@babel/types': ^7.18.9 + '@microsoft/api-extractor': ^7.28.4 '@rollup/plugin-typescript': ^8.3.3 '@types/babel__core': ^7.1.19 '@types/babel__standalone': ^7.1.4 '@types/convert-source-map': ^1.5.2 '@types/cross-spawn': ^6.0.2 '@types/debug': ^4.1.7 - '@types/estree': ^0.0.52 + '@types/estree': ^1.0.0 '@types/etag': ^1.8.1 '@types/fs-extra': ^9.0.13 '@types/hash-sum': ^1.0.0 @@ -33,12 +33,12 @@ importers: '@types/semver': ^7.3.10 '@types/stylus': ^0.48.38 '@types/ws': ^8.5.3 - '@typescript-eslint/eslint-plugin': ^5.30.4 - '@typescript-eslint/parser': ^5.30.4 + '@typescript-eslint/eslint-plugin': ^5.30.6 + '@typescript-eslint/parser': ^5.30.6 conventional-changelog-cli: ^2.2.2 cross-env: ^7.0.3 esbuild: ^0.14.47 - eslint: ^8.19.0 + eslint: ^8.20.0 eslint-define-config: ^1.5.1 eslint-plugin-import: ^2.26.0 eslint-plugin-node: ^11.1.0 @@ -47,11 +47,11 @@ importers: kill-port: ^1.6.1 lint-staged: ^13.0.3 minimist: ^1.2.6 - node-fetch: ^3.2.6 + node-fetch: ^3.2.8 npm-run-all: ^4.1.5 picocolors: ^1.0.0 - playwright-chromium: ^1.23.1 - pnpm: ^7.5.0 + playwright-chromium: ^1.23.4 + pnpm: ^7.5.2 prettier: 2.7.1 prompts: ^2.4.2 rimraf: ^3.0.2 @@ -60,23 +60,23 @@ importers: simple-git-hooks: ^2.8.0 sirv: ^2.0.2 tslib: ^2.4.0 - tsx: ^3.7.1 + tsx: ^3.8.0 typescript: ^4.6.4 unbuild: ^0.7.4 vite: workspace:* vitepress: ^1.0.0-alpha.4 - vitest: ^0.17.0 + vitest: ^0.18.1 vue: ^3.2.37 devDependencies: - '@babel/types': 7.18.7 - '@microsoft/api-extractor': 7.28.2 + '@babel/types': 7.18.9 + '@microsoft/api-extractor': 7.28.4 '@rollup/plugin-typescript': 8.3.3_uct5nfewsakxkk4livyn3qaf3e '@types/babel__core': 7.1.19 '@types/babel__standalone': 7.1.4 '@types/convert-source-map': 1.5.2 '@types/cross-spawn': 6.0.2 '@types/debug': 4.1.7 - '@types/estree': 0.0.52 + '@types/estree': 1.0.0 '@types/etag': 1.8.1 '@types/fs-extra': 9.0.13 '@types/hash-sum': 1.0.0 @@ -91,25 +91,25 @@ importers: '@types/semver': 7.3.10 '@types/stylus': 0.48.38 '@types/ws': 8.5.3 - '@typescript-eslint/eslint-plugin': 5.30.4_nnp5j3mtg3i6tzbs733geadfcy - '@typescript-eslint/parser': 5.30.4_g4cxuhevh5o54harssx6h7xjim + '@typescript-eslint/eslint-plugin': 5.30.6_m6yr5nzxxaufp5er7e5dqljbi4 + '@typescript-eslint/parser': 5.30.6_sxmbcirybhoxa24uzkr344oiiy conventional-changelog-cli: 2.2.2 cross-env: 7.0.3 esbuild: 0.14.47 - eslint: 8.19.0 + eslint: 8.20.0 eslint-define-config: 1.5.1 - eslint-plugin-import: 2.26.0_eewxtjj33uq4o73zpcjsegq3l4 - eslint-plugin-node: 11.1.0_eslint@8.19.0 + eslint-plugin-import: 2.26.0_y5cwkwncsnk6w3wfynadgn7abe + eslint-plugin-node: 11.1.0_eslint@8.20.0 execa: 6.1.0 fs-extra: 10.1.0 kill-port: 1.6.1 lint-staged: 13.0.3 minimist: 1.2.6 - node-fetch: 3.2.6 + node-fetch: 3.2.8 npm-run-all: 4.1.5 picocolors: 1.0.0 - playwright-chromium: 1.23.1 - pnpm: 7.5.0 + playwright-chromium: 1.23.4 + pnpm: 7.5.2 prettier: 2.7.1 prompts: 2.4.2 rimraf: 3.0.2 @@ -118,12 +118,12 @@ importers: simple-git-hooks: 2.8.0 sirv: 2.0.2 tslib: 2.4.0 - tsx: 3.7.1 + tsx: 3.8.0 typescript: 4.6.4 unbuild: 0.7.4 vite: link:packages/vite vitepress: 1.0.0-alpha.4 - vitest: 0.17.0 + vitest: 0.18.1 vue: 3.2.37 packages/create-vite: @@ -138,38 +138,40 @@ importers: packages/plugin-legacy: specifiers: - '@babel/core': ^7.18.6 - '@babel/standalone': ^7.18.7 - core-js: ^3.23.1 + '@babel/core': ^7.18.9 + '@babel/standalone': ^7.18.9 + core-js: ^3.23.5 magic-string: ^0.26.2 regenerator-runtime: ^0.13.9 systemjs: ^6.12.1 vite: workspace:* dependencies: - '@babel/standalone': 7.18.7 - core-js: 3.23.1 + '@babel/standalone': 7.18.9 + core-js: 3.23.5 magic-string: 0.26.2 regenerator-runtime: 0.13.9 systemjs: 6.12.1 devDependencies: - '@babel/core': 7.18.6 + '@babel/core': 7.18.9 vite: link:../vite packages/plugin-react: specifiers: - '@babel/core': ^7.18.6 + '@babel/core': ^7.18.9 '@babel/plugin-transform-react-jsx': ^7.18.6 '@babel/plugin-transform-react-jsx-development': ^7.18.6 '@babel/plugin-transform-react-jsx-self': ^7.18.6 '@babel/plugin-transform-react-jsx-source': ^7.18.6 + magic-string: ^0.26.2 react-refresh: ^0.14.0 vite: workspace:* dependencies: - '@babel/core': 7.18.6 - '@babel/plugin-transform-react-jsx': 7.18.6_@babel+core@7.18.6 - '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.18.6 - '@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.18.6 - '@babel/plugin-transform-react-jsx-source': 7.18.6_@babel+core@7.18.6 + '@babel/core': 7.18.9 + '@babel/plugin-transform-react-jsx': 7.18.6_@babel+core@7.18.9 + '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.18.9 + '@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.18.9 + '@babel/plugin-transform-react-jsx-source': 7.18.6_@babel+core@7.18.9 + magic-string: 0.26.2 react-refresh: 0.14.0 devDependencies: vite: link:../vite @@ -196,24 +198,24 @@ importers: packages/plugin-vue-jsx: specifiers: - '@babel/core': ^7.18.6 + '@babel/core': ^7.18.9 '@babel/plugin-syntax-import-meta': ^7.10.4 - '@babel/plugin-transform-typescript': ^7.18.6 + '@babel/plugin-transform-typescript': ^7.18.8 '@vue/babel-plugin-jsx': ^1.1.1 vite: workspace:* dependencies: - '@babel/core': 7.18.6 - '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.18.6 - '@babel/plugin-transform-typescript': 7.18.6_@babel+core@7.18.6 - '@vue/babel-plugin-jsx': 1.1.1_@babel+core@7.18.6 + '@babel/core': 7.18.9 + '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.18.9 + '@babel/plugin-transform-typescript': 7.18.8_@babel+core@7.18.9 + '@vue/babel-plugin-jsx': 1.1.1_@babel+core@7.18.9 devDependencies: vite: link:../vite packages/vite: specifiers: '@ampproject/remapping': ^2.2.0 - '@babel/parser': ^7.18.6 - '@babel/types': ^7.18.7 + '@babel/parser': ^7.18.9 + '@babel/types': ^7.18.9 '@jridgewell/trace-mapping': ^0.3.14 '@rollup/plugin-alias': ^3.1.9 '@rollup/plugin-commonjs': ^22.0.1 @@ -247,7 +249,6 @@ importers: micromatch: ^4.0.5 mlly: ^0.5.4 mrmime: ^1.0.1 - node-forge: ^1.3.1 okie: ^1.0.1 open: ^8.4.0 periscopic: ^3.0.4 @@ -268,8 +269,8 @@ importers: tsconfck: ^2.0.1 tslib: ^2.4.0 types: link:./types - ufo: ^0.8.4 - ws: ^8.8.0 + ufo: ^0.8.5 + ws: ^8.8.1 dependencies: esbuild: 0.14.47 postcss: 8.4.14 @@ -279,8 +280,8 @@ importers: fsevents: 2.3.2 devDependencies: '@ampproject/remapping': 2.2.0 - '@babel/parser': 7.18.6 - '@babel/types': 7.18.7 + '@babel/parser': 7.18.9 + '@babel/types': 7.18.9 '@jridgewell/trace-mapping': 0.3.14 '@rollup/plugin-alias': 3.1.9_rollup@2.75.6 '@rollup/plugin-commonjs': 22.0.1_rollup@2.75.6 @@ -312,7 +313,6 @@ importers: micromatch: 4.0.5 mlly: 0.5.4 mrmime: 1.0.1 - node-forge: 1.3.1 okie: 1.0.1 open: 8.4.0 periscopic: 3.0.4 @@ -330,8 +330,8 @@ importers: tsconfck: 2.0.1 tslib: 2.4.0 types: link:types - ufo: 0.8.4 - ws: 8.8.0 + ufo: 0.8.5 + ws: 8.8.1 playground: specifiers: @@ -364,11 +364,14 @@ importers: specifiers: fast-glob: ^3.2.11 sass: ^1.53.0 - tailwindcss: ^3.1.4 + tailwindcss: ^3.1.6 devDependencies: fast-glob: 3.2.11 sass: 1.53.0 - tailwindcss: 3.1.4 + tailwindcss: 3.1.6 + + playground/build-old: + specifiers: {} playground/cli: specifiers: {} @@ -511,6 +514,15 @@ importers: playground/html: specifiers: {} + playground/import-assertion: + specifiers: + '@vitejs/import-assertion-dep': file:./import-assertion-dep + dependencies: + '@vitejs/import-assertion-dep': file:playground/import-assertion/import-assertion-dep + + playground/import-assertion/import-assertion-dep: + specifiers: {} + playground/js-sourcemap: specifiers: {} @@ -533,11 +545,11 @@ importers: specifiers: '@vitejs/plugin-legacy': workspace:* express: ^4.18.1 - terser: ^5.14.1 + terser: ^5.14.2 devDependencies: '@vitejs/plugin-legacy': link:../../packages/plugin-legacy express: 4.18.1 - terser: 5.14.1 + terser: 5.14.2 playground/lib: specifiers: {} @@ -624,7 +636,7 @@ importers: lodash-es: ^4.17.21 lodash.clonedeep: ^4.5.0 nested-exclude: file:./nested-exclude - phoenix: ^1.6.10 + phoenix: ^1.6.11 react: ^18.2.0 react-dom: ^18.2.0 resolve-linked: workspace:0.0.0 @@ -651,7 +663,7 @@ importers: lodash-es: 4.17.21 lodash.clonedeep: 4.5.0 nested-exclude: file:playground/optimize-deps/nested-exclude - phoenix: 1.6.10 + phoenix: 1.6.11 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 resolve-linked: link:../resolve-linked @@ -741,17 +753,17 @@ importers: '@vitejs/plugin-vue': workspace:* dep-a: file:./dep-a dep-including-a: file:./dep-including-a - terser: ^5.14.1 + terser: ^5.14.2 vue: ^3.2.37 - vue-router: ^4.0.16 + vue-router: ^4.1.2 dependencies: vue: 3.2.37 - vue-router: 4.0.16_vue@3.2.37 + vue-router: 4.1.2_vue@3.2.37 devDependencies: '@vitejs/plugin-vue': link:../../packages/plugin-vue dep-a: file:playground/preload/dep-a dep-including-a: file:playground/preload/dep-including-a - terser: 5.14.1 + terser: 5.14.2 playground/preload/dep-a: specifiers: {} @@ -797,7 +809,7 @@ importers: playground/react-emotion: specifiers: - '@babel/plugin-proposal-pipeline-operator': ^7.18.6 + '@babel/plugin-proposal-pipeline-operator': ^7.18.9 '@emotion/babel-plugin': ^11.9.2 '@emotion/react': ^11.9.3 '@vitejs/plugin-react': workspace:* @@ -810,16 +822,29 @@ importers: react-dom: 18.2.0_react@18.2.0 react-switch: 7.0.0_biqbaboplfbrettd7655fr4n2y devDependencies: - '@babel/plugin-proposal-pipeline-operator': 7.18.6 + '@babel/plugin-proposal-pipeline-operator': 7.18.9 '@emotion/babel-plugin': 11.9.2 '@vitejs/plugin-react': link:../../packages/plugin-react + playground/react-sourcemap: + specifiers: + '@vitejs/plugin-react': workspace:* + cross-env: ^7.0.3 + react: ^18.2.0 + react-dom: ^18.2.0 + dependencies: + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + devDependencies: + '@vitejs/plugin-react': link:../../packages/plugin-react + cross-env: 7.0.3 + playground/react/jsx-entry: specifiers: {} playground/resolve: specifiers: - '@babel/runtime': ^7.18.6 + '@babel/runtime': ^7.18.9 es5-ext: 0.10.61 normalize.css: ^8.0.1 require-pkg-with-module-field: link:./require-pkg-with-module-field @@ -830,7 +855,7 @@ importers: resolve-exports-path: link:./exports-path resolve-linked: workspace:* dependencies: - '@babel/runtime': 7.18.6 + '@babel/runtime': 7.18.9 es5-ext: 0.10.61 normalize.css: 8.0.1 require-pkg-with-module-field: link:require-pkg-with-module-field @@ -878,8 +903,11 @@ importers: define-properties-exports: file:./define-properties-exports define-property-exports: file:./define-property-exports express: ^4.18.1 + external-entry: file:./external-entry + external-using-external-entry: file:./external-using-external-entry forwarded-export: file:./forwarded-export import-builtin-cjs: file:./import-builtin-cjs + linked-no-external: link:./linked-no-external no-external-cjs: file:./no-external-cjs no-external-css: file:./no-external-css non-optimized-with-nested-external: file:./non-optimized-with-nested-external @@ -895,8 +923,11 @@ importers: bcrypt: 5.0.1 define-properties-exports: file:playground/ssr-deps/define-properties-exports define-property-exports: file:playground/ssr-deps/define-property-exports + external-entry: file:playground/ssr-deps/external-entry + external-using-external-entry: file:playground/ssr-deps/external-using-external-entry forwarded-export: file:playground/ssr-deps/forwarded-export import-builtin-cjs: file:playground/ssr-deps/import-builtin-cjs + linked-no-external: link:linked-no-external no-external-cjs: file:playground/ssr-deps/no-external-cjs no-external-css: file:playground/ssr-deps/no-external-css non-optimized-with-nested-external: file:playground/ssr-deps/non-optimized-with-nested-external @@ -918,6 +949,15 @@ importers: playground/ssr-deps/define-property-exports: specifiers: {} + playground/ssr-deps/external-entry: + specifiers: {} + + playground/ssr-deps/external-using-external-entry: + specifiers: + external-entry: file:../external-entry + dependencies: + external-entry: file:playground/ssr-deps/external-entry + playground/ssr-deps/forwarded-export: specifiers: object-assigned-exports: file:../object-assigned-exports @@ -927,6 +967,9 @@ importers: playground/ssr-deps/import-builtin-cjs: specifiers: {} + playground/ssr-deps/linked-no-external: + specifiers: {} + playground/ssr-deps/nested-external: specifiers: {} @@ -1022,12 +1065,12 @@ importers: express: ^4.18.1 serve-static: ^1.15.0 vue: ^3.2.37 - vue-router: ^4.0.16 + vue-router: ^4.1.2 vuex: ^4.0.2 dependencies: example-external-component: file:playground/ssr-vue/example-external-component vue: 3.2.37 - vue-router: 4.0.16_vue@3.2.37 + vue-router: 4.1.2_vue@3.2.37 vuex: 4.0.2_vue@3.2.37 devDependencies: '@vitejs/plugin-vue': link:../../packages/plugin-vue @@ -1059,24 +1102,24 @@ importers: specifiers: '@vitejs/plugin-vue': workspace:* autoprefixer: ^10.4.7 - tailwindcss: ^3.1.4 - ts-node: ^10.8.2 + tailwindcss: ^3.1.6 + ts-node: ^10.9.1 vue: ^3.2.37 - vue-router: ^4.0.16 + vue-router: ^4.1.2 dependencies: autoprefixer: 10.4.7 - tailwindcss: 3.1.4_ts-node@10.8.2 + tailwindcss: 3.1.6_ts-node@10.9.1 vue: 3.2.37 - vue-router: 4.0.16_vue@3.2.37 + vue-router: 4.1.2_vue@3.2.37 devDependencies: '@vitejs/plugin-vue': link:../../packages/plugin-vue - ts-node: 10.8.2 + ts-node: 10.9.1 playground/tailwind-sourcemap: specifiers: - tailwindcss: ^3.1.4 + tailwindcss: ^3.1.6 dependencies: - tailwindcss: 3.1.4 + tailwindcss: 3.1.6 playground/tsconfig-json: specifiers: {} @@ -1290,8 +1333,8 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/compat-data/7.18.6: - resolution: {integrity: sha512-tzulrgDT0QD6U7BJ4TKVk2SDDg7wlP39P9yAx1RfLy7vP/7rsDRlWVfbWxElslu56+r7QOhB2NSDsabYYruoZQ==} + /@babel/compat-data/7.18.8: + resolution: {integrity: sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ==} engines: {node: '>=6.9.0'} /@babel/core/7.18.5: @@ -1307,7 +1350,7 @@ packages: '@babel/parser': 7.18.5 '@babel/template': 7.16.7 '@babel/traverse': 7.18.5 - '@babel/types': 7.18.7 + '@babel/types': 7.18.9 convert-source-map: 1.8.0 debug: 4.3.4 gensync: 1.0.0-beta.2 @@ -1317,20 +1360,20 @@ packages: - supports-color dev: true - /@babel/core/7.18.6: - resolution: {integrity: sha512-cQbWBpxcbbs/IUredIPkHiAGULLV8iwgNRMFzvbhEXISp4f3rUUXE5+TIw6KwUWUR3DwyI6gmBRnmAtYaWehwQ==} + /@babel/core/7.18.9: + resolution: {integrity: sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.0 '@babel/code-frame': 7.18.6 - '@babel/generator': 7.18.7 - '@babel/helper-compilation-targets': 7.18.6_@babel+core@7.18.6 - '@babel/helper-module-transforms': 7.18.6 - '@babel/helpers': 7.18.6 - '@babel/parser': 7.18.6 + '@babel/generator': 7.18.9 + '@babel/helper-compilation-targets': 7.18.9_@babel+core@7.18.9 + '@babel/helper-module-transforms': 7.18.9 + '@babel/helpers': 7.18.9 + '@babel/parser': 7.18.9 '@babel/template': 7.18.6 - '@babel/traverse': 7.18.6 - '@babel/types': 7.18.7 + '@babel/traverse': 7.18.9 + '@babel/types': 7.18.9 convert-source-map: 1.8.0 debug: 4.3.4 gensync: 1.0.0-beta.2 @@ -1343,7 +1386,7 @@ packages: resolution: {integrity: sha512-46MJZZo9y3o4kmhBVc7zW7i8dtR1oIK/sdO5NcfcZRhTGYi+KKJRtHNgsU6c4VUcJmUNV/LQdebD/9Dlv4K+Tg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.7 + '@babel/types': 7.18.8 '@jridgewell/gen-mapping': 0.1.1 jsesc: 2.5.2 dev: false @@ -1352,7 +1395,7 @@ packages: resolution: {integrity: sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.7 + '@babel/types': 7.18.9 '@jridgewell/gen-mapping': 0.3.1 jsesc: 2.5.2 dev: true @@ -1364,6 +1407,15 @@ packages: '@babel/types': 7.18.7 '@jridgewell/gen-mapping': 0.3.2 jsesc: 2.5.2 + dev: false + + /@babel/generator/7.18.9: + resolution: {integrity: sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.18.9 + '@jridgewell/gen-mapping': 0.3.2 + jsesc: 2.5.2 /@babel/helper-annotate-as-pure/7.18.6: resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} @@ -1385,25 +1437,25 @@ packages: semver: 6.3.0 dev: true - /@babel/helper-compilation-targets/7.18.6_@babel+core@7.18.6: - resolution: {integrity: sha512-vFjbfhNCzqdeAtZflUFrG5YIFqGTqsctrtkZ1D/NB0mDW9TwW3GmmUepYY4G9wCET5rY5ugz4OGTcLd614IzQg==} + /@babel/helper-compilation-targets/7.18.9_@babel+core@7.18.9: + resolution: {integrity: sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/compat-data': 7.18.6 - '@babel/core': 7.18.6 + '@babel/compat-data': 7.18.8 + '@babel/core': 7.18.9 '@babel/helper-validator-option': 7.18.6 browserslist: 4.20.3 semver: 6.3.0 - /@babel/helper-create-class-features-plugin/7.18.6_@babel+core@7.18.6: + /@babel/helper-create-class-features-plugin/7.18.6_@babel+core@7.18.9: resolution: {integrity: sha512-YfDzdnoxHGV8CzqHGyCbFvXg5QESPFkXlHtvdCkesLjjVMT2Adxe4FGUR5ChIb3DxSaXO12iIOCWoXdsUVwnqw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.18.6 + '@babel/core': 7.18.9 '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-environment-visitor': 7.18.6 '@babel/helper-function-name': 7.18.6 @@ -1419,7 +1471,7 @@ packages: resolution: {integrity: sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.7 + '@babel/types': 7.18.9 dev: true /@babel/helper-environment-visitor/7.18.2: @@ -1430,13 +1482,18 @@ packages: /@babel/helper-environment-visitor/7.18.6: resolution: {integrity: sha512-8n6gSfn2baOY+qlp+VSzsosjCVGFqWKmDF0cCWOybh52Dw3SEyoWR1KrhMJASjLwIEkkAufZ0xvr+SxLHSpy2Q==} engines: {node: '>=6.9.0'} + dev: false + + /@babel/helper-environment-visitor/7.18.9: + resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} + engines: {node: '>=6.9.0'} /@babel/helper-function-name/7.17.9: resolution: {integrity: sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==} engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.16.7 - '@babel/types': 7.18.7 + '@babel/types': 7.18.9 dev: true /@babel/helper-function-name/7.18.6: @@ -1444,32 +1501,40 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.18.6 - '@babel/types': 7.18.7 + '@babel/types': 7.18.8 + dev: false + + /@babel/helper-function-name/7.18.9: + resolution: {integrity: sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.18.6 + '@babel/types': 7.18.9 /@babel/helper-hoist-variables/7.16.7: resolution: {integrity: sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.7 + '@babel/types': 7.18.8 /@babel/helper-hoist-variables/7.18.6: resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.7 + '@babel/types': 7.18.9 /@babel/helper-member-expression-to-functions/7.18.6: resolution: {integrity: sha512-CeHxqwwipekotzPDUuJOfIMtcIHBuc7WAzLmTYWctVigqS5RktNMQ5bEwQSuGewzYnCtTWa3BARXeiLxDTv+Ng==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.7 + '@babel/types': 7.18.8 dev: false /@babel/helper-module-imports/7.16.7: resolution: {integrity: sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.7 + '@babel/types': 7.18.8 /@babel/helper-module-imports/7.18.6: resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} @@ -1488,23 +1553,23 @@ packages: '@babel/helper-validator-identifier': 7.16.7 '@babel/template': 7.16.7 '@babel/traverse': 7.18.5 - '@babel/types': 7.18.7 + '@babel/types': 7.18.9 transitivePeerDependencies: - supports-color dev: true - /@babel/helper-module-transforms/7.18.6: - resolution: {integrity: sha512-L//phhB4al5uucwzlimruukHB3jRd5JGClwRMD/ROrVjXfLqovYnvQrK/JK36WYyVwGGO7OD3kMyVTjx+WVPhw==} + /@babel/helper-module-transforms/7.18.9: + resolution: {integrity: sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-environment-visitor': 7.18.6 + '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-module-imports': 7.18.6 '@babel/helper-simple-access': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6 '@babel/helper-validator-identifier': 7.18.6 '@babel/template': 7.18.6 - '@babel/traverse': 7.18.6 - '@babel/types': 7.18.7 + '@babel/traverse': 7.18.9 + '@babel/types': 7.18.9 transitivePeerDependencies: - supports-color @@ -1512,7 +1577,7 @@ packages: resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.7 + '@babel/types': 7.18.8 dev: false /@babel/helper-plugin-utils/7.16.7: @@ -1524,6 +1589,11 @@ packages: resolution: {integrity: sha512-gvZnm1YAAxh13eJdkb9EWHBnF3eAub3XTLCZEehHT2kWxiKVRL64+ae5Y6Ivne0mVHmMYKT+xWgZO+gQhuLUBg==} engines: {node: '>=6.9.0'} + /@babel/helper-plugin-utils/7.18.9: + resolution: {integrity: sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-replace-supers/7.18.6: resolution: {integrity: sha512-fTf7zoXnUGl9gF25fXCWE26t7Tvtyn6H4hkLSYhATwJvw2uYxd3aoXplMSe0g9XbwK7bmxNes7+FGO0rB/xC0g==} engines: {node: '>=6.9.0'} @@ -1532,7 +1602,7 @@ packages: '@babel/helper-member-expression-to-functions': 7.18.6 '@babel/helper-optimise-call-expression': 7.18.6 '@babel/traverse': 7.18.6 - '@babel/types': 7.18.7 + '@babel/types': 7.18.8 transitivePeerDependencies: - supports-color dev: false @@ -1541,27 +1611,27 @@ packages: resolution: {integrity: sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.7 + '@babel/types': 7.18.9 dev: true /@babel/helper-simple-access/7.18.6: resolution: {integrity: sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.7 + '@babel/types': 7.18.9 /@babel/helper-split-export-declaration/7.16.7: resolution: {integrity: sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.7 + '@babel/types': 7.18.9 dev: true /@babel/helper-split-export-declaration/7.18.6: resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.18.7 + '@babel/types': 7.18.9 /@babel/helper-validator-identifier/7.16.7: resolution: {integrity: sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==} @@ -1586,18 +1656,18 @@ packages: dependencies: '@babel/template': 7.16.7 '@babel/traverse': 7.18.5 - '@babel/types': 7.18.7 + '@babel/types': 7.18.9 transitivePeerDependencies: - supports-color dev: true - /@babel/helpers/7.18.6: - resolution: {integrity: sha512-vzSiiqbQOghPngUYt/zWGvK3LAsPhz55vc9XNN0xAl2gV4ieShI2OQli5duxWHD+72PZPTKAcfcZDE1Cwc5zsQ==} + /@babel/helpers/7.18.9: + resolution: {integrity: sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.18.6 - '@babel/traverse': 7.18.6 - '@babel/types': 7.18.7 + '@babel/traverse': 7.18.9 + '@babel/types': 7.18.9 transitivePeerDependencies: - supports-color @@ -1630,23 +1700,31 @@ packages: hasBin: true dependencies: '@babel/types': 7.18.7 + dev: false + + /@babel/parser/7.18.9: + resolution: {integrity: sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.18.9 - /@babel/plugin-proposal-pipeline-operator/7.18.6: - resolution: {integrity: sha512-TtmOg+ew8KKLTNfOzEM/KCkwp3JKjA8E5E95rnrqnBZWs9KuXS+2yXq/x10uy+Sq9Ys6TscfRVCN2UFOhZ4bZw==} + /@babel/plugin-proposal-pipeline-operator/7.18.9: + resolution: {integrity: sha512-Pc33e6m8f4MJhRXVCUwiKZNtEm+W2CUPHIL0lyJNtkp+w6d75CLw3gsBKQ81VAMUgT9jVPIEU8gwJ5nJgmJ1Ag==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/helper-plugin-utils': 7.18.6 + '@babel/helper-plugin-utils': 7.18.9 '@babel/plugin-syntax-pipeline-operator': 7.18.6 dev: true - /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.18.6: + /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.18.9: resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.18.6 + '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.16.7 dev: false @@ -1658,23 +1736,23 @@ packages: dependencies: '@babel/helper-plugin-utils': 7.18.6 - /@babel/plugin-syntax-jsx/7.16.7_@babel+core@7.18.6: + /@babel/plugin-syntax-jsx/7.16.7_@babel+core@7.18.9: resolution: {integrity: sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.18.6 + '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 dev: false - /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.18.6: + /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.18.9: resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.18.6 + '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 dev: false @@ -1684,73 +1762,73 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/helper-plugin-utils': 7.18.6 + '@babel/helper-plugin-utils': 7.18.9 dev: true - /@babel/plugin-syntax-typescript/7.18.6_@babel+core@7.18.6: + /@babel/plugin-syntax-typescript/7.18.6_@babel+core@7.18.9: resolution: {integrity: sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.18.6 + '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 dev: false - /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.18.6: + /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.18.9: resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.18.6 - '@babel/plugin-transform-react-jsx': 7.18.6_@babel+core@7.18.6 + '@babel/core': 7.18.9 + '@babel/plugin-transform-react-jsx': 7.18.6_@babel+core@7.18.9 dev: false - /@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.18.6: + /@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.18.9: resolution: {integrity: sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.18.6 + '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 dev: false - /@babel/plugin-transform-react-jsx-source/7.18.6_@babel+core@7.18.6: + /@babel/plugin-transform-react-jsx-source/7.18.6_@babel+core@7.18.9: resolution: {integrity: sha512-utZmlASneDfdaMh0m/WausbjUjEdGrQJz0vFK93d7wD3xf5wBtX219+q6IlCNZeguIcxS2f/CvLZrlLSvSHQXw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.18.6 + '@babel/core': 7.18.9 '@babel/helper-plugin-utils': 7.18.6 dev: false - /@babel/plugin-transform-react-jsx/7.18.6_@babel+core@7.18.6: + /@babel/plugin-transform-react-jsx/7.18.6_@babel+core@7.18.9: resolution: {integrity: sha512-Mz7xMPxoy9kPS/JScj6fJs03TZ/fZ1dJPlMjRAgTaxaS0fUBk8FV/A2rRgfPsVCZqALNwMexD+0Uaf5zlcKPpw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.18.6 + '@babel/core': 7.18.9 '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-module-imports': 7.18.6 '@babel/helper-plugin-utils': 7.18.6 - '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.18.6 + '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.18.9 '@babel/types': 7.18.7 dev: false - /@babel/plugin-transform-typescript/7.18.6_@babel+core@7.18.6: - resolution: {integrity: sha512-ijHNhzIrLj5lQCnI6aaNVRtGVuUZhOXFLRVFs7lLrkXTHip4FKty5oAuQdk4tywG0/WjXmjTfQCWmuzrvFer1w==} + /@babel/plugin-transform-typescript/7.18.8_@babel+core@7.18.9: + resolution: {integrity: sha512-p2xM8HI83UObjsZGofMV/EdYjamsDm6MoN3hXPYIT0+gxIoopE+B7rPYKAxfrz9K9PK7JafTTjqYC6qipLExYA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.18.6 - '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.18.6 + '@babel/core': 7.18.9 + '@babel/helper-create-class-features-plugin': 7.18.6_@babel+core@7.18.9 '@babel/helper-plugin-utils': 7.18.6 - '@babel/plugin-syntax-typescript': 7.18.6_@babel+core@7.18.6 + '@babel/plugin-syntax-typescript': 7.18.6_@babel+core@7.18.9 transitivePeerDependencies: - supports-color dev: false @@ -1768,8 +1846,8 @@ packages: regenerator-runtime: 0.13.9 dev: false - /@babel/runtime/7.18.6: - resolution: {integrity: sha512-t9wi7/AW6XtKahAe20Yw0/mMljKq0B1r2fPdvaAdV/KPDZewFXdaaa6K7lxmZBZ8FBNpCiAT6iHPmd6QO9bKfQ==} + /@babel/runtime/7.18.9: + resolution: {integrity: sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.13.9 @@ -1780,8 +1858,8 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/standalone/7.18.7: - resolution: {integrity: sha512-AIOn3ON0KhYqAbvmkT11vi/YAlhrPn6RSPQb8Hl3PUZoE1yFwut5fQ9/oJ4Dvf2SGmO41pF7xmwP2W1RT0uJCA==} + /@babel/standalone/7.18.9: + resolution: {integrity: sha512-6E+p5azHMHcMkHzGFnA7Pqhtgfwx1cClwjMqomMHhdFupCLZDDpVQUctRGYE7p7nn7cXJZSI/L9en+tt30AP3w==} engines: {node: '>=6.9.0'} dev: false @@ -1791,15 +1869,15 @@ packages: dependencies: '@babel/code-frame': 7.16.7 '@babel/parser': 7.18.5 - '@babel/types': 7.18.7 + '@babel/types': 7.18.8 /@babel/template/7.18.6: resolution: {integrity: sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/parser': 7.18.6 - '@babel/types': 7.18.7 + '@babel/parser': 7.18.9 + '@babel/types': 7.18.9 /@babel/traverse/7.17.10: resolution: {integrity: sha512-VmbrTHQteIdUUQNTb+zE12SHS/xQVIShmBPhlNP12hD5poF2pbITW1Z4172d03HegaQWhLffdkRJYtAzp0AGcw==} @@ -1812,7 +1890,7 @@ packages: '@babel/helper-hoist-variables': 7.16.7 '@babel/helper-split-export-declaration': 7.18.6 '@babel/parser': 7.18.5 - '@babel/types': 7.18.7 + '@babel/types': 7.18.8 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: @@ -1830,7 +1908,7 @@ packages: '@babel/helper-hoist-variables': 7.16.7 '@babel/helper-split-export-declaration': 7.16.7 '@babel/parser': 7.18.5 - '@babel/types': 7.18.7 + '@babel/types': 7.18.9 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: @@ -1848,7 +1926,25 @@ packages: '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6 '@babel/parser': 7.18.6 - '@babel/types': 7.18.7 + '@babel/types': 7.18.8 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: false + + /@babel/traverse/7.18.9: + resolution: {integrity: sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.18.9 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.18.9 + '@babel/helper-hoist-variables': 7.18.6 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/parser': 7.18.9 + '@babel/types': 7.18.9 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: @@ -1875,6 +1971,20 @@ packages: '@babel/helper-validator-identifier': 7.18.6 to-fast-properties: 2.0.0 + /@babel/types/7.18.8: + resolution: {integrity: sha512-qwpdsmraq0aJ3osLJRApsc2ouSJCdnMeZwB0DhbtHAtRpZNZCdlbRnHIgcRKzdE1g0iOGg644fzjOBcdOz9cPw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.18.6 + to-fast-properties: 2.0.0 + + /@babel/types/7.18.9: + resolution: {integrity: sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.18.6 + to-fast-properties: 2.0.0 + /@cloudflare/workers-types/2.2.2: resolution: {integrity: sha512-kaMn2rueJ0PL1TYVGknTCh0X0x0d9G+FNXAFep7/4uqecEZoQb/63o6rOmMuiqI09zLuHV6xhKRXinokV/MY9A==} dev: true @@ -2001,24 +2111,24 @@ packages: resolution: {integrity: sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==} dev: false - /@esbuild-kit/cjs-loader/2.3.0: - resolution: {integrity: sha512-KInrVt8wlKLhWy7+y4a+E+0uBJoWgdx6Xupy+rrF4MFHA/dEt22ACvvChOZSyiqtQieYPtbPkVYSjbC7mOrFVw==} + /@esbuild-kit/cjs-loader/2.3.1: + resolution: {integrity: sha512-ov6ALYD9xZSPoo5mmGOQtEC/b0xXeUlPy65p8aHMHLF4DfBEe8Y+iquH2lTDsy6Iskc1uMTadF+SVADTSTNJMA==} dependencies: - '@esbuild-kit/core-utils': 2.0.2 + '@esbuild-kit/core-utils': 2.1.0 get-tsconfig: 4.1.0 dev: true - /@esbuild-kit/core-utils/2.0.2: - resolution: {integrity: sha512-clNYQUsqtc36pzW5EufMsahcbLG45EaW3YDyf0DlaS0eCMkDXpxIlHwPC0rndUwG6Ytk9sMSD5k1qHbwYEC/OQ==} + /@esbuild-kit/core-utils/2.1.0: + resolution: {integrity: sha512-fZirrc2KjeTumVjE4bpleWOk2gD83b7WuGeQqOceKFQL+heNKKkNB5G5pekOUTLzfSBc0hP7hCSBoD9TuR0hLw==} dependencies: esbuild: 0.14.47 source-map-support: 0.5.21 dev: true - /@esbuild-kit/esm-loader/2.4.0: - resolution: {integrity: sha512-zS720jXh06nfg5yAzm6oob4sWN9VTP2E1SonhFgEb6zCBswa4S8fOQ/4Bksz1flDgn56NPqoTTDn2XmWRyMG9Q==} + /@esbuild-kit/esm-loader/2.4.1: + resolution: {integrity: sha512-6x44rygVfNODm27v0RW3wX5y61mqSrXDvB39G0nomgWWqxG3mjiKtPSwrFppdkrA39QIqDgVlD4gJmPOxnleSw==} dependencies: - '@esbuild-kit/core-utils': 2.0.2 + '@esbuild-kit/core-utils': 2.1.0 get-tsconfig: 4.1.0 dev: true @@ -2098,8 +2208,8 @@ packages: /@jridgewell/source-map/0.3.2: resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==} dependencies: - '@jridgewell/gen-mapping': 0.3.1 - '@jridgewell/trace-mapping': 0.3.13 + '@jridgewell/gen-mapping': 0.3.2 + '@jridgewell/trace-mapping': 0.3.14 dev: true /@jridgewell/sourcemap-codec/1.4.13: @@ -2150,8 +2260,8 @@ packages: '@rushstack/node-core-library': 3.49.0 dev: true - /@microsoft/api-extractor/7.28.2: - resolution: {integrity: sha512-sl97erZ5Zh3ov5dvV/rMSt45//dYf7C5Y6PCpIXpFidDYMyRwN+pizZ543g2d8D5/WbthGvsZoYcYSzG7CkjHQ==} + /@microsoft/api-extractor/7.28.4: + resolution: {integrity: sha512-7JeROBGYTUt4/4HPnpMscsQgLzX0OfGTQR2qOQzzh3kdkMyxmiv2mzpuhoMnwbubb1GvPcyFm+NguoqOqkCVaw==} hasBin: true dependencies: '@microsoft/api-extractor-model': 7.21.0 @@ -2453,7 +2563,7 @@ packages: resolution: {integrity: sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==} dependencies: '@babel/parser': 7.18.5 - '@babel/types': 7.18.7 + '@babel/types': 7.18.9 '@types/babel__generator': 7.6.4 '@types/babel__template': 7.4.1 '@types/babel__traverse': 7.17.1 @@ -2462,7 +2572,7 @@ packages: /@types/babel__generator/7.6.4: resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} dependencies: - '@babel/types': 7.18.7 + '@babel/types': 7.18.9 dev: true /@types/babel__standalone/7.1.4: @@ -2477,13 +2587,13 @@ packages: resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} dependencies: '@babel/parser': 7.18.5 - '@babel/types': 7.18.7 + '@babel/types': 7.18.9 dev: true /@types/babel__traverse/7.17.1: resolution: {integrity: sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==} dependencies: - '@babel/types': 7.18.7 + '@babel/types': 7.18.9 dev: true /@types/braces/3.0.1: @@ -2524,8 +2634,8 @@ packages: resolution: {integrity: sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==} dev: true - /@types/estree/0.0.52: - resolution: {integrity: sha512-BZWrtCU0bMVAIliIV+HJO1f1PR41M7NKjfxrFJwwhKI1KwhwOxYw1SXg9ao+CIMt774nFuGiG6eU+udtbEI9oQ==} + /@types/estree/1.0.0: + resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==} dev: true /@types/etag/1.8.1: @@ -2633,8 +2743,8 @@ packages: '@types/node': 17.0.42 dev: true - /@typescript-eslint/eslint-plugin/5.30.4_nnp5j3mtg3i6tzbs733geadfcy: - resolution: {integrity: sha512-xjujQISAIa4HAaos8fcMZXmqkuZqMx6icdxkI88jMM/eNe4J8AuTLYnLK+zdm0mBYLyctdFf//UE4/xFCcQzYQ==} + /@typescript-eslint/eslint-plugin/5.30.6_m6yr5nzxxaufp5er7e5dqljbi4: + resolution: {integrity: sha512-J4zYMIhgrx4MgnZrSDD7sEnQp7FmhKNOaqaOpaoQ/SfdMfRB/0yvK74hTnvH+VQxndZynqs5/Hn4t+2/j9bADg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: '@typescript-eslint/parser': ^5.0.0 @@ -2644,12 +2754,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.30.4_g4cxuhevh5o54harssx6h7xjim - '@typescript-eslint/scope-manager': 5.30.4 - '@typescript-eslint/type-utils': 5.30.4_g4cxuhevh5o54harssx6h7xjim - '@typescript-eslint/utils': 5.30.4_g4cxuhevh5o54harssx6h7xjim + '@typescript-eslint/parser': 5.30.6_sxmbcirybhoxa24uzkr344oiiy + '@typescript-eslint/scope-manager': 5.30.6 + '@typescript-eslint/type-utils': 5.30.6_sxmbcirybhoxa24uzkr344oiiy + '@typescript-eslint/utils': 5.30.6_sxmbcirybhoxa24uzkr344oiiy debug: 4.3.4 - eslint: 8.19.0 + eslint: 8.20.0 functional-red-black-tree: 1.0.1 ignore: 5.2.0 regexpp: 3.2.0 @@ -2660,8 +2770,8 @@ packages: - supports-color dev: true - /@typescript-eslint/parser/5.30.4_g4cxuhevh5o54harssx6h7xjim: - resolution: {integrity: sha512-/ge1HtU63wVoED4VnlU2o+FPFmi017bPYpeSrCmd8Ycsti4VSxXrmcpXXm7JpI4GT0Aa7qviabv1PEp6L5bboQ==} + /@typescript-eslint/parser/5.30.6_sxmbcirybhoxa24uzkr344oiiy: + resolution: {integrity: sha512-gfF9lZjT0p2ZSdxO70Xbw8w9sPPJGfAdjK7WikEjB3fcUI/yr9maUVEdqigBjKincUYNKOmf7QBMiTf719kbrA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -2670,26 +2780,26 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.30.4 - '@typescript-eslint/types': 5.30.4 - '@typescript-eslint/typescript-estree': 5.30.4_typescript@4.6.4 + '@typescript-eslint/scope-manager': 5.30.6 + '@typescript-eslint/types': 5.30.6 + '@typescript-eslint/typescript-estree': 5.30.6_typescript@4.6.4 debug: 4.3.4 - eslint: 8.19.0 + eslint: 8.20.0 typescript: 4.6.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager/5.30.4: - resolution: {integrity: sha512-DNzlQwGSiGefz71JwaHrpcaAX3zYkEcy8uVuan3YMKOa6qeW/y+7SaD8KIsIAruASwq6P+U4BjWBWtM2O+mwBQ==} + /@typescript-eslint/scope-manager/5.30.6: + resolution: {integrity: sha512-Hkq5PhLgtVoW1obkqYH0i4iELctEKixkhWLPTYs55doGUKCASvkjOXOd/pisVeLdO24ZX9D6yymJ/twqpJiG3g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.30.4 - '@typescript-eslint/visitor-keys': 5.30.4 + '@typescript-eslint/types': 5.30.6 + '@typescript-eslint/visitor-keys': 5.30.6 dev: true - /@typescript-eslint/type-utils/5.30.4_g4cxuhevh5o54harssx6h7xjim: - resolution: {integrity: sha512-55cf1dZviwwv+unDB+mF8vZkfta5muTK6bppPvenWWCD7slZZ0DEsXUjZerqy7Rq8s3J4SXdg4rMIY8ngCtTmA==} + /@typescript-eslint/type-utils/5.30.6_sxmbcirybhoxa24uzkr344oiiy: + resolution: {integrity: sha512-GFVVzs2j0QPpM+NTDMXtNmJKlF842lkZKDSanIxf+ArJsGeZUIaeT4jGg+gAgHt7AcQSFwW7htzF/rbAh2jaVA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -2698,22 +2808,22 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/utils': 5.30.4_g4cxuhevh5o54harssx6h7xjim + '@typescript-eslint/utils': 5.30.6_sxmbcirybhoxa24uzkr344oiiy debug: 4.3.4 - eslint: 8.19.0 + eslint: 8.20.0 tsutils: 3.21.0_typescript@4.6.4 typescript: 4.6.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types/5.30.4: - resolution: {integrity: sha512-NTEvqc+Vvu8Q6JeAKryHk2eqLKqsr2St3xhIjhOjQv5wQUBhaTuix4WOSacqj0ONWfKVU12Eug3LEAB95GBkMA==} + /@typescript-eslint/types/5.30.6: + resolution: {integrity: sha512-HdnP8HioL1F7CwVmT4RaaMX57RrfqsOMclZc08wGMiDYJBsLGBM7JwXM4cZJmbWLzIR/pXg1kkrBBVpxTOwfUg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree/5.30.4_typescript@4.6.4: - resolution: {integrity: sha512-V4VnEs6/J9/nNizaA12IeU4SAeEYaiKr7XndLNfV5+3zZSB4hIu6EhHJixTKhvIqA+EEHgBl6re8pivBMLLO1w==} + /@typescript-eslint/typescript-estree/5.30.6_typescript@4.6.4: + resolution: {integrity: sha512-Z7TgPoeYUm06smfEfYF0RBkpF8csMyVnqQbLYiGgmUSTaSXTP57bt8f0UFXstbGxKIreTwQCujtaH0LY9w9B+A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -2721,8 +2831,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.30.4 - '@typescript-eslint/visitor-keys': 5.30.4 + '@typescript-eslint/types': 5.30.6 + '@typescript-eslint/visitor-keys': 5.30.6 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -2733,29 +2843,29 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.30.4_g4cxuhevh5o54harssx6h7xjim: - resolution: {integrity: sha512-a+GQrJzOUhn4WT1mUumXDyam+22Oo4c5K/jnZ+6r/4WTQF3q8e4CsC9PLHb4SnOClzOqo/5GLZWvkE1aa5UGKQ==} + /@typescript-eslint/utils/5.30.6_sxmbcirybhoxa24uzkr344oiiy: + resolution: {integrity: sha512-xFBLc/esUbLOJLk9jKv0E9gD/OH966M40aY9jJ8GiqpSkP2xOV908cokJqqhVd85WoIvHVHYXxSFE4cCSDzVvA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: '@types/json-schema': 7.0.11 - '@typescript-eslint/scope-manager': 5.30.4 - '@typescript-eslint/types': 5.30.4 - '@typescript-eslint/typescript-estree': 5.30.4_typescript@4.6.4 - eslint: 8.19.0 + '@typescript-eslint/scope-manager': 5.30.6 + '@typescript-eslint/types': 5.30.6 + '@typescript-eslint/typescript-estree': 5.30.6_typescript@4.6.4 + eslint: 8.20.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.19.0 + eslint-utils: 3.0.0_eslint@8.20.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/visitor-keys/5.30.4: - resolution: {integrity: sha512-ulKGse3mruSc8x6l8ORSc6+1ORyJzKmZeIaRTu/WpaF/jx3vHvEn5XZUKF9XaVg2710mFmTAUlLcLYLPp/Zf/Q==} + /@typescript-eslint/visitor-keys/5.30.6: + resolution: {integrity: sha512-41OiCjdL2mCaSDi2SvYbzFLlqqlm5v1ZW9Ym55wXKL/Rx6OOB1IbuFGo71Fj6Xy90gJDFTlgOS+vbmtGHPTQQA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.30.4 + '@typescript-eslint/types': 5.30.6 eslint-visitor-keys: 3.3.0 dev: true @@ -2763,11 +2873,11 @@ packages: resolution: {integrity: sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==} dev: false - /@vue/babel-plugin-jsx/1.1.1_@babel+core@7.18.6: + /@vue/babel-plugin-jsx/1.1.1_@babel+core@7.18.9: resolution: {integrity: sha512-j2uVfZjnB5+zkcbc/zsOc0fSNGCMMjaEXP52wdwdIfn0qjFfEYpYZBFKFg+HHnQeJCVrjOeO0YxgaL7DMrym9w==} dependencies: '@babel/helper-module-imports': 7.16.7 - '@babel/plugin-syntax-jsx': 7.16.7_@babel+core@7.18.6 + '@babel/plugin-syntax-jsx': 7.16.7_@babel+core@7.18.9 '@babel/template': 7.16.7 '@babel/traverse': 7.17.10 '@babel/types': 7.17.10 @@ -3789,8 +3899,8 @@ packages: is-what: 3.14.1 dev: true - /core-js/3.23.1: - resolution: {integrity: sha512-wfMYHWi1WQjpgZNC9kAlN4ut04TM9fUTdi7CqIoTVM7yaiOUQTklOzfb+oWH3r9edQcT3F887swuVmxrV+CC8w==} + /core-js/3.23.5: + resolution: {integrity: sha512-7Vh11tujtAZy82da4duVreQysIoO2EvVrur7y6IzZkH1IHPSekuDi8Vuw1+YKjkbfWLRD7Nc9ICQ/sIUDutcyg==} requiresBuild: true dev: false @@ -4590,7 +4700,7 @@ packages: - supports-color dev: true - /eslint-module-utils/2.7.3_baa5opwrycsxtp3dnugww5zmnq: + /eslint-module-utils/2.7.3_bsugbhruclroeiaqnd7gqoy7ya: resolution: {integrity: sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==} engines: {node: '>=4'} peerDependencies: @@ -4608,7 +4718,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.30.4_g4cxuhevh5o54harssx6h7xjim + '@typescript-eslint/parser': 5.30.6_sxmbcirybhoxa24uzkr344oiiy debug: 3.2.7 eslint-import-resolver-node: 0.3.6 find-up: 2.1.0 @@ -4616,18 +4726,18 @@ packages: - supports-color dev: true - /eslint-plugin-es/3.0.1_eslint@8.19.0: + /eslint-plugin-es/3.0.1_eslint@8.20.0: resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==} engines: {node: '>=8.10.0'} peerDependencies: eslint: '>=4.19.1' dependencies: - eslint: 8.19.0 + eslint: 8.20.0 eslint-utils: 2.1.0 regexpp: 3.2.0 dev: true - /eslint-plugin-import/2.26.0_eewxtjj33uq4o73zpcjsegq3l4: + /eslint-plugin-import/2.26.0_y5cwkwncsnk6w3wfynadgn7abe: resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} engines: {node: '>=4'} peerDependencies: @@ -4637,14 +4747,14 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.30.4_g4cxuhevh5o54harssx6h7xjim + '@typescript-eslint/parser': 5.30.6_sxmbcirybhoxa24uzkr344oiiy array-includes: 3.1.5 array.prototype.flat: 1.3.0 debug: 2.6.9 doctrine: 2.1.0 - eslint: 8.19.0 + eslint: 8.20.0 eslint-import-resolver-node: 0.3.6 - eslint-module-utils: 2.7.3_baa5opwrycsxtp3dnugww5zmnq + eslint-module-utils: 2.7.3_bsugbhruclroeiaqnd7gqoy7ya has: 1.0.3 is-core-module: 2.9.0 is-glob: 4.0.3 @@ -4658,14 +4768,14 @@ packages: - supports-color dev: true - /eslint-plugin-node/11.1.0_eslint@8.19.0: + /eslint-plugin-node/11.1.0_eslint@8.20.0: resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==} engines: {node: '>=8.10.0'} peerDependencies: eslint: '>=5.16.0' dependencies: - eslint: 8.19.0 - eslint-plugin-es: 3.0.1_eslint@8.19.0 + eslint: 8.20.0 + eslint-plugin-es: 3.0.1_eslint@8.20.0 eslint-utils: 2.1.0 ignore: 5.2.0 minimatch: 3.1.2 @@ -4696,13 +4806,13 @@ packages: eslint-visitor-keys: 1.3.0 dev: true - /eslint-utils/3.0.0_eslint@8.19.0: + /eslint-utils/3.0.0_eslint@8.20.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: - eslint: 8.19.0 + eslint: 8.20.0 eslint-visitor-keys: 2.1.0 dev: true @@ -4721,8 +4831,8 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint/8.19.0: - resolution: {integrity: sha512-SXOPj3x9VKvPe81TjjUJCYlV4oJjQw68Uek+AM0X4p+33dj2HY5bpTZOgnQHcG2eAm1mtCU9uNMnJi7exU/kYw==} + /eslint/8.20.0: + resolution: {integrity: sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: @@ -4735,7 +4845,7 @@ packages: doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.1.1 - eslint-utils: 3.0.0_eslint@8.19.0 + eslint-utils: 3.0.0_eslint@8.20.0 eslint-visitor-keys: 3.3.0 espree: 9.3.2 esquery: 1.4.0 @@ -5703,7 +5813,7 @@ packages: dev: true /isexe/2.0.0: - resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=} + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true /jiti/1.13.0: @@ -5931,8 +6041,8 @@ packages: engines: {node: '>= 12.13.0'} dev: true - /local-pkg/0.4.1: - resolution: {integrity: sha512-lL87ytIGP2FU5PWwNDo0w3WhIo2gopIAxPg9RxDYF7m4rr5ahuZxP22xnJHIvaLTe4Z9P6uKKY2UHiwyB4pcrw==} + /local-pkg/0.4.2: + resolution: {integrity: sha512-mlERgSPrbxU3BP4qBqAvvwlgW4MTg78iwJdGGnv7kibKjWcJksrG3t6LB5lXI93wXRDvG4NpUgJFmTG4T6rdrg==} engines: {node: '>=14'} dev: true @@ -6382,8 +6492,8 @@ packages: whatwg-url: 5.0.0 dev: false - /node-fetch/3.2.6: - resolution: {integrity: sha512-LAy/HZnLADOVkVPubaxHDft29booGglPFDr2Hw0J1AercRh01UiVFm++KMDnJeH9sHgNB4hsXPii7Sgym/sTbw==} + /node-fetch/3.2.8: + resolution: {integrity: sha512-KtpD1YhGszhntMpBDyp5lyagk8KIMopC1LEb7cQUAh7zcosaX5uK8HnbNb2i3NTQK3sIawCItS0uFC3QzcLHdg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: data-uri-to-buffer: 4.0.0 @@ -6396,11 +6506,6 @@ packages: engines: {node: '>= 6.0.0'} dev: true - /node-forge/1.3.1: - resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} - engines: {node: '>= 6.13.0'} - dev: true - /node-releases/2.0.4: resolution: {integrity: sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==} @@ -6735,8 +6840,8 @@ packages: is-reference: 3.0.0 dev: true - /phoenix/1.6.10: - resolution: {integrity: sha512-KfYAJrrw95JGaOlvmZ+lFJZhSfQmo4SVOj6s175/V8YxqhYGO5EGacdrJxQmJ6uhaK4H3S6b0wkC1T33qU/d8Q==} + /phoenix/1.6.11: + resolution: {integrity: sha512-z/MSg9yY20JhTSj6tKmOYE9p+PuU+FVstYtgBfIZPGNLKhSuV9Zcs9LLLKWeiJ9EUzaXS/QeO8Po4+jJnyNfMw==} dev: false /picocolors/1.0.0: @@ -6789,23 +6894,23 @@ packages: pathe: 0.3.2 dev: true - /playwright-chromium/1.23.1: - resolution: {integrity: sha512-Cx9VkJBFPxSim7qz571aDXU+oXmqYJW2W+Po6eiq2vi/abkH87BtxM/E0tsFJavFMB8ZpBWX1Z+77LctZv3V5w==} + /playwright-chromium/1.23.4: + resolution: {integrity: sha512-aqiOpX76107knxZqydyd0snNHiU6wgGwmQUFA8MEbG6sVjvjF8fS8Uy6n39z9U52pSpRFGPBP8dfkTkXBokkqQ==} engines: {node: '>=14'} hasBin: true requiresBuild: true dependencies: - playwright-core: 1.23.1 + playwright-core: 1.23.4 dev: true - /playwright-core/1.23.1: - resolution: {integrity: sha512-9CXsE0gawph4KXl6oUaa0ehHRySZjHvly4TybcBXDvzK3N3o6L/eZ8Q6iVWUiMn0LLS5bRFxo1qEtOETlYJxjw==} + /playwright-core/1.23.4: + resolution: {integrity: sha512-h5V2yw7d8xIwotjyNrkLF13nV9RiiZLHdXeHo+nVJIYGVlZ8U2qV0pMxNJKNTvfQVT0N8/A4CW6/4EW2cOcTiA==} engines: {node: '>=14'} hasBin: true dev: true - /pnpm/7.5.0: - resolution: {integrity: sha512-sb9wJNyx/d8l3Gze2jI1y8BGNbb/ga+JT3SrGNiH+C5KbtZ4wmgePBWGjaiGugcpT9+vQ5MO//+QlVWhMCpedQ==} + /pnpm/7.5.2: + resolution: {integrity: sha512-tTLvMnu1zIAWrD87Q/Dgw0+d71Brhlm+aM62KkDr/EPNZyA7dBIsu7tS9pNfRSvwgVF7V1Dhc8jJLAsTNTXnDQ==} engines: {node: '>=14.6'} hasBin: true dev: true @@ -6830,7 +6935,7 @@ packages: camelcase-css: 2.0.1 postcss: 8.4.14 - /postcss-load-config/3.1.4_i7duc3lt6p42geuj2nwruihc6u: + /postcss-load-config/3.1.4_pe6iykxod2v7i2uk6okjazxzki: resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} engines: {node: '>= 10'} peerDependencies: @@ -6844,7 +6949,7 @@ packages: dependencies: lilconfig: 2.0.5 postcss: 8.4.14 - ts-node: 10.8.2 + ts-node: 10.9.1 yaml: 1.10.2 dev: false @@ -7978,8 +8083,8 @@ packages: resolution: {integrity: sha512-hqTN6kW+pN6/qro6G9OZ7ceDQOcYno020zBQKpZQLsJhYTDMCMNfXi/Y8duF5iW+4WWZr42ry0MMkcRGpbwG2A==} dev: false - /tailwindcss/3.1.4: - resolution: {integrity: sha512-NrxbFV4tYsga/hpWbRyUfIaBrNMXDxx5BsHgBS4v5tlyjf+sDsgBg5m9OxjrXIqAS/uR9kicxLKP+bEHI7BSeQ==} + /tailwindcss/3.1.6: + resolution: {integrity: sha512-7skAOY56erZAFQssT1xkpk+kWt2NrO45kORlxFPXUt3CiGsVPhH1smuH5XoDH6sGPXLyBv+zgCKA2HWBsgCytg==} engines: {node: '>=12.13.0'} hasBin: true dependencies: @@ -8008,8 +8113,8 @@ packages: transitivePeerDependencies: - ts-node - /tailwindcss/3.1.4_ts-node@10.8.2: - resolution: {integrity: sha512-NrxbFV4tYsga/hpWbRyUfIaBrNMXDxx5BsHgBS4v5tlyjf+sDsgBg5m9OxjrXIqAS/uR9kicxLKP+bEHI7BSeQ==} + /tailwindcss/3.1.6_ts-node@10.9.1: + resolution: {integrity: sha512-7skAOY56erZAFQssT1xkpk+kWt2NrO45kORlxFPXUt3CiGsVPhH1smuH5XoDH6sGPXLyBv+zgCKA2HWBsgCytg==} engines: {node: '>=12.13.0'} hasBin: true dependencies: @@ -8029,7 +8134,7 @@ packages: postcss: 8.4.14 postcss-import: 14.1.0_postcss@8.4.14 postcss-js: 4.0.0_postcss@8.4.14 - postcss-load-config: 3.1.4_i7duc3lt6p42geuj2nwruihc6u + postcss-load-config: 3.1.4_pe6iykxod2v7i2uk6okjazxzki postcss-nested: 5.0.6_postcss@8.4.14 postcss-selector-parser: 6.0.10 postcss-value-parser: 4.2.0 @@ -8064,8 +8169,8 @@ packages: uuid: 3.4.0 dev: true - /terser/5.14.1: - resolution: {integrity: sha512-+ahUAE+iheqBTDxXhTisdA8hgvbEG1hHOQ9xmNjeUJSoi6DU/gMrKNcfZjHkyY6Alnuyc+ikYJaxxfHkT3+WuQ==} + /terser/5.14.2: + resolution: {integrity: sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==} engines: {node: '>=10'} hasBin: true dependencies: @@ -8109,13 +8214,13 @@ packages: resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==} dev: false - /tinypool/0.2.1: - resolution: {integrity: sha512-HFU5ZYVq3wBfhSaf8qdqGsneaqXm0FgJQpoUlJbVdHpRLzm77IneKAD3RjzJWZvIv0YpPB9S7LUW53f6BE6ZSg==} + /tinypool/0.2.4: + resolution: {integrity: sha512-Vs3rhkUH6Qq1t5bqtb816oT+HeJTXfwt2cbPH17sWHIYKTotQIFPk3tf2fgqRrVyMDVOc1EnPgzIxfIulXVzwQ==} engines: {node: '>=14.0.0'} dev: true - /tinyspy/0.3.3: - resolution: {integrity: sha512-gRiUR8fuhUf0W9lzojPf1N1euJYA30ISebSfgca8z76FOvXtVXqd5ojEIaKLWbDQhAaC3ibxZIjqbyi4ybjcTw==} + /tinyspy/1.0.0: + resolution: {integrity: sha512-FI5B2QdODQYDRjfuLF+OrJ8bjWRMCXokQPcwKm0W3IzcbUmBNv536cQc7eXGoAuXphZwgx1DFbqImwzz08Fnhw==} engines: {node: '>=14.0.0'} dev: true @@ -8165,8 +8270,8 @@ packages: utf8-byte-length: 1.0.4 dev: true - /ts-node/10.8.2: - resolution: {integrity: sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==} + /ts-node/10.9.1: + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: '@swc/core': '>=1.2.50' @@ -8231,13 +8336,13 @@ packages: typescript: 4.6.4 dev: true - /tsx/3.7.1: - resolution: {integrity: sha512-dwl1GBdkwVQ9zRxTmETGi+ck8pewNm2QXh+HK6jHxdHmeCjfCL+Db3b4VX/dOMDSS2hle1j5LzQoo8OpVXu6XQ==} + /tsx/3.8.0: + resolution: {integrity: sha512-PcvTwRXTm6hDWfPihA4n5WW/9SmgFNxKaDKqvLLG+FKNEPA4crsipChzC7PVozPtdOaMfR5QctDlkC/hKoIsxw==} hasBin: true dependencies: - '@esbuild-kit/cjs-loader': 2.3.0 - '@esbuild-kit/core-utils': 2.0.2 - '@esbuild-kit/esm-loader': 2.4.0 + '@esbuild-kit/cjs-loader': 2.3.1 + '@esbuild-kit/core-utils': 2.1.0 + '@esbuild-kit/esm-loader': 2.4.1 optionalDependencies: fsevents: 2.3.2 dev: true @@ -8319,8 +8424,8 @@ packages: resolution: {integrity: sha512-kMBmblijHJXyOpKzgDhKx9INYU4u4E1RPMB0HqmKSgWG8vEcf3exEfLh4FFfzd3xdQOw9EuIy/cP0akY6rHopQ==} dev: true - /ufo/0.8.4: - resolution: {integrity: sha512-/+BmBDe8GvlB2nIflWasLLAInjYG0bC9HRnfEpNi4sw77J2AJNnEVnTDReVrehoh825+Q/evF3THXTAweyam2g==} + /ufo/0.8.5: + resolution: {integrity: sha512-e4+UtA5IRO+ha6hYklwj6r7BjiGMxS0O+UaSg9HbaTefg4kMkzj4tXzEBajRR+wkxf+golgAWKzLbytCUDMJAA==} dev: true /uglify-js/3.16.1: @@ -8395,7 +8500,7 @@ packages: dependencies: '@babel/core': 7.18.5 '@babel/standalone': 7.18.5 - '@babel/types': 7.18.7 + '@babel/types': 7.18.9 scule: 0.2.1 transitivePeerDependencies: - supports-color @@ -8477,8 +8582,8 @@ packages: - react-dom dev: true - /vitest/0.17.0: - resolution: {integrity: sha512-5YO9ubHo0Zg35mea3+zZAr4sCku32C3usvIH5COeJB48TZV/R0J9aGNtGOOqEWZYfOKP0pGZUvTokne3x/QEFg==} + /vitest/0.18.1: + resolution: {integrity: sha512-4F/1K/Vn4AvJwe7i2YblR02PT5vMKcw9KN4unDq2KD0YcSxX0B/6D6Qu9PJaXwVuxXMFTQ5ovd4+CQaW3bwofA==} engines: {node: '>=v14.16.0'} hasBin: true peerDependencies: @@ -8504,9 +8609,9 @@ packages: '@types/node': 17.0.42 chai: 4.3.6 debug: 4.3.4 - local-pkg: 0.4.1 - tinypool: 0.2.1 - tinyspy: 0.3.3 + local-pkg: 0.4.2 + tinypool: 0.2.4 + tinyspy: 1.0.0 vite: link:packages/vite transitivePeerDependencies: - supports-color @@ -8540,8 +8645,8 @@ packages: vue: 3.2.37 dev: true - /vue-router/4.0.16_vue@3.2.37: - resolution: {integrity: sha512-JcO7cb8QJLBWE+DfxGUL3xUDOae/8nhM1KVdnudadTAORbuxIC/xAydC5Zr/VLHUDQi1ppuTF5/rjBGzgzrJNA==} + /vue-router/4.1.2_vue@3.2.37: + resolution: {integrity: sha512-5BP1qXFncVRwgV/XnqzsKApdMjQPqWIpoUBdL1ynz8HyLxIX/UDAx7Ql2BjmA5CXT/p61JfZvkpiFWFpaqcfag==} peerDependencies: vue: ^3.2.0 dependencies: @@ -8691,8 +8796,8 @@ packages: optional: true dev: true - /ws/8.8.0: - resolution: {integrity: sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==} + /ws/8.8.1: + resolution: {integrity: sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -8808,6 +8913,12 @@ packages: vue: 3.2.37 dev: false + file:playground/import-assertion/import-assertion-dep: + resolution: {directory: playground/import-assertion/import-assertion-dep, type: directory} + name: '@vitejs/import-assertion-dep' + version: 0.0.0 + dev: false + file:playground/json/json-module: resolution: {directory: playground/json/json-module, type: directory} name: json-module @@ -8939,6 +9050,20 @@ packages: version: 0.0.0 dev: false + file:playground/ssr-deps/external-entry: + resolution: {directory: playground/ssr-deps/external-entry, type: directory} + name: external-entry + version: 0.0.0 + dev: false + + file:playground/ssr-deps/external-using-external-entry: + resolution: {directory: playground/ssr-deps/external-using-external-entry, type: directory} + name: external-using-external-entry + version: 0.0.0 + dependencies: + external-entry: file:playground/ssr-deps/external-entry + dev: false + file:playground/ssr-deps/forwarded-export: resolution: {directory: playground/ssr-deps/forwarded-export, type: directory} name: forwarded-export diff --git a/scripts/releaseUtils.ts b/scripts/releaseUtils.ts index a4394c01381e1e..f4426bef834b69 100644 --- a/scripts/releaseUtils.ts +++ b/scripts/releaseUtils.ts @@ -226,8 +226,9 @@ export async function logRecentCommits(pkgName: string): Promise { } export async function updateTemplateVersions(): Promise { - const viteVersion = (await fs.readJSON('../packages/vite/package.json')) - .version + const viteVersion = ( + await fs.readJSON(path.resolve(__dirname, '../packages/vite/package.json')) + ).version if (/beta|alpha|rc/.test(viteVersion)) return const dir = path.resolve(__dirname, '../packages/create-vite') @@ -241,7 +242,21 @@ export async function updateTemplateVersions(): Promise { pkg.devDependencies.vite = `^` + viteVersion if (template.startsWith('template-vue')) { pkg.devDependencies['@vitejs/plugin-vue'] = - `^` + (await fs.readJSON('../packages/plugin-vue/package.json')).version + `^` + + ( + await fs.readJSON( + path.resolve(__dirname, '../packages/plugin-vue/package.json') + ) + ).version + } + if (template.startsWith('template-react')) { + pkg.devDependencies['@vitejs/plugin-react'] = + `^` + + ( + await fs.readJSON( + path.resolve(__dirname, '../packages/plugin-react/package.json') + ) + ).version } writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n') }