diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3954ca49c11479..cde7dfb03825ed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,8 @@ on: - main - release/* - feat/* + - fix/* + - perf/* pull_request: workflow_dispatch: @@ -36,7 +38,7 @@ jobs: name: "Build&Test: node-${{ matrix.node_version }}, ${{ matrix.os }}" steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install pnpm uses: pnpm/action-setup@v2 @@ -44,7 +46,7 @@ jobs: version: 6 - name: Set node version to ${{ matrix.node_version }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: node-version: ${{ matrix.node_version }} cache: "pnpm" @@ -72,7 +74,7 @@ jobs: runs-on: ubuntu-latest name: "Lint: node-16, ubuntu-latest" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 @@ -82,7 +84,7 @@ jobs: version: 6 - name: Set node version to 16 - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: node-version: 16 cache: "pnpm" diff --git a/.github/workflows/lock-closed-issues.yml b/.github/workflows/lock-closed-issues.yml index e20c3e3c8e8138..1f24f316952ea0 100644 --- a/.github/workflows/lock-closed-issues.yml +++ b/.github/workflows/lock-closed-issues.yml @@ -11,11 +11,11 @@ jobs: action: runs-on: ubuntu-latest steps: - - uses: dessant/lock-threads@v2 + - uses: dessant/lock-threads@v3 with: github-token: ${{ secrets.GITHUB_TOKEN }} - issue-lock-inactive-days: "14" - #issue-lock-comment: | + issue-inactive-days: "14" + #issue-comment: | # This issue has been locked since it has been closed for more than 14 days. # # If you have found a concrete bug or regression related to it, please open a new [bug report](https://github.com/vitejs/vite/issues/new/choose) with a reproduction against the latest Vite version. If you have any other comments you should join the chat at [Vite Land](https://chat.vitejs.dev) or create a new [discussion](https://github.com/vitejs/vite/discussions). diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index eb8f4513707872..c58c28adac7b40 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,7 +15,7 @@ jobs: environment: Release steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install pnpm uses: pnpm/action-setup@v2 @@ -23,7 +23,7 @@ jobs: version: 6 - name: Set node version to 16.x - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: node-version: 16.x registry-url: https://registry.npmjs.org/ diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml index f9d5b8de30bec9..21af4792d4741a 100644 --- a/.github/workflows/release-tag.yml +++ b/.github/workflows/release-tag.yml @@ -13,7 +13,7 @@ jobs: release: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Get pkgName for tag id: tag diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000000000..4abbb42e5ef159 --- /dev/null +++ b/.npmrc @@ -0,0 +1,7 @@ +hoist-pattern[]=*eslint* +hoist-pattern[]=*babel* +hoist-pattern[]=*jest* +hoist-pattern[]=@emotion/* +hoist-pattern[]=postcss +hoist-pattern[]=pug +hoist-pattern[]=source-map-support diff --git a/.prettierignore b/.prettierignore index 1692b9d26cfa20..c624a3a21eecfe 100644 --- a/.prettierignore +++ b/.prettierignore @@ -10,3 +10,4 @@ pnpm-lock.yaml pnpm-workspace.yaml packages/playground/tsconfig-json-load-error/has-error/tsconfig.json packages/playground/html/invalid.html +packages/playground/worker/classic-worker.js diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5b8f1fed7192c3..b105499159bebb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,10 +10,42 @@ To develop and test the core `vite` package: 1. Run `pnpm i` in Vite's root folder -2. Go to `packages/vite` and run `pnpm run dev`. This starts `rollup` in watch mode. +2. Run `pnpm run build` in Vite's root folder. + +3. If you are developing Vite itself, you can go to `packages/vite` and run `pnpm run dev` to automatically rebuild Vite whenever you change its code. You can alternatively use [Vite.js Docker Dev](https://github.com/nystudio107/vitejs-docker-dev) for a containerized Docker setup for Vite.js development. +## 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. + +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. + +3. Click on the "JavaScript Debug Terminal" button. + +4. It will open a terminal, then go to `packages/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... + +### Debugging errors in Jest tests using Playwright (Chromium) + +Some errors are masked and hidden away because of the layers of abstraction and sandboxed nature added by Jest, 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 `scripts/jestPerTestSetup.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 -- --runInBand resolve`. + +1. 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. + +1. Focusing the Chomium 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. + ## 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`: @@ -37,6 +69,8 @@ And re-run `pnpm install` to link the package. Each package under `packages/playground/` contains a `__tests__` directory. The tests are run using [Jest](https://jestjs.io/) + [Playwright](https://playwright.dev/) with custom integrations to make writing tests simple. The detailed setup is inside `jest.config.js` and `scripts/jest*` 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). + Each test can be run under either dev server mode or build mode. - `pnpm test` by default runs every test in both serve and build mode. @@ -195,7 +229,7 @@ The english docs are embedded in the main Vite repo, to allow contributors to wo 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. + - 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` @@ -204,7 +238,7 @@ The english docs are embedded in the main Vite repo, to allow contributors to wo - 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. +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. diff --git a/docs/blog/announcing-vite2.md b/docs/blog/announcing-vite2.md index 0bf520dfdfcb9a..0007205debba4a 100644 --- a/docs/blog/announcing-vite2.md +++ b/docs/blog/announcing-vite2.md @@ -34,7 +34,7 @@ The [programmatic API](https://vitejs.dev/guide/api-javascript.html) has also be ### esbuild Powered Dep Pre-Bundling -Since Vite is a native ESM dev server, it pre-bundles dependencies to reduce the number browser requests and handle CommonJS to ESM conversion. Previously Vite did this using Rollup, and in 2.0 it now uses `esbuild` which results in 10-100x faster dependency pre-bundling. As a reference, cold-booting a test app with heavy dependencies like React Material UI previously took 28 seconds on an M1-powered Macbook Pro and now takes ~1.5 seconds. Expect similar improvements if you are switching from a traditional bundler based setup. +Since Vite is a native ESM dev server, it pre-bundles dependencies to reduce the number browser requests and handle CommonJS to ESM conversion. Previously Vite did this using Rollup, and in 2.0 it now uses `esbuild` which results in 10-100x faster dependency pre-bundling. As a reference, cold-booting a test app with heavy dependencies like React Material UI previously took 28 seconds on an M1-powered MacBook Pro and now takes ~1.5 seconds. Expect similar improvements if you are switching from a traditional bundler based setup. ### First-class CSS Support diff --git a/docs/config/index.md b/docs/config/index.md index 88c2ab62ac3b92..5b618364cf2b3a 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -27,7 +27,8 @@ You can also explicitly specify a config file to use with the `--config` CLI opt vite --config my-config.js ``` -Note that Vite will replace `__filename`, `__dirname`, and `import.meta.url`. Using these as variable names will result in an error: +::: tip NOTE +Vite will replace `__filename`, `__dirname`, and `import.meta.url` in **CommonJS** and **TypeScript** config files. Using these as variable names will result in an error: ```js const __filename = "value" @@ -35,6 +36,8 @@ const __filename = "value" const "path/vite.config.js" = "value" ``` +::: + ### Config Intellisense Since Vite ships with TypeScript typings, you can leverage your IDE's intellisense with jsdoc type hints: @@ -96,6 +99,22 @@ export default defineConfig(async ({ command, mode }) => { }) ``` +### Environment Variables + +Vite doesn't load `.env` files by default as the files to load can only be determined after evaluating the Vite config, for example, the `root` and `envDir` options affects the loading behaviour. However, you can use the exported `loadEnv` helper to load the specific `.env` file if needed. + +```js +import { defineConfig, loadEnv } from 'vite' + +export default defineConfig(({ command, mode }) => { + // Load env file based on `mode` in the current working directory + const env = loadEnv(mode, process.cwd()) + return { + // build specific config + } +}) +``` + ## Shared Options ### root @@ -137,11 +156,15 @@ export default defineConfig(async ({ command, mode }) => { - Starting from `2.0.0-beta.70`, string values will be used as raw expressions, so if defining a string constant, it needs to be explicitly quoted (e.g. with `JSON.stringify`). + - To be consistent with [esbuild behavior](https://esbuild.github.io/api/#define), expressions must either be a JSON object (null, boolean, number, string, array, or object) or a single identifier. + - Replacements are performed only when the match is surrounded by word boundaries (`\b`). + ::: warning Because it's implemented as straightforward text replacements without any syntax analysis, we recommend using `define` for CONSTANTS only. For example, `process.env.FOO` and `__APP_VERSION__` are good fits. But `process` or `global` should not be put into this option. Variables can be shimmed or polyfilled instead. + ::: ::: tip NOTE For TypeScript users, make sure to add the type declarations in the `env.d.ts` or `vite-env.d.ts` file to get type checks and Intellisense. @@ -223,6 +246,10 @@ export default defineConfig(async ({ command, mode }) => { Vite has a list of "allowed conditions" and will match the first condition that is in the allowed list. The default allowed conditions are: `import`, `module`, `browser`, `default`, and `production/development` based on current mode. The `resolve.conditions` config option allows specifying additional allowed conditions. + :::warning Resolving subpath exports + Export keys ending with "/" is deprecated by Node and may not work well. Please contact the package author to use [`*` subpath patterns](https://nodejs.org/api/packages.html#package-entry-points) instead. + ::: + ### resolve.mainFields - **Type:** `string[]` @@ -277,7 +304,7 @@ export default defineConfig(async ({ command, mode }) => { - **Type:** `string | (postcss.ProcessOptions & { plugins?: postcss.Plugin[] })` - Inline PostCSS config (expects the same format as `postcss.config.js`), or a custom path to search PostCSS config from (default is project root). The search is done using [postcss-load-config](https://github.com/postcss/postcss-load-config). + Inline PostCSS config (expects the same format as `postcss.config.js`), or a custom directory to search PostCSS config from (default is project root). The search is done using [postcss-load-config](https://github.com/postcss/postcss-load-config) and only the supported config file names are loaded. Note if an inline config is provided, Vite will not search for other PostCSS config sources. @@ -285,7 +312,7 @@ export default defineConfig(async ({ command, mode }) => { - **Type:** `Record` - Specify options to pass to CSS pre-processors. Example: + Specify options to pass to CSS pre-processors. The file extensions are used as keys for the options. Example: ```js export default defineConfig({ @@ -293,12 +320,23 @@ export default defineConfig(async ({ command, mode }) => { preprocessorOptions: { scss: { additionalData: `$injectedColor: orange;` + }, + styl: { + additionalData: `$injectedColor ?= orange` } } } }) ``` +### css.devSourcemap + +- **Experimental** +- **Type:** `boolean` +- **Default:** `false` + + Whether to enable sourcemaps during dev. + ### json.namedExports - **Type:** `boolean` @@ -319,7 +357,7 @@ export default defineConfig(async ({ command, mode }) => { - **Type:** `ESBuildOptions | false` - `ESBuildOptions` extends [ESbuild's own transform options](https://esbuild.github.io/api/#transform-api). The most common use case is customizing JSX: + `ESBuildOptions` extends [esbuild's own transform options](https://esbuild.github.io/api/#transform-api). The most common use case is customizing JSX: ```js export default defineConfig({ @@ -330,9 +368,9 @@ export default defineConfig(async ({ command, mode }) => { }) ``` - By default, ESBuild is applied to `ts`, `jsx` and `tsx` files. You can customize this with `esbuild.include` and `esbuild.exclude`, both of which expect type of `string | RegExp | (string | RegExp)[]`. + By default, esbuild is applied to `ts`, `jsx` and `tsx` files. You can customize this with `esbuild.include` and `esbuild.exclude`, which can be a regex, a [picomatch](https://github.com/micromatch/picomatch#globbing-features) pattern, or an array of either. - In addition, you can also use `esbuild.jsxInject` to automatically inject JSX helper imports for every file transformed by ESBuild: + In addition, you can also use `esbuild.jsxInject` to automatically inject JSX helper imports for every file transformed by esbuild: ```js export default defineConfig({ @@ -342,14 +380,14 @@ export default defineConfig(async ({ command, mode }) => { }) ``` - Set to `false` to disable ESbuild transforms. + Set to `false` to disable esbuild transforms. ### assetsInclude - **Type:** `string | RegExp | (string | RegExp)[]` - **Related:** [Static Asset Handling](/guide/assets) - Specify additional [picomatch patterns](https://github.com/micromatch/picomatch) to be treated as static assets so that: + Specify additional [picomatch patterns](https://github.com/micromatch/picomatch#globbing-features) to be treated as static assets so that: - They will be excluded from the plugin transform pipeline when referenced from HTML or directly requested over `fetch` or XHR. @@ -499,6 +537,12 @@ export default defineConfig(async ({ command, mode }) => { Configure CORS for the dev server. This is enabled by default and allows any origin. Pass an [options object](https://github.com/expressjs/cors) to fine tune the behavior or `false` to disable. +### server.headers + +- **Type:** `OutgoingHttpHeaders` + + Specify server response headers. + ### server.force - **Type:** `boolean` @@ -516,7 +560,7 @@ export default defineConfig(async ({ command, mode }) => { `clientPort` is an advanced option that overrides the port only on the client side, allowing you to serve the websocket on a different port than the client code looks for it on. Useful if you're using an SSL proxy in front of your dev server. - When using `server.middlewareMode` or `server.https`, assigning `server.hmr.server` to your HTTP(S) server will process HMR connection requests through your server. This can be helpful when using self-signed certificates or when you want to expose Vite over a network on a single port. + If specifying `server.hmr.server`, Vite will process HMR connection requests through the provided server. If not in middleware mode, Vite will attempt to process HMR connection requests through the existing server. This can be helpful when using self-signed certificates or when you want to expose Vite over a network on a single port. ### server.watch @@ -580,6 +624,12 @@ async function createServer() { createServer() ``` +### server.base + +- **Type:** `string | undefined` + + Prepend this folder to http requests, for use when proxying vite as a subfolder. Should start and end with the `/` character. + ### server.fs.strict - **Type:** `boolean` @@ -799,7 +849,7 @@ export default defineConfig({ - **Type:** `boolean | 'terser' | 'esbuild'` - **Default:** `'esbuild'` - Set to `false` to disable minification, or specify the minifier to use. The default is [Esbuild](https://github.com/evanw/esbuild) which is 20 ~ 40x faster than terser and only 1 ~ 2% worse compression. [Benchmarks](https://github.com/privatenumber/minification-benchmarks) + Set to `false` to disable minification, or specify the minifier to use. The default is [esbuild](https://github.com/evanw/esbuild) which is 20 ~ 40x faster than terser and only 1 ~ 2% worse compression. [Benchmarks](https://github.com/privatenumber/minification-benchmarks) Note the `build.minify` option is not available when using the `'es'` format in lib mode. @@ -923,9 +973,9 @@ export default defineConfig({ - **Type:** `string | string[]` - 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. + By default, Vite will crawl all your `.html` files to detect dependencies that need to be pre-bundled (ignoring `node_modules`, `build.outDir`, `__tests__` and `coverage`). 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](https://github.com/mrmlnc/fast-glob#basic-syntax) or array of patterns that are relative from Vite project root. This will overwrite default entries inference. + If neither of these fit your needs, you can specify custom entries using this option - the value should be a [fast-glob pattern](https://github.com/mrmlnc/fast-glob#basic-syntax) or array of patterns that are relative from Vite project root. This will overwrite default entries inference. Only `node_modules` and `build.outDir` folders will be ignored by default when `optimizeDeps.entries` is explicitily defined. If other folders needs to be ignored, you can use an ignore pattern as part of the entries list, marked with an initial `!`. ### optimizeDeps.exclude diff --git a/docs/guide/api-hmr.md b/docs/guide/api-hmr.md index f4ddf59d8abcd1..46eabab04e8868 100644 --- a/docs/guide/api-hmr.md +++ b/docs/guide/api-hmr.md @@ -123,3 +123,11 @@ The following HMR events are dispatched by Vite automatically: - `'vite:error'` when an error occurs (e.g. syntax error) Custom HMR events can also be sent from plugins. See [handleHotUpdate](./api-plugin#handlehotupdate) for more details. + +## `hot.send(event, data)` + +Send custom events back to Vite's dev server. + +If called before connected, the data will be buffered and sent once the connection is established. + +See [Client-server Communication](/guide/api-plugin.html#client-server-communication) for more details. diff --git a/docs/guide/api-javascript.md b/docs/guide/api-javascript.md index 1651923c06cdcb..0128be26bd92ba 100644 --- a/docs/guide/api-javascript.md +++ b/docs/guide/api-javascript.md @@ -1,6 +1,6 @@ # JavaScript API -Vite's JavaScript APIs are fully typed, and it's recommended to use TypeScript or enable JS type checking in VSCode to leverage the intellisense and validation. +Vite's JavaScript APIs are fully typed, and it's recommended to use TypeScript or enable JS type checking in VS Code to leverage the intellisense and validation. ## `createServer` @@ -94,7 +94,7 @@ interface ViteDevServer { */ ssrLoadModule( url: string, - options?: { isolated?: boolean } + options?: { fixStacktrace?: boolean } ): Promise> /** * Fix ssr error stacktrace. diff --git a/docs/guide/api-plugin.md b/docs/guide/api-plugin.md index 01b42980197473..4a5b1c07c7893e 100644 --- a/docs/guide/api-plugin.md +++ b/docs/guide/api-plugin.md @@ -458,7 +458,7 @@ In general, as long as a Rollup plugin fits the following criteria then it shoul - It doesn't use the [`moduleParsed`](https://rollupjs.org/guide/en/#moduleparsed) hook. - It doesn't have strong coupling between bundle-phase hooks and output-phase hooks. -If a Rollup plugin only makes sense for the build phase, then it can be specified under `build.rollupOptions.plugins` instead. +If a Rollup plugin only makes sense for the build phase, then it can be specified under `build.rollupOptions.plugins` instead. It will work the same as a Vite plugin with `enforce: 'post'` and `apply: 'build'`. You can also augment an existing Rollup plugin with Vite-only properties: @@ -480,7 +480,7 @@ export default defineConfig({ Check out [Vite Rollup Plugins](https://vite-rollup-plugins.patak.dev) for a list of compatible official Rollup plugins with usage instructions. -## Path normalization +## Path Normalization Vite normalizes paths while resolving ids to use POSIX separators ( / ) while preserving the volume in Windows. On the other hand, Rollup keeps resolved paths untouched by default, so resolved ids have win32 separators ( \\ ) in Windows. However, Rollup plugins use a [`normalizePath` utility function](https://github.com/rollup/plugins/tree/master/packages/pluginutils#normalizepath) from `@rollup/pluginutils` internally, which converts separators to POSIX before performing comparisons. This means that when these plugins are used in Vite, the `include` and `exclude` config pattern and other similar paths against resolved ids comparisons work correctly. @@ -492,3 +492,87 @@ import { normalizePath } from 'vite' normalizePath('foo\\bar') // 'foo/bar' normalizePath('foo/bar') // 'foo/bar' ``` + +## Client-server Communication + +Since Vite 2.9, we provide some utilities for plugins to help handle the communication with clients. + +### Server to Client + +On the plugin side, we could use `server.ws.send` to broadcast events to all the clients: + +```js +// vite.config.js +export default defineConfig({ + plugins: [ + { + // ... + configureServer(server) { + server.ws.send('my:greetings', { msg: 'hello' }) + } + } + ] +}) +``` + +::: tip NOTE +We recommend **alway prefixing** your event names to avoid collisions with other plugins. +::: + +On the client side, use [`hot.on`](/guide/api-hmr.html#hot-on-event-cb) to listen to the events: + +```ts +// client side +if (import.meta.hot) { + import.meta.hot.on('my:greetings', (data) => { + console.log(data.msg) // hello + }) +} +``` + +### Client to Server + +To send events from the client to the server, we can use [`hot.send`](/guide/api-hmr.html#hot-send-event-payload): + +```ts +// client side +if (import.meta.hot) { + import.meta.hot.send('my:from-client', { msg: 'Hey!' }) +} +``` + +Then use `server.ws.on` and listen to the events on the server side: + +```js +// vite.config.js +export default defineConfig({ + plugins: [ + { + // ... + configureServer(server) { + server.ws.on('my:from-client', (data, client) => { + console.log('Message from client:', data.msg) // Hey! + // reply only to the client (if needed) + client.send('my:ack', { msg: 'Hi! I got your message!' }) + }) + } + } + ] +}) +``` + +### TypeScript for Custom Events + +It is possible to type custom events by extending the `CustomEventMap` interface: + +```ts +// events.d.ts +import 'vite/types/customEvent' + +declare module 'vite/types/customEvent' { + interface CustomEventMap { + 'custom:foo': { msg: string } + // 'event-key': payload + } +} +``` diff --git a/docs/guide/assets.md b/docs/guide/assets.md index fd5aa46f49467f..53ac153f9465bd 100644 --- a/docs/guide/assets.md +++ b/docs/guide/assets.md @@ -103,8 +103,13 @@ function getImageUrl(name) { } ``` -During the production build, Vite will perform necessary transforms so that the URLs still point to the correct location even after bundling and asset hashing. +During the production build, Vite will perform necessary transforms so that the URLs still point to the correct location even after bundling and asset hashing. However, the URL string must be static so it can be analyzed, otherwise the code will be left as is, which can cause runtime errors if `build.target` does not support `import.meta.url` -::: warning Note: Does not work with SSR +```js +// Vite will not transform this +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. ::: diff --git a/docs/guide/backend-integration.md b/docs/guide/backend-integration.md index a30831e735fff7..55a4b87f1ac481 100644 --- a/docs/guide/backend-integration.md +++ b/docs/guide/backend-integration.md @@ -33,7 +33,6 @@ 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 1dff97bf5fb243..822374e8d0ab2c 100644 --- a/docs/guide/build.md +++ b/docs/guide/build.md @@ -43,6 +43,20 @@ module.exports = defineConfig({ For example, you can specify multiple Rollup outputs with plugins that are only applied during build. +## Chunking Strategy + +You can configure how chunks are split using `build.rollupOptions.output.manualChunks` (see [Rollup docs](https://rollupjs.org/guide/en/#outputmanualchunks)). Until Vite 2.8, the default chunking strategy divided the chunks into `index` and `vendor`. It is a good strategy for some SPAs, but it is hard to provide a general solution for every Vite target use case. From Vite 2.9, `manualChunks` is no longer modified by default. You can continue to use the Split Vendor Chunk strategy by adding the `splitVendorChunkPlugin` in your config file: + +```js +// vite.config.js +import { splitVendorChunkPlugin } from 'vite' +module.exports = defineConfig({ + plugins: [splitVendorChunkPlugin()] +}) +``` + +This strategy is also provided as a `splitVendorChunk({ cache: SplitVendorChunkCache })` factory, in case composition with custom logic is needed. `cache.reset()` needs to be called at `buildStart` for build watch mode to work correctly in this case. + ## Rebuild on files changes You can enable rollup watcher with `vite build --watch`. Or, you can directly adjust the underlying [`WatcherOptions`](https://rollupjs.org/guide/en/#watch-options) via `build.watch`: @@ -58,6 +72,8 @@ module.exports = defineConfig({ }) ``` +With the `--watch` flag enabled, changes to the `vite.config.js`, as well as any files to be bundled, will trigger a rebuild. + ## Multi-Page App Suppose you have the following source code structure: @@ -130,6 +146,15 @@ module.exports = defineConfig({ }) ``` +The entry file would contain exports that can be imported by users of your package: + +```js +// lib/main.js +import Foo from './Foo.vue' +import Bar from './Bar.vue' +export { Foo, Bar } +``` + Running `vite build` with this config uses a Rollup preset that is oriented towards shipping libraries and produces two bundle formats: `es` and `umd` (configurable via `build.lib`): ``` diff --git a/docs/guide/dep-pre-bundling.md b/docs/guide/dep-pre-bundling.md index 6864ef55899eba..0afce072e9fcc3 100644 --- a/docs/guide/dep-pre-bundling.md +++ b/docs/guide/dep-pre-bundling.md @@ -3,10 +3,10 @@ When you run `vite` for the first time, you may notice this message: ``` -Optimizable dependencies detected: -react, react-dom -Pre-bundling them to speed up dev server page load... -(this will be run only when your dependencies have changed) +Pre-bundling dependencies: + react + react-dom +(this will be run only when your dependencies or config have changed) ``` ## The Why @@ -28,6 +28,10 @@ This is Vite performing what we call "dependency pre-bundling". This process ser By pre-bundling `lodash-es` into a single module, we now only need one HTTP request instead! +::: tip NOTE +Dependency pre-bundling only applies in development mode, and uses `esbuild` to convert dependencies to ESM. In production builds, `@rollup/plugin-commonjs` is used instead. +::: + ## Automatic Dependency Discovery If an existing cache is not found, Vite will crawl your source code and automatically discover dependency imports (i.e. "bare imports" that expect to be resolved from `node_modules`) and use these found imports as entry points for the pre-bundle. The pre-bundling is performed with `esbuild` so it's typically very fast. @@ -36,11 +40,27 @@ After the server has already started, if a new dependency import is encountered ## Monorepos and Linked Dependencies -In a monorepo setup, a dependency may be a linked package from the same repo. Vite automatically detects dependencies that are not resolved from `node_modules` and treats the linked dep as source code. It will not attempt to bundle the linked dep, and instead will analyze the linked dep's dependency list instead. +In a monorepo setup, a dependency may be a linked package from the same repo. Vite automatically detects dependencies that are not resolved from `node_modules` and treats the linked dep as source code. It will not attempt to bundle the linked dep, and will analyze the linked dep's dependency list instead. + +However, this requires the linked dep to be exported as ESM. If not, you can add the dependency to [`optimizeDeps.include`](/config/#optimizedeps-include) and [`build.commonjsOptions.include`](/config/#build-commonjsoptions) in your config. + +```js +export default defineConfig({ + optimizeDeps: { + include: ['linked-dep'] + }, + build: { + commonjsOptions: { + include: [/linked-dep/, /node_modules/] + } + } +}) +``` + +When making changes to the linked dep, restart the dev server with the `--force` command line option for the changes to take effect. -::: warning Note -Linked dependencies might not work properly in the final build due to differences in dependency resolution. -Use `npm package` instead for all local dependencies to avoid issues in the final bundle. +::: warning Deduping +Due to differences in linked dependency resolution, transitive dependencies can deduplicated incorrectly, causing issues when used in runtime. If you stumble on this issue, use `npm pack` on the linked dependency to fix it. ::: ## Customizing the Behavior @@ -57,7 +77,7 @@ Both `include` and `exclude` can be used to deal with this. If the dependency is Vite caches the pre-bundled dependencies in `node_modules/.vite`. It determines whether it needs to re-run the pre-bundling step based on a few sources: -- The `dependencies` list in your `package.json` +- The `dependencies` list in your `package.json`. - Package manager lockfiles, e.g. `package-lock.json`, `yarn.lock`, or `pnpm-lock.yaml`. - Relevant fields in your `vite.config.js`, if present. diff --git a/docs/guide/env-and-mode.md b/docs/guide/env-and-mode.md index d3a6a575bce64c..1649feda8c7501 100644 --- a/docs/guide/env-and-mode.md +++ b/docs/guide/env-and-mode.md @@ -37,7 +37,7 @@ Vite uses [dotenv](https://github.com/motdotla/dotenv) to load additional enviro An env file for a specific mode (e.g. `.env.production`) will take higher priority than a generic one (e.g. `.env`). -In addition, environment variables that already exist when Vite is executed have the highest priority and will not be overwritten by `.env` files. +In addition, environment variables that already exist when Vite is executed have the highest priority and will not be overwritten by `.env` files. For example, when running `VITE_SOME_KEY=123 vite build`. `.env` files are loaded at the start of Vite. Restart the server after making changes. ::: @@ -57,7 +57,7 @@ If you want to customize env variables prefix, see [envPrefix](/config/index#env :::warning SECURITY NOTES -- `.env.*.local` files are local-only and can contain sensitive variables. You should add `.local` to your `.gitignore` to avoid them being checked into git. +- `.env.*.local` files are local-only and can contain sensitive variables. You should add `*.local` to your `.gitignore` to avoid them being checked into git. - Since any variables exposed to your Vite source code will end up in your client bundle, `VITE_*` variables should _not_ contain any sensitive information. ::: diff --git a/docs/guide/features.md b/docs/guide/features.md index c7fd2424b53cb1..ebed85cd2d529d 100644 --- a/docs/guide/features.md +++ b/docs/guide/features.md @@ -298,10 +298,10 @@ const modules = { } ``` -`import.meta.glob` and `import.meta.globEager` also support importing files as strings, similar to [Importing Asset as String](https://vitejs.dev/guide/assets.html#importing-asset-as-string). Here, we use the [Import Assertions](https://github.com/tc39/proposal-import-assertions#synopsis) syntax to import. +`import.meta.glob` and `import.meta.globEager` also support importing files as strings (similar to [Importing Asset as String](https://vitejs.dev/guide/assets.html#importing-asset-as-string)) with the [Import Reflection](https://github.com/tc39/proposal-import-reflection) syntax: ```js -const modules = import.meta.glob('./dir/*.js', { assert: { type: 'raw' } }) +const modules = import.meta.glob('./dir/*.js', { as: 'raw' }) ``` The above will be transformed into the following: @@ -317,7 +317,7 @@ const modules = { Note that: - This is a Vite-only feature and is not a web or ES standard. -- The glob patterns are treated like import specifiers: they must be either relative (start with `./`) or absolute (start with `/`, resolved relative to project root). +- The glob patterns are treated like import specifiers: they must be either relative (start with `./`) or absolute (start with `/`, resolved relative to project root) or an alias path (see [`resolve.alias` option](/config/#resolve-alias)). - The glob matching is done via `fast-glob` - check out its documentation for [supported glob patterns](https://github.com/mrmlnc/fast-glob#pattern-syntax). - You should also be aware that glob imports do not accept variables, you need to directly pass the string pattern. - The glob patterns cannot contain the same quote string (i.e. `'`, `"`, `` ` ``) as outer quotes, e.g. `'/Tom\'s files/**'`, use `"/Tom's files/**"` instead. @@ -352,6 +352,24 @@ In the production build, `.wasm` files smaller than `assetInlineLimit` will be i ## Web Workers +### Import with Constructors + +A web worker script can be imported using [`new Worker()`](https://developer.mozilla.org/en-US/docs/Web/API/Worker/Worker) and [`new SharedWorker()`](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker/SharedWorker). Compared to the worker suffixes, this syntax leans closer to the standards and is the **recommended** way to create workers. + +```ts +const worker = new Worker(new URL('./worker.js', import.meta.url)) +``` + +The worker constructor also accepts options, which can be used to create "module" workers: + +```ts +const worker = new Worker(new URL('./worker.js', import.meta.url), { + type: 'module' +}) +``` + +### Import with Query Suffixes + A web worker script can be directly imported by appending `?worker` or `?sharedworker` to the import request. The default export will be a custom worker constructor: ```js @@ -368,6 +386,8 @@ By default, the worker script will be emitted as a separate chunk in the product import MyWorker from './worker?worker&inline' ``` +See [Worker Options](/config/#worker-options) for details on configuring the bundling of all workers. + ## Build Optimizations > Features listed below are automatically applied as part of the build process and there is no need for explicit configuration unless you want to disable them. diff --git a/docs/guide/static-deploy.md b/docs/guide/static-deploy.md index 43b047dd7f53eb..8c6c219f568a9e 100644 --- a/docs/guide/static-deploy.md +++ b/docs/guide/static-deploy.md @@ -299,7 +299,7 @@ Vercel CLI ### Vercel for Git -1. Push your code to your git repository (GitHub, GitLab, BitBucket). +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/)) diff --git a/docs/guide/why.md b/docs/guide/why.md index 59e9c138eb7dca..9a24cf64777611 100644 --- a/docs/guide/why.md +++ b/docs/guide/why.md @@ -18,7 +18,7 @@ Vite improves the dev server start time by first dividing the modules in an appl - **Dependencies** are mostly plain JavaScript that do not change often during development. Some large dependencies (e.g. component libraries with hundreds of modules) are also quite expensive to process. Dependencies may also be shipped in various module formats (e.g. ESM or CommonJS). - Vite [pre-bundles dependencies](./dep-pre-bundling) using [esbuild](https://esbuild.github.io/). Esbuild is written in Go and pre-bundles dependencies 10-100x faster than JavaScript-based bundlers. + Vite [pre-bundles dependencies](./dep-pre-bundling) using [esbuild](https://esbuild.github.io/). esbuild is written in Go and pre-bundles dependencies 10-100x faster than JavaScript-based bundlers. - **Source code** often contains non-plain JavaScript that needs transforming (e.g. JSX, CSS or Vue/Svelte components), and will be edited very often. Also, not all source code needs to be loaded at the same time (e.g. with route-based code-splitting). @@ -32,7 +32,7 @@ Vite improves the dev server start time by first dividing the modules in an appl When a file is edited in a bundler-based build setup, it is inefficient to rebuild the whole bundle for obvious reasons: the update speed will degrade linearly with the size of the app. -Some bundler dev server runs the bundling in memory so that it only needs to invalidate part of its module graph when a file changes, but it still needs to re-construct the entire bundle and reload the web page. Reconstructing the bundle can be expensive, and reloading the page blows away the current state of the application. This is why some bundlers support Hot Module Replacement (HMR): allowing a module to "hot replace" itself without affecting the rest of the page. This greatly improves DX - however, in practice we've found that even HMR update speed deteriorates significantly as the size of the application grows. +In some bundlers, the dev server runs the bundling in memory so that it only needs to invalidate part of its module graph when a file changes, but it still needs to re-construct the entire bundle and reload the web page. Reconstructing the bundle can be expensive, and reloading the page blows away the current state of the application. This is why some bundlers support Hot Module Replacement (HMR): allowing a module to "hot replace" itself without affecting the rest of the page. This greatly improves DX - however, in practice we've found that even HMR update speed deteriorates significantly as the size of the application grows. In Vite, HMR is performed over native ESM. When a file is edited, Vite only needs to precisely invalidate the chain between the edited module and its closest HMR boundary (most of the time only the module itself), making HMR updates consistently fast regardless of the size of your application. diff --git a/jest.config.ts b/jest.config.ts index 7d4831524d01c3..11663af4e08107 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -6,7 +6,7 @@ const config: Config.InitialOptions = { testMatch: process.env.VITE_TEST_BUILD ? ['**/playground/**/*.spec.[jt]s?(x)'] : ['**/*.spec.[jt]s?(x)'], - testTimeout: process.env.CI ? 30000 : 10000, + testTimeout: process.env.CI ? 50000 : 20000, globalSetup: './scripts/jestGlobalSetup.cjs', globalTeardown: './scripts/jestGlobalTeardown.cjs', testEnvironment: './scripts/jestEnv.cjs', diff --git a/package.json b/package.json index 72b7076ee65d01..f6166c2985a30c 100644 --- a/package.json +++ b/package.json @@ -34,41 +34,41 @@ "ci-docs": "run-s build-vite build-plugin-vue build-docs" }, "devDependencies": { - "@microsoft/api-extractor": "^7.19.4", + "@microsoft/api-extractor": "^7.19.5", "@types/fs-extra": "^9.0.13", - "@types/jest": "^27.4.0", - "@types/node": "^16.11.22", + "@types/jest": "^27.4.1", + "@types/node": "^16.11.26", "@types/prompts": "^2.0.14", "@types/semver": "^7.3.9", - "@typescript-eslint/eslint-plugin": "^5.11.0", - "@typescript-eslint/parser": "^5.11.0", + "@typescript-eslint/eslint-plugin": "^5.16.0", + "@typescript-eslint/parser": "^5.16.0", "conventional-changelog-cli": "^2.2.2", "cross-env": "^7.0.3", - "esbuild": "^0.14.14", - "eslint": "^8.8.0", - "eslint-define-config": "^1.2.4", + "esbuild": "^0.14.27", + "eslint": "^8.12.0", + "eslint-define-config": "^1.3.0", "eslint-plugin-node": "^11.1.0", "execa": "^5.1.1", - "fs-extra": "^10.0.0", + "fs-extra": "^10.0.1", "jest": "^27.5.1", - "lint-staged": "^12.3.3", - "minimist": "^1.2.5", + "lint-staged": "^12.3.7", + "minimist": "^1.2.6", "node-fetch": "^2.6.6", "npm-run-all": "^4.1.5", "picocolors": "^1.0.0", - "playwright-chromium": "^1.18.1", - "prettier": "2.5.1", + "playwright-chromium": "^1.20.1", + "prettier": "2.6.1", "prompts": "^2.4.2", "rimraf": "^3.0.2", "rollup": "^2.59.0", "semver": "^7.3.5", "simple-git-hooks": "^2.7.0", "sirv": "^2.0.2", - "ts-jest": "^27.1.3", + "ts-jest": "^27.1.4", "ts-node": "^10.4.0", "typescript": "~4.5.4", "vite": "workspace:*", - "vitepress": "^0.21.6" + "vitepress": "^0.22.3" }, "simple-git-hooks": { "pre-commit": "pnpm exec lint-staged --concurrent false", @@ -85,11 +85,18 @@ "eslint --ext .ts" ] }, - "packageManager": "pnpm@6.30.0", + "packageManager": "pnpm@6.32.3", "pnpm": { "overrides": { "vite": "workspace:*", "@vitejs/plugin-vue": "workspace:*" + }, + "packageExtensions": { + "postcss-load-config": { + "peerDependencies": { + "postcss": "*" + } + } } } } diff --git a/packages/create-vite/CHANGELOG.md b/packages/create-vite/CHANGELOG.md index b81d7ec6fac49a..bf69fae7e535ad 100644 --- a/packages/create-vite/CHANGELOG.md +++ b/packages/create-vite/CHANGELOG.md @@ -1,3 +1,12 @@ +## 2.9.0 (2022-03-30) + +* chore: add isolatedModules to create-vite > template-vue-ts > tsconfig (#7304) ([21990ea](https://github.com/vitejs/vite/commit/21990ea)), closes [#7304](https://github.com/vitejs/vite/issues/7304) +* chore(deps): update all non-major dependencies (#7490) ([42c15f6](https://github.com/vitejs/vite/commit/42c15f6)), closes [#7490](https://github.com/vitejs/vite/issues/7490) +* docs(vue-ts): update note on vue type support in ts (#6165) ([cfc7648](https://github.com/vitejs/vite/commit/cfc7648)), closes [#6165](https://github.com/vitejs/vite/issues/6165) +* workflow: separate version bumping and publishing on release (#6879) ([fe8ef39](https://github.com/vitejs/vite/commit/fe8ef39)), closes [#6879](https://github.com/vitejs/vite/issues/6879) + + + # [2.8.0](https://github.com/vitejs/vite/compare/create-vite@2.7.2...create-vite@2.8.0) (2022-02-09) diff --git a/packages/create-vite/package.json b/packages/create-vite/package.json index 5d873b83fe515b..72955697360477 100644 --- a/packages/create-vite/package.json +++ b/packages/create-vite/package.json @@ -1,6 +1,6 @@ { "name": "create-vite", - "version": "2.8.0", + "version": "2.9.0", "license": "MIT", "author": "Evan You", "bin": { @@ -26,7 +26,7 @@ "homepage": "https://github.com/vitejs/vite/tree/main/packages/create-vite#readme", "dependencies": { "kolorist": "^1.5.1", - "minimist": "^1.2.5", + "minimist": "^1.2.6", "prompts": "^2.4.2" } } diff --git a/packages/create-vite/template-lit-ts/package.json b/packages/create-vite/template-lit-ts/package.json index 5c0a7c7948ee58..061def321a22e6 100644 --- a/packages/create-vite/template-lit-ts/package.json +++ b/packages/create-vite/template-lit-ts/package.json @@ -19,7 +19,7 @@ "lit": "^2.0.2" }, "devDependencies": { - "vite": "^2.8.0", + "vite": "^2.9.0", "typescript": "^4.5.4" } } diff --git a/packages/create-vite/template-lit/package.json b/packages/create-vite/template-lit/package.json index ca3c71428f22c9..89f4fee41576c6 100644 --- a/packages/create-vite/template-lit/package.json +++ b/packages/create-vite/template-lit/package.json @@ -17,6 +17,6 @@ "lit": "^2.0.2" }, "devDependencies": { - "vite": "^2.8.0" + "vite": "^2.9.0" } } diff --git a/packages/create-vite/template-preact-ts/package.json b/packages/create-vite/template-preact-ts/package.json index df1726ba6c4f7b..dfa6659650c5ae 100644 --- a/packages/create-vite/template-preact-ts/package.json +++ b/packages/create-vite/template-preact-ts/package.json @@ -13,6 +13,6 @@ "devDependencies": { "@preact/preset-vite": "^2.1.5", "typescript": "^4.5.4", - "vite": "^2.8.0" + "vite": "^2.9.0" } } diff --git a/packages/create-vite/template-preact/package.json b/packages/create-vite/template-preact/package.json index 2865df70374acf..02528128f6442e 100644 --- a/packages/create-vite/template-preact/package.json +++ b/packages/create-vite/template-preact/package.json @@ -12,6 +12,6 @@ }, "devDependencies": { "@preact/preset-vite": "^2.1.5", - "vite": "^2.8.0" + "vite": "^2.9.0" } } diff --git a/packages/create-vite/template-react-ts/package.json b/packages/create-vite/template-react-ts/package.json index 3b1e21b7dbca8c..00f99c8669d660 100644 --- a/packages/create-vite/template-react-ts/package.json +++ b/packages/create-vite/template-react-ts/package.json @@ -16,6 +16,6 @@ "@types/react-dom": "^17.0.10", "@vitejs/plugin-react": "^1.0.7", "typescript": "^4.5.4", - "vite": "^2.8.0" + "vite": "^2.9.0" } } diff --git a/packages/create-vite/template-react/package.json b/packages/create-vite/template-react/package.json index 7b0f87c6bc95f5..f6a93540f0d3ee 100644 --- a/packages/create-vite/template-react/package.json +++ b/packages/create-vite/template-react/package.json @@ -13,6 +13,6 @@ }, "devDependencies": { "@vitejs/plugin-react": "^1.0.7", - "vite": "^2.8.0" + "vite": "^2.9.0" } } diff --git a/packages/create-vite/template-svelte-ts/README.md b/packages/create-vite/template-svelte-ts/README.md index a9d516a32c682e..4ef762ffec4df3 100644 --- a/packages/create-vite/template-svelte-ts/README.md +++ b/packages/create-vite/template-svelte-ts/README.md @@ -4,7 +4,7 @@ This template should help get you started developing with Svelte and TypeScript ## Recommended IDE Setup -[VSCode](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). +[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). ## Need an official Svelte framework? diff --git a/packages/create-vite/template-svelte-ts/package.json b/packages/create-vite/template-svelte-ts/package.json index 3f2c63759285e5..32e080146e0b6e 100644 --- a/packages/create-vite/template-svelte-ts/package.json +++ b/packages/create-vite/template-svelte-ts/package.json @@ -17,6 +17,6 @@ "svelte-preprocess": "^4.9.8", "tslib": "^2.3.1", "typescript": "^4.5.4", - "vite": "^2.8.0" + "vite": "^2.9.0" } } diff --git a/packages/create-vite/template-svelte/README.md b/packages/create-vite/template-svelte/README.md index 8e35d33d2bc7c8..50ea7ed3b9132d 100644 --- a/packages/create-vite/template-svelte/README.md +++ b/packages/create-vite/template-svelte/README.md @@ -4,7 +4,7 @@ This template should help get you started developing with Svelte in Vite. ## Recommended IDE Setup -[VSCode](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). +[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). ## Need an official Svelte framework? diff --git a/packages/create-vite/template-svelte/package.json b/packages/create-vite/template-svelte/package.json index e81ffa8288b6ef..da049c170731b9 100644 --- a/packages/create-vite/template-svelte/package.json +++ b/packages/create-vite/template-svelte/package.json @@ -11,6 +11,6 @@ "devDependencies": { "@sveltejs/vite-plugin-svelte": "^1.0.0-next.30", "svelte": "^3.44.0", - "vite": "^2.8.0" + "vite": "^2.9.0" } } diff --git a/packages/create-vite/template-vanilla-ts/package.json b/packages/create-vite/template-vanilla-ts/package.json index 9b6cc582bfdb11..8dd7a0bb800909 100644 --- a/packages/create-vite/template-vanilla-ts/package.json +++ b/packages/create-vite/template-vanilla-ts/package.json @@ -9,6 +9,6 @@ }, "devDependencies": { "typescript": "^4.5.4", - "vite": "^2.8.0" + "vite": "^2.9.0" } } diff --git a/packages/create-vite/template-vanilla/package.json b/packages/create-vite/template-vanilla/package.json index f409412bbdc272..ff318e00f14fd1 100644 --- a/packages/create-vite/template-vanilla/package.json +++ b/packages/create-vite/template-vanilla/package.json @@ -8,6 +8,6 @@ "preview": "vite preview" }, "devDependencies": { - "vite": "^2.8.0" + "vite": "^2.9.0" } } diff --git a/packages/create-vite/template-vue-ts/README.md b/packages/create-vite/template-vue-ts/README.md index f5342b7d8f66dd..e432516724c1a7 100644 --- a/packages/create-vite/template-vue-ts/README.md +++ b/packages/create-vite/template-vue-ts/README.md @@ -1,11 +1,16 @@ -# Vue 3 + Typescript + Vite +# Vue 3 + TypeScript + Vite -This template should help get you started developing with Vue 3 and Typescript in Vite. The template uses Vue 3 ` + + + ", + ], + "version": 3, + } + `) + }) + + test('linked css', async () => { + const res = await page.request.get( + new URL('./linked.css', page.url()).href, + { + headers: { + accept: 'text/css' + } + } + ) + const css = await res.text() + const lines = css.split('\n') + expect(lines[lines.length - 1].includes('/*')).toBe(false) // expect no sourcemap + }) + + test('linked css with import', async () => { + const res = await page.request.get( + new URL('./linked-with-import.css', page.url()).href, + { + headers: { + accept: 'text/css' + } + } + ) + const css = await res.text() + const map = extractSourcemap(css) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + Object { + "mappings": "AAAA;EACE,UAAU;AACZ;;ACAA;EACE,UAAU;AACZ", + "sources": Array [ + "/root/be-imported.css", + "/root/linked-with-import.css", + ], + "sourcesContent": Array [ + ".be-imported { + color: red; + } + ", + "@import '@/be-imported.css'; + + .linked-with-import { + color: red; + } + ", + ], + "version": 3, + } + `) + }) + + test('imported css', async () => { + const css = await getStyleTagContentIncluding('.imported ') + const map = extractSourcemap(css) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + Object { + "mappings": "AAAA,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACX,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACb,CAAC;", + "sources": Array [ + "/root/imported.css", + ], + "sourcesContent": Array [ + ".imported { + color: red; + } + ", + ], + "version": 3, + } + `) + }) + + test('imported css with import', async () => { + const css = await getStyleTagContentIncluding('.imported-with-import ') + const map = extractSourcemap(css) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + Object { + "mappings": "AAAA;EACE,UAAU;AACZ;;ACAA;EACE,UAAU;AACZ", + "sources": Array [ + "/root/be-imported.css", + "/root/imported-with-import.css", + ], + "sourcesContent": Array [ + ".be-imported { + color: red; + } + ", + "@import '@/be-imported.css'; + + .imported-with-import { + color: red; + } + ", + ], + "version": 3, + } + `) + }) + + test('imported sass', async () => { + const css = await getStyleTagContentIncluding('.imported-sass ') + const map = extractSourcemap(css) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + Object { + "mappings": "AACE;EACE", + "sources": Array [ + "/root/imported.sass", + ], + "sourcesContent": Array [ + ".imported + &-sass + color: red + ", + ], + "version": 3, + } + `) + }) + + test('imported sass module', async () => { + const css = await getStyleTagContentIncluding('._imported-sass-module_') + const map = extractSourcemap(css) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + Object { + "mappings": "AACE;EACE", + "sources": Array [ + "/root/imported.module.sass", + ], + "sourcesContent": Array [ + ".imported + &-sass-module + color: red + ", + ], + "version": 3, + } + `) + }) + + test('imported less', async () => { + const css = await getStyleTagContentIncluding('.imported-less ') + const map = extractSourcemap(css) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + Object { + "mappings": "AACE;EACE", + "sources": Array [ + "/root/imported.less", + ], + "sourcesContent": Array [ + ".imported { + &-less { + color: @color; + } + } + ", + ], + "version": 3, + } + `) + }) + + test('imported stylus', async () => { + const css = await getStyleTagContentIncluding('.imported-stylus ') + const map = extractSourcemap(css) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + Object { + "mappings": "AACE;EACE,cAAM", + "sources": Array [ + "/root/imported.styl", + ], + "sourcesContent": Array [ + ".imported + &-stylus + color blue-red-mixed + ", + ], + "version": 3, + } + `) + }) + + test('should not output missing source file warning', () => { + serverLogs.forEach((log) => { + expect(log).not.toMatch(/Sourcemap for .+ points to missing source files/) + }) + }) +} else { + test('this file only includes test for serve', () => { + expect(true).toBe(true) + }) +} diff --git a/packages/playground/css-sourcemap/be-imported.css b/packages/playground/css-sourcemap/be-imported.css new file mode 100644 index 00000000000000..a29e5f77e3cb5d --- /dev/null +++ b/packages/playground/css-sourcemap/be-imported.css @@ -0,0 +1,3 @@ +.be-imported { + color: red; +} diff --git a/packages/playground/css-sourcemap/imported-with-import.css b/packages/playground/css-sourcemap/imported-with-import.css new file mode 100644 index 00000000000000..6a1ed3c3772698 --- /dev/null +++ b/packages/playground/css-sourcemap/imported-with-import.css @@ -0,0 +1,5 @@ +@import '@/be-imported.css'; + +.imported-with-import { + color: red; +} diff --git a/packages/playground/css-sourcemap/imported.css b/packages/playground/css-sourcemap/imported.css new file mode 100644 index 00000000000000..9c9b32924962dc --- /dev/null +++ b/packages/playground/css-sourcemap/imported.css @@ -0,0 +1,3 @@ +.imported { + color: red; +} diff --git a/packages/playground/css-sourcemap/imported.less b/packages/playground/css-sourcemap/imported.less new file mode 100644 index 00000000000000..e71b15eb102441 --- /dev/null +++ b/packages/playground/css-sourcemap/imported.less @@ -0,0 +1,5 @@ +.imported { + &-less { + color: @color; + } +} diff --git a/packages/playground/css-sourcemap/imported.module.sass b/packages/playground/css-sourcemap/imported.module.sass new file mode 100644 index 00000000000000..448a5e7e31f75a --- /dev/null +++ b/packages/playground/css-sourcemap/imported.module.sass @@ -0,0 +1,3 @@ +.imported + &-sass-module + color: red diff --git a/packages/playground/css-sourcemap/imported.sass b/packages/playground/css-sourcemap/imported.sass new file mode 100644 index 00000000000000..06fa634d5dd4e9 --- /dev/null +++ b/packages/playground/css-sourcemap/imported.sass @@ -0,0 +1,3 @@ +.imported + &-sass + color: red diff --git a/packages/playground/css-sourcemap/imported.styl b/packages/playground/css-sourcemap/imported.styl new file mode 100644 index 00000000000000..83c7cf517acf4d --- /dev/null +++ b/packages/playground/css-sourcemap/imported.styl @@ -0,0 +1,3 @@ +.imported + &-stylus + color blue-red-mixed diff --git a/packages/playground/css-sourcemap/index.html b/packages/playground/css-sourcemap/index.html new file mode 100644 index 00000000000000..a943c1d113a9b4 --- /dev/null +++ b/packages/playground/css-sourcemap/index.html @@ -0,0 +1,45 @@ + + + + + +
+

CSS Sourcemap

+ +

<inline>

+ +

<linked>: no import

+

<linked>: with import

+ +

<imported>: no import

+

<imported>: with import

+ +

<imported sass>

+

<imported sass> with module

+ +

<imported less> with string additionalData

+ +

<imported stylus>

+
+ + + + diff --git a/packages/playground/css-sourcemap/linked-with-import.css b/packages/playground/css-sourcemap/linked-with-import.css new file mode 100644 index 00000000000000..6f65d92441fa49 --- /dev/null +++ b/packages/playground/css-sourcemap/linked-with-import.css @@ -0,0 +1,5 @@ +@import '@/be-imported.css'; + +.linked-with-import { + color: red; +} diff --git a/packages/playground/css-sourcemap/linked.css b/packages/playground/css-sourcemap/linked.css new file mode 100644 index 00000000000000..e3b67c83872ac0 --- /dev/null +++ b/packages/playground/css-sourcemap/linked.css @@ -0,0 +1,3 @@ +.linked { + color: red; +} diff --git a/packages/playground/css-sourcemap/package.json b/packages/playground/css-sourcemap/package.json new file mode 100644 index 00000000000000..c7e9e61372cefa --- /dev/null +++ b/packages/playground/css-sourcemap/package.json @@ -0,0 +1,17 @@ +{ + "name": "test-css-sourcemap", + "private": true, + "version": "0.0.0", + "scripts": { + "dev": "vite", + "build": "vite build", + "debug": "node --inspect-brk ../../vite/bin/vite", + "preview": "vite preview" + }, + "devDependencies": { + "less": "^4.1.2", + "magic-string": "^0.25.7", + "sass": "^1.43.4", + "stylus": "^0.55.0" + } +} diff --git a/packages/playground/css-sourcemap/vite.config.js b/packages/playground/css-sourcemap/vite.config.js new file mode 100644 index 00000000000000..4fbeaa9a13aeb0 --- /dev/null +++ b/packages/playground/css-sourcemap/vite.config.js @@ -0,0 +1,61 @@ +const MagicString = require('magic-string') + +/** + * @type {import('vite').UserConfig} + */ +module.exports = { + resolve: { + alias: { + '@': __dirname + } + }, + css: { + devSourcemap: true, + preprocessorOptions: { + less: { + additionalData: '@color: red;' + }, + styl: { + additionalData: (content, filename) => { + const ms = new MagicString(content, { filename }) + + const willBeReplaced = 'blue-red-mixed' + const start = content.indexOf(willBeReplaced) + ms.overwrite(start, start + willBeReplaced.length, 'purple') + + const map = ms.generateMap({ hires: true }) + map.file = filename + map.sources = [filename] + + return { + content: ms.toString(), + map + } + } + } + } + }, + build: { + sourcemap: true + }, + plugins: [ + { + name: 'virtual-html', + configureServer(server) { + server.middlewares.use(async (req, res, next) => { + if (req.url === '/virtual.html') { + const t = await server.transformIndexHtml( + '/virtual.html', + '

virtual html

' + ) + res.setHeader('Content-Type', 'text/html') + res.statusCode = 200 + res.end(t) + return + } + next() + }) + } + } + ] +} diff --git a/packages/playground/css/__tests__/css.spec.ts b/packages/playground/css/__tests__/css.spec.ts index f1eb66e097ad86..ddb5c8c69d0e48 100644 --- a/packages/playground/css/__tests__/css.spec.ts +++ b/packages/playground/css/__tests__/css.spec.ts @@ -13,6 +13,14 @@ import { // note: tests should retrieve the element at the beginning of test and reuse it // in later assertions to ensure CSS HMR doesn't reload the page +test('imported css', async () => { + const css = await page.textContent('.imported-css') + expect(css).toContain('.imported {') + const glob = await page.textContent('.imported-css-glob') + expect(glob).toContain('.dir-import') + const globEager = await page.textContent('.imported-css-globEager') + expect(globEager).toContain('.dir-import') +}) test('linked css', async () => { const linked = await page.$('.linked') @@ -46,6 +54,12 @@ test('css import from js', async () => { await untilUpdated(() => getColor(atImport), 'blue') }) +test('css import asset with space', async () => { + const importedWithSpace = await page.$('.import-with-space') + + expect(await getBg(importedWithSpace)).toMatch(/.*ok\..*png/) +}) + test('postcss config', async () => { const imported = await page.$('.postcss .nesting') expect(await getColor(imported)).toBe('pink') @@ -310,7 +324,7 @@ test('PostCSS dir-dependency', async () => { } }) -test('Url separation', async () => { +test('URL separation', async () => { const urlSeparated = await page.$('.url-separated') const baseUrl = 'url(images/dog.webp)' const cases = new Array(5) @@ -356,3 +370,16 @@ test('minify css', async () => { expect(cssFile).toMatch('rgba(') expect(cssFile).not.toMatch('#ffff00b3') }) + +test('?raw', async () => { + const rawImportCss = await page.$('.raw-imported-css') + + expect(await rawImportCss.textContent()).toBe( + require('fs').readFileSync(require.resolve('../raw-imported.css'), 'utf-8') + ) +}) + +test('import css in less', async () => { + expect(await getColor('.css-in-less')).toBe('yellow') + expect(await getColor('.css-in-less-2')).toBe('blue') +}) diff --git a/packages/playground/css/__tests__/postcss-plugins-different-dir.spec.ts b/packages/playground/css/__tests__/postcss-plugins-different-dir.spec.ts new file mode 100644 index 00000000000000..19e9a43ae4ff6e --- /dev/null +++ b/packages/playground/css/__tests__/postcss-plugins-different-dir.spec.ts @@ -0,0 +1,29 @@ +import { getColor, getBgColor } from '../../testUtils' +import { createServer } from 'vite' +import path from 'path' + +// Regression test for https://github.com/vitejs/vite/issues/4000 +test('postcss plugins in different dir', async () => { + const port = 5006 + const server = await createServer({ + root: path.join(__dirname, '..', '..', 'tailwind'), + logLevel: 'silent', + server: { + port, + strictPort: true + }, + build: { + // skip transpilation during tests to make it faster + target: 'esnext' + } + }) + await server.listen() + try { + await page.goto(`http://localhost:${port}`) + const tailwindStyle = await page.$('.tailwind-style') + expect(await getBgColor(tailwindStyle)).toBe('rgb(254, 226, 226)') + expect(await getColor(tailwindStyle)).toBe('rgb(136, 136, 136)') + } finally { + await server.close() + } +}) diff --git a/packages/playground/css/folder with space/ok.png b/packages/playground/css/folder with space/ok.png new file mode 100644 index 00000000000000..a8d1e52510c41c Binary files /dev/null and b/packages/playground/css/folder with space/ok.png differ diff --git a/packages/playground/css/folder with space/space.css b/packages/playground/css/folder with space/space.css new file mode 100644 index 00000000000000..55a8532da32a94 --- /dev/null +++ b/packages/playground/css/folder with space/space.css @@ -0,0 +1,5 @@ +.import-with-space { + color: green; + background: url(spacefolder/ok.png); + background-position: center; +} diff --git a/packages/playground/css/glob-import/bar.css b/packages/playground/css/glob-import/bar.css new file mode 100644 index 00000000000000..a273f4970dcfa9 --- /dev/null +++ b/packages/playground/css/glob-import/bar.css @@ -0,0 +1,3 @@ +.dir-import-2 { + color: grey; +} diff --git a/packages/playground/css/glob-import/foo.css b/packages/playground/css/glob-import/foo.css new file mode 100644 index 00000000000000..03bd30eef45556 --- /dev/null +++ b/packages/playground/css/glob-import/foo.css @@ -0,0 +1,3 @@ +.dir-import { + color: grey; +} diff --git a/packages/playground/css/imported.css b/packages/playground/css/imported.css index 65743d08b932a7..7d582995fab9fd 100644 --- a/packages/playground/css/imported.css +++ b/packages/playground/css/imported.css @@ -1,4 +1,5 @@ @import './imported-at-import.css'; +@import 'spacefolder/space.css'; .imported { color: green; diff --git a/packages/playground/css/index.html b/packages/playground/css/index.html index 7a79bb1629f989..d08bc232752e8b 100644 --- a/packages/playground/css/index.html +++ b/packages/playground/css/index.html @@ -10,8 +10,14 @@

CSS

@import in import from js: This should be purple

+

+ @import from file with space: This should be green and have a background + image +

Imported css string:


+  

+  

 
   

PostCSS nesting plugin: this should be pink @@ -99,11 +105,26 @@

CSS

- Url separation preservation: should have valid background-image + URL separation preservation: should have valid background-image

Inlined import - this should NOT be red.

+ +
+ test import css in less, this color will be yellow +
+
+ test for import less in less, this color will be blue +
+ +
+ test import css in scss, this color will be orange +
+

+
+  

Raw Support

+

 
 
 
diff --git a/packages/playground/css/less.less b/packages/playground/css/less.less
index f8870e06f3a72c..69ffa830862014 100644
--- a/packages/playground/css/less.less
+++ b/packages/playground/css/less.less
@@ -1,4 +1,5 @@
 @import '@/nested/nested';
+@import './nested/css-in-less.less';
 
 @color: blue;
 
diff --git a/packages/playground/css/main.js b/packages/playground/css/main.js
index 24a278c8687940..6edd840a87c5e7 100644
--- a/packages/playground/css/main.js
+++ b/packages/playground/css/main.js
@@ -12,6 +12,9 @@ text('.imported-less', less)
 import stylus from './stylus.styl'
 text('.imported-stylus', stylus)
 
+import rawCss from './raw-imported.css?raw'
+text('.raw-imported-css', rawCss)
+
 import mod from './mod.module.css'
 document.querySelector('.modules').classList.add(mod['apply-color'])
 text('.modules-code', JSON.stringify(mod, null, 2))
@@ -68,3 +71,13 @@ if (import.meta.env.DEV) {
 // inlined
 import inlined from './inlined.css?inline'
 text('.inlined-code', inlined)
+
+// glob
+const glob = import.meta.glob('./glob-import/*.css')
+Promise.all(Object.keys(glob).map((key) => glob[key]())).then((res) => {
+  text('.imported-css-glob', JSON.stringify(res, null, 2))
+})
+
+// globEager
+const globEager = import.meta.globEager('./glob-import/*.css')
+text('.imported-css-globEager', JSON.stringify(globEager, null, 2))
diff --git a/packages/playground/css/nested/_index.scss b/packages/playground/css/nested/_index.scss
index 6f2103c79fc2c8..48d630b573ae1b 100644
--- a/packages/playground/css/nested/_index.scss
+++ b/packages/playground/css/nested/_index.scss
@@ -1,3 +1,5 @@
+@import './css-in-scss.css';
+
 .sass-at-import {
   color: olive;
   background: url(./icon.png) 10px no-repeat;
diff --git a/packages/playground/css/nested/css-in-less-2.less b/packages/playground/css/nested/css-in-less-2.less
new file mode 100644
index 00000000000000..443d17da34c0da
--- /dev/null
+++ b/packages/playground/css/nested/css-in-less-2.less
@@ -0,0 +1,3 @@
+.css-in-less-2 {
+  color: blue;
+}
diff --git a/packages/playground/css/nested/css-in-less.css b/packages/playground/css/nested/css-in-less.css
new file mode 100644
index 00000000000000..b174a601b1356c
--- /dev/null
+++ b/packages/playground/css/nested/css-in-less.css
@@ -0,0 +1,3 @@
+.css-in-less {
+  color: yellow;
+}
diff --git a/packages/playground/css/nested/css-in-less.less b/packages/playground/css/nested/css-in-less.less
new file mode 100644
index 00000000000000..abdd904b43016a
--- /dev/null
+++ b/packages/playground/css/nested/css-in-less.less
@@ -0,0 +1,4 @@
+@import url('./css-in-less.css');
+@import './css-in-less.css';
+
+@import './css-in-less-2.less';
diff --git a/packages/playground/css/nested/css-in-scss.css b/packages/playground/css/nested/css-in-scss.css
new file mode 100644
index 00000000000000..a63e49e4d6a1fd
--- /dev/null
+++ b/packages/playground/css/nested/css-in-scss.css
@@ -0,0 +1,3 @@
+.css-in-scss {
+  color: orange;
+}
diff --git a/packages/playground/css/package.json b/packages/playground/css/package.json
index 13a58874578c09..b45063100be089 100644
--- a/packages/playground/css/package.json
+++ b/packages/playground/css/package.json
@@ -10,6 +10,7 @@
   },
   "devDependencies": {
     "css-dep": "link:./css-dep",
+    "fast-glob": "^3.2.11",
     "less": "^4.1.2",
     "postcss-nested": "^5.0.6",
     "sass": "^1.43.4",
diff --git a/packages/playground/css/raw-imported.css b/packages/playground/css/raw-imported.css
new file mode 100644
index 00000000000000..ac0aee96390c33
--- /dev/null
+++ b/packages/playground/css/raw-imported.css
@@ -0,0 +1,3 @@
+.raw-imported {
+  color: yellow;
+}
diff --git a/packages/playground/css/vite.config.js b/packages/playground/css/vite.config.js
index e4dc8d5a9f265f..639a1302debb88 100644
--- a/packages/playground/css/vite.config.js
+++ b/packages/playground/css/vite.config.js
@@ -1,4 +1,5 @@
 const path = require('path')
+
 /**
  * @type {import('vite').UserConfig}
  */
@@ -8,7 +9,8 @@ module.exports = {
   },
   resolve: {
     alias: {
-      '@': __dirname
+      '@': __dirname,
+      spacefolder: __dirname + '/folder with space'
     }
   },
   css: {
diff --git a/packages/playground/define/__tests__/define.spec.ts b/packages/playground/define/__tests__/define.spec.ts
index f5eb78ea4e2766..709f7a935dc8c1 100644
--- a/packages/playground/define/__tests__/define.spec.ts
+++ b/packages/playground/define/__tests__/define.spec.ts
@@ -20,4 +20,7 @@ test('string', async () => {
   expect(await page.textContent('.spread-array')).toBe(
     JSON.stringify([...defines.__STRING__])
   )
+  // html would't need to define replacement
+  expect(await page.textContent('.exp-define')).toBe('__EXP__')
+  expect(await page.textContent('.import-json')).toBe('__EXP__')
 })
diff --git a/packages/playground/define/data.json b/packages/playground/define/data.json
new file mode 100644
index 00000000000000..491b781c2d97d3
--- /dev/null
+++ b/packages/playground/define/data.json
@@ -0,0 +1,3 @@
+{
+  "foo": "__EXP__"
+}
diff --git a/packages/playground/define/index.html b/packages/playground/define/index.html
index bf6a9c59689396..da78d192216b11 100644
--- a/packages/playground/define/index.html
+++ b/packages/playground/define/index.html
@@ -9,6 +9,8 @@ 

Define

process as property:

spread object:

spread array:

+

define variable in html: __EXP__

+

import json:

diff --git a/packages/playground/env-nested/package.json b/packages/playground/env-nested/package.json new file mode 100644 index 00000000000000..8fecc69a41c2f4 --- /dev/null +++ b/packages/playground/env-nested/package.json @@ -0,0 +1,11 @@ +{ + "name": "test-env-nested", + "private": true, + "version": "0.0.0", + "scripts": { + "dev": "vite", + "build": "vite build", + "debug": "node --inspect-brk ../../vite/bin/vite", + "preview": "vite preview" + } +} diff --git a/packages/playground/env-nested/vite.config.js b/packages/playground/env-nested/vite.config.js new file mode 100644 index 00000000000000..0e46100698650d --- /dev/null +++ b/packages/playground/env-nested/vite.config.js @@ -0,0 +1,5 @@ +const { defineConfig } = require('vite') + +module.exports = defineConfig({ + envDir: './envs' +}) diff --git a/packages/playground/fs-serve/__tests__/fs-serve.spec.ts b/packages/playground/fs-serve/__tests__/fs-serve.spec.ts index c618186b9bcd64..eba1e441881710 100644 --- a/packages/playground/fs-serve/__tests__/fs-serve.spec.ts +++ b/packages/playground/fs-serve/__tests__/fs-serve.spec.ts @@ -23,6 +23,15 @@ describe('main', () => { expect(await page.textContent('.safe-fetch-status')).toBe('200') }) + test('safe fetch with special characters', async () => { + expect( + await page.textContent('.safe-fetch-subdir-special-characters') + ).toMatch('KEY=safe') + expect( + await page.textContent('.safe-fetch-subdir-special-characters-status') + ).toBe('200') + }) + test('unsafe fetch', async () => { expect(await page.textContent('.unsafe-fetch')).toMatch('403 Restricted') expect(await page.textContent('.unsafe-fetch-status')).toBe('403') @@ -33,6 +42,13 @@ describe('main', () => { expect(await page.textContent('.safe-fs-fetch-status')).toBe('200') }) + test('safe fs fetch with special characters', async () => { + expect(await page.textContent('.safe-fs-fetch-special-characters')).toBe( + stringified + ) + expect(await page.textContent('.safe-fs-fetch-status')).toBe('200') + }) + test('unsafe fs fetch', async () => { expect(await page.textContent('.unsafe-fs-fetch')).toBe('') expect(await page.textContent('.unsafe-fs-fetch-status')).toBe('403') diff --git a/packages/playground/fs-serve/root/src/index.html b/packages/playground/fs-serve/root/src/index.html index c8b294e86ab0ea..951e14ad2cce91 100644 --- a/packages/playground/fs-serve/root/src/index.html +++ b/packages/playground/fs-serve/root/src/index.html @@ -8,6 +8,12 @@

Safe Fetch


 

 
+

Safe Fetch Subdirectory

+

+

+

+

+
 

Unsafe Fetch


 

@@ -15,6 +21,8 @@ 

Unsafe Fetch

Safe /@fs/ Fetch


 

+

+

 
 

Unsafe /@fs/ Fetch


@@ -42,6 +50,25 @@ 

Denied

.then((data) => { text('.safe-fetch', JSON.stringify(data)) }) + // inside allowed dir, safe fetch + fetch('/src/subdir/safe.txt') + .then((r) => { + text('.safe-fetch-subdir-status', r.status) + return r.text() + }) + .then((data) => { + text('.safe-fetch-subdir', JSON.stringify(data)) + }) + + // inside allowed dir, with special characters, safe fetch + fetch('/src/special%20characters%20%C3%A5%C3%A4%C3%B6/safe.txt') + .then((r) => { + text('.safe-fetch-subdir-special-characters-status', r.status) + return r.text() + }) + .then((data) => { + text('.safe-fetch-subdir-special-characters', JSON.stringify(data)) + }) // outside of allowed dir, treated as unsafe fetch('/unsafe.txt') @@ -79,6 +106,20 @@

Denied

console.error(e) }) + // not imported before, inside root with special characters, treated as safe + fetch( + '/@fs/' + + ROOT + + '/root/src/special%20characters%20%C3%A5%C3%A4%C3%B6/safe.json' + ) + .then((r) => { + text('.safe-fs-fetch-special-characters-status', r.status) + return r.json() + }) + .then((data) => { + text('.safe-fs-fetch-special-characters', JSON.stringify(data)) + }) + // .env, denied by default fetch('/@fs/' + ROOT + '/root/.env') .then((r) => { diff --git "a/packages/playground/fs-serve/root/src/special characters \303\245\303\244\303\266/safe.json" "b/packages/playground/fs-serve/root/src/special characters \303\245\303\244\303\266/safe.json" new file mode 100644 index 00000000000000..84f96593c10bad --- /dev/null +++ "b/packages/playground/fs-serve/root/src/special characters \303\245\303\244\303\266/safe.json" @@ -0,0 +1,3 @@ +{ + "msg": "safe" +} diff --git "a/packages/playground/fs-serve/root/src/special characters \303\245\303\244\303\266/safe.txt" "b/packages/playground/fs-serve/root/src/special characters \303\245\303\244\303\266/safe.txt" new file mode 100644 index 00000000000000..3f3d0607101642 --- /dev/null +++ "b/packages/playground/fs-serve/root/src/special characters \303\245\303\244\303\266/safe.txt" @@ -0,0 +1 @@ +KEY=safe diff --git a/packages/playground/fs-serve/root/src/subdir/safe.txt b/packages/playground/fs-serve/root/src/subdir/safe.txt new file mode 100644 index 00000000000000..3f3d0607101642 --- /dev/null +++ b/packages/playground/fs-serve/root/src/subdir/safe.txt @@ -0,0 +1 @@ +KEY=safe diff --git a/packages/playground/glob-import/__tests__/glob-import.spec.ts b/packages/playground/glob-import/__tests__/glob-import.spec.ts index 3a2425736548ea..ebdf6c0ab29193 100644 --- a/packages/playground/glob-import/__tests__/glob-import.spec.ts +++ b/packages/playground/glob-import/__tests__/glob-import.spec.ts @@ -7,6 +7,9 @@ import { } from '../../testUtils' const filteredResult = { + './alias.js': { + default: 'hi' + }, './foo.js': { msg: 'foo' } @@ -30,11 +33,19 @@ const json = isBuild const allResult = { // JSON file should be properly transformed + '/dir/alias.js': { + default: 'hi' + }, '/dir/baz.json': json, '/dir/foo.js': { msg: 'foo' }, '/dir/index.js': { + globWithAlias: { + './alias.js': { + default: 'hi' + } + }, modules: filteredResult }, '/dir/nested/bar.js': { @@ -55,6 +66,12 @@ const rawResult = { } } +const relativeRawResult = { + '../glob-import/dir/baz.json': { + msg: 'baz' + } +} + test('should work', async () => { expect(await page.textContent('.result')).toBe( JSON.stringify(allResult, null, 2) @@ -70,6 +87,12 @@ test('import glob raw', async () => { ) }) +test('import relative glob raw', async () => { + expect(await page.textContent('.relative-glob-raw')).toBe( + JSON.stringify(relativeRawResult, null, 2) + ) +}) + if (!isBuild) { test('hmr for adding/removing files', async () => { addFile('dir/a.js', '') @@ -80,6 +103,7 @@ if (!isBuild) { '/dir/a.js': {}, ...allResult, '/dir/index.js': { + ...allResult['/dir/index.js'], modules: { './a.js': {}, ...allResult['/dir/index.js'].modules @@ -102,6 +126,7 @@ if (!isBuild) { }, ...allResult, '/dir/index.js': { + ...allResult['/dir/index.js'], modules: { './a.js': { msg: 'a' diff --git a/packages/playground/glob-import/dir/alias.js b/packages/playground/glob-import/dir/alias.js new file mode 100644 index 00000000000000..9c533d93b9a98a --- /dev/null +++ b/packages/playground/glob-import/dir/alias.js @@ -0,0 +1 @@ +export default 'hi' diff --git a/packages/playground/glob-import/dir/index.js b/packages/playground/glob-import/dir/index.js index d13d470e2b2b80..fb87f69f0f3a61 100644 --- a/packages/playground/glob-import/dir/index.js +++ b/packages/playground/glob-import/dir/index.js @@ -1,3 +1,4 @@ const modules = import.meta.globEager('./*.(js|ts)') +const globWithAlias = import.meta.globEager('@dir/al*.js') -export { modules } +export { modules, globWithAlias } diff --git a/packages/playground/glob-import/index.html b/packages/playground/glob-import/index.html index bb5e2f3c18f752..64f456aeb4d6a2 100644 --- a/packages/playground/glob-import/index.html +++ b/packages/playground/glob-import/index.html @@ -1,6 +1,7 @@

 

 

+

 
 
 
+
+
diff --git a/packages/playground/glob-import/vite.config.ts b/packages/playground/glob-import/vite.config.ts
new file mode 100644
index 00000000000000..abc75b51656503
--- /dev/null
+++ b/packages/playground/glob-import/vite.config.ts
@@ -0,0 +1,10 @@
+import path from 'path'
+import { defineConfig } from 'vite'
+
+export default defineConfig({
+  resolve: {
+    alias: {
+      '@dir': path.resolve(__dirname, './dir/')
+    }
+  }
+})
diff --git a/packages/playground/hmr/__tests__/hmr.spec.ts b/packages/playground/hmr/__tests__/hmr.spec.ts
index 1f28763a90df94..6ddc2345ae4fb4 100644
--- a/packages/playground/hmr/__tests__/hmr.spec.ts
+++ b/packages/playground/hmr/__tests__/hmr.spec.ts
@@ -16,7 +16,7 @@ if (!isBuild) {
   test('self accept', async () => {
     const el = await page.$('.app')
 
-    editFile('hmr.js', (code) => code.replace('const foo = 1', 'const foo = 2'))
+    editFile('hmr.ts', (code) => code.replace('const foo = 1', 'const foo = 2'))
     await untilUpdated(() => el.textContent(), '2')
 
     expect(browserLogs).toMatchObject([
@@ -24,11 +24,11 @@ if (!isBuild) {
       'foo was: 1',
       '(self-accepting 1) foo is now: 2',
       '(self-accepting 2) foo is now: 2',
-      '[vite] hot updated: /hmr.js'
+      '[vite] hot updated: /hmr.ts'
     ])
     browserLogs.length = 0
 
-    editFile('hmr.js', (code) => code.replace('const foo = 2', 'const foo = 3'))
+    editFile('hmr.ts', (code) => code.replace('const foo = 2', 'const foo = 3'))
     await untilUpdated(() => el.textContent(), '3')
 
     expect(browserLogs).toMatchObject([
@@ -36,7 +36,7 @@ if (!isBuild) {
       'foo was: 2',
       '(self-accepting 1) foo is now: 3',
       '(self-accepting 2) foo is now: 3',
-      '[vite] hot updated: /hmr.js'
+      '[vite] hot updated: /hmr.ts'
     ])
     browserLogs.length = 0
   })
@@ -57,7 +57,7 @@ if (!isBuild) {
       '(single dep) nested foo is now: 1',
       '(multi deps) foo is now: 2',
       '(multi deps) nested foo is now: 1',
-      '[vite] hot updated: /hmrDep.js via /hmr.js'
+      '[vite] hot updated: /hmrDep.js via /hmr.ts'
     ])
     browserLogs.length = 0
 
@@ -74,7 +74,7 @@ if (!isBuild) {
       '(single dep) nested foo is now: 1',
       '(multi deps) foo is now: 3',
       '(multi deps) nested foo is now: 1',
-      '[vite] hot updated: /hmrDep.js via /hmr.js'
+      '[vite] hot updated: /hmrDep.js via /hmr.ts'
     ])
     browserLogs.length = 0
   })
@@ -95,7 +95,7 @@ if (!isBuild) {
       '(single dep) nested foo is now: 2',
       '(multi deps) foo is now: 3',
       '(multi deps) nested foo is now: 2',
-      '[vite] hot updated: /hmrDep.js via /hmr.js'
+      '[vite] hot updated: /hmrDep.js via /hmr.ts'
     ])
     browserLogs.length = 0
 
@@ -112,7 +112,7 @@ if (!isBuild) {
       '(single dep) nested foo is now: 3',
       '(multi deps) foo is now: 3',
       '(multi deps) nested foo is now: 3',
-      '[vite] hot updated: /hmrDep.js via /hmr.js'
+      '[vite] hot updated: /hmrDep.js via /hmr.ts'
     ])
     browserLogs.length = 0
   })
@@ -123,11 +123,16 @@ if (!isBuild) {
     await untilUpdated(() => el.textContent(), 'edited')
   })
 
+  test('plugin client-server communication', async () => {
+    const el = await page.$('.custom-communication')
+    await untilUpdated(() => el.textContent(), '3')
+  })
+
   test('full-reload encodeURI path', async () => {
     await page.goto(
       viteTestUrl + '/unicode-path/中文-にほんご-한글-🌕🌖🌗/index.html'
     )
-    let el = await page.$('#app')
+    const el = await page.$('#app')
     expect(await el.textContent()).toBe('title')
     await editFile(
       'unicode-path/中文-にほんご-한글-🌕🌖🌗/index.html',
diff --git a/packages/playground/hmr/event.d.ts b/packages/playground/hmr/event.d.ts
new file mode 100644
index 00000000000000..151a9cc3b861cd
--- /dev/null
+++ b/packages/playground/hmr/event.d.ts
@@ -0,0 +1,9 @@
+import 'vite/types/customEvent'
+
+declare module 'vite/types/customEvent' {
+  interface CustomEventMap {
+    'custom:foo': { msg: string }
+    'custom:remote-add': { a: number; b: number }
+    'custom:remote-add-result': { result: string }
+  }
+}
diff --git a/packages/playground/hmr/hmr.js b/packages/playground/hmr/hmr.ts
similarity index 81%
rename from packages/playground/hmr/hmr.js
rename to packages/playground/hmr/hmr.ts
index 01dca20f5dd71c..113b87bc5865d4 100644
--- a/packages/playground/hmr/hmr.js
+++ b/packages/playground/hmr/hmr.ts
@@ -41,7 +41,7 @@ if (import.meta.hot) {
         update.type === 'css-update' && update.path.match('global.css')
     )
     if (cssUpdate) {
-      const el = document.querySelector('#global-css')
+      const el = document.querySelector('#global-css') as HTMLLinkElement
       text('.css-prev', el.href)
       // We don't have a vite:afterUpdate event, but updates are currently sync
       setTimeout(() => {
@@ -54,9 +54,15 @@ if (import.meta.hot) {
     console.log(`>>> vite:error -- ${event.type}`)
   })
 
-  import.meta.hot.on('foo', ({ msg }) => {
+  import.meta.hot.on('custom:foo', ({ msg }) => {
     text('.custom', msg)
   })
+
+  // send custom event to server to calculate 1 + 2
+  import.meta.hot.send('custom:remote-add', { a: 1, b: 2 })
+  import.meta.hot.on('custom:remote-add-result', ({ result }) => {
+    text('.custom-communication', result)
+  })
 }
 
 function text(el, text) {
diff --git a/packages/playground/hmr/index.html b/packages/playground/hmr/index.html
index 766338598e51ad..0add7c26011a01 100644
--- a/packages/playground/hmr/index.html
+++ b/packages/playground/hmr/index.html
@@ -1,9 +1,10 @@
 
-
+
 
 
+
diff --git a/packages/playground/hmr/tsconfig.json b/packages/playground/hmr/tsconfig.json new file mode 100644 index 00000000000000..41b16fdc65ec8c --- /dev/null +++ b/packages/playground/hmr/tsconfig.json @@ -0,0 +1,15 @@ +{ + "include": ["."], + "exclude": ["**/dist/**"], + "compilerOptions": { + "target": "es2019", + "module": "esnext", + "outDir": "dist", + "allowJs": true, + "esModuleInterop": true, + "moduleResolution": "node", + "baseUrl": ".", + "jsx": "preserve", + "types": ["vite/client", "jest", "node"] + } +} diff --git a/packages/playground/hmr/vite.config.js b/packages/playground/hmr/vite.config.js deleted file mode 100644 index c34637844e2170..00000000000000 --- a/packages/playground/hmr/vite.config.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @type {import('vite').UserConfig} - */ -module.exports = { - plugins: [ - { - name: 'mock-custom', - async handleHotUpdate({ file, read, server }) { - if (file.endsWith('customFile.js')) { - const content = await read() - const msg = content.match(/export const msg = '(\w+)'/)[1] - server.ws.send({ - type: 'custom', - event: 'foo', - data: { - msg - } - }) - } - } - } - ] -} diff --git a/packages/playground/hmr/vite.config.ts b/packages/playground/hmr/vite.config.ts new file mode 100644 index 00000000000000..ef5d3cf36a2fcb --- /dev/null +++ b/packages/playground/hmr/vite.config.ts @@ -0,0 +1,21 @@ +import { defineConfig } from 'vite' + +export default defineConfig({ + plugins: [ + { + name: 'mock-custom', + async handleHotUpdate({ file, read, server }) { + if (file.endsWith('customFile.js')) { + const content = await read() + const msg = content.match(/export const msg = '(\w+)'/)[1] + server.ws.send('custom:foo', { msg }) + } + }, + configureServer(server) { + server.ws.on('custom:remote-add', ({ a, b }, client) => { + client.send('custom:remote-add-result', { result: a + b }) + }) + } + } + ] +}) diff --git a/packages/playground/html/__tests__/html.spec.ts b/packages/playground/html/__tests__/html.spec.ts index 66f537e5026361..834db1f6126cad 100644 --- a/packages/playground/html/__tests__/html.spec.ts +++ b/packages/playground/html/__tests__/html.spec.ts @@ -231,7 +231,7 @@ if (!isBuild) { await editFile('invalid.html', (content) => { return content.replace('
Good') }) - const content = await page.waitForSelector('text=Good Html') + const content = await page.waitForSelector('text=Good HTML') expect(content).toBeTruthy() }) }) diff --git a/packages/playground/html/invalid.html b/packages/playground/html/invalid.html index 5b5cf429687466..8acea73f16bdad 100644 --- a/packages/playground/html/invalid.html +++ b/packages/playground/html/invalid.html @@ -1 +1 @@ -
+
diff --git a/packages/playground/js-sourcemap/__tests__/build.spec.ts b/packages/playground/js-sourcemap/__tests__/build.spec.ts new file mode 100644 index 00000000000000..e36c1f52d2c1f8 --- /dev/null +++ b/packages/playground/js-sourcemap/__tests__/build.spec.ts @@ -0,0 +1,13 @@ +import { isBuild } from 'testUtils' + +if (isBuild) { + test('should not output sourcemap warning (#4939)', () => { + serverLogs.forEach((log) => { + expect(log).not.toMatch('Sourcemap is likely to be incorrect') + }) + }) +} else { + test('this file only includes test for build', () => { + expect(true).toBe(true) + }) +} diff --git a/packages/playground/js-sourcemap/__tests__/serve.spec.ts b/packages/playground/js-sourcemap/__tests__/serve.spec.ts new file mode 100644 index 00000000000000..a1ffdddc37ecd5 --- /dev/null +++ b/packages/playground/js-sourcemap/__tests__/serve.spec.ts @@ -0,0 +1,44 @@ +import { URL } from 'url' +import { + extractSourcemap, + formatSourcemapForSnapshot, + isBuild +} from 'testUtils' + +if (!isBuild) { + test('js', async () => { + const res = await page.request.get(new URL('./foo.js', page.url()).href) + const js = await res.text() + const lines = js.split('\n') + expect(lines[lines.length - 1].includes('//')).toBe(false) // expect no sourcemap + }) + + test('ts', async () => { + const res = await page.request.get(new URL('./bar.ts', page.url()).href) + const js = await res.text() + const map = extractSourcemap(js) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + Object { + "mappings": "AAAO,aAAM,MAAM;", + "sources": Array [ + "/root/bar.ts", + ], + "sourcesContent": Array [ + "export const bar = 'bar' + ", + ], + "version": 3, + } + `) + }) + + test('should not output missing source file warning', () => { + serverLogs.forEach((log) => { + expect(log).not.toMatch(/Sourcemap for .+ points to missing source files/) + }) + }) +} else { + test('this file only includes test for serve', () => { + expect(true).toBe(true) + }) +} diff --git a/packages/playground/js-sourcemap/bar.ts b/packages/playground/js-sourcemap/bar.ts new file mode 100644 index 00000000000000..1fc11814f22e80 --- /dev/null +++ b/packages/playground/js-sourcemap/bar.ts @@ -0,0 +1 @@ +export const bar = 'bar' diff --git a/packages/playground/js-sourcemap/foo.js b/packages/playground/js-sourcemap/foo.js new file mode 100644 index 00000000000000..cb356468240d50 --- /dev/null +++ b/packages/playground/js-sourcemap/foo.js @@ -0,0 +1 @@ +export const foo = 'foo' diff --git a/packages/playground/js-sourcemap/index.html b/packages/playground/js-sourcemap/index.html new file mode 100644 index 00000000000000..025b161011a3fa --- /dev/null +++ b/packages/playground/js-sourcemap/index.html @@ -0,0 +1,6 @@ +
+

JS Sourcemap

+
+ + + diff --git a/packages/playground/js-sourcemap/package.json b/packages/playground/js-sourcemap/package.json new file mode 100644 index 00000000000000..e5a97aea80830f --- /dev/null +++ b/packages/playground/js-sourcemap/package.json @@ -0,0 +1,11 @@ +{ + "name": "test-js-sourcemap", + "private": true, + "version": "0.0.0", + "scripts": { + "dev": "vite", + "build": "vite build", + "debug": "node --inspect-brk ../../vite/bin/vite", + "preview": "vite preview" + } +} diff --git a/packages/playground/js-sourcemap/vite.config.js b/packages/playground/js-sourcemap/vite.config.js new file mode 100644 index 00000000000000..bc9d1748cab964 --- /dev/null +++ b/packages/playground/js-sourcemap/vite.config.js @@ -0,0 +1,8 @@ +/** + * @type {import('vite').UserConfig} + */ +module.exports = { + build: { + sourcemap: true + } +} diff --git a/packages/playground/json/index.html b/packages/playground/json/index.html index 4f6e2b6ae57466..cf16636f91cb68 100644 --- a/packages/playground/json/index.html +++ b/packages/playground/json/index.html @@ -19,6 +19,9 @@

Importing as URL

Raw Import


 
+

JSON Module

+

+
 
diff --git a/packages/playground/legacy/main.js b/packages/playground/legacy/main.js
index b05acf439bdff8..31579b4717810d 100644
--- a/packages/playground/legacy/main.js
+++ b/packages/playground/legacy/main.js
@@ -21,6 +21,12 @@ text('#env', `is legacy: ${isLegacy}`)
 // Iterators
 text('#iterators', [...new Set(['hello'])].join(''))
 
+// structuredClone is supported core.js v3.20.0+
+text(
+  '#features-after-corejs-3',
+  JSON.stringify(structuredClone({ foo: 'foo' }))
+)
+
 // babel-helpers
 // Using `String.raw` to inject `@babel/plugin-transform-template-literals`
 // helpers.
diff --git a/packages/playground/legacy/package.json b/packages/playground/legacy/package.json
index 177aa5a0a5078b..3a3315c42aa832 100644
--- a/packages/playground/legacy/package.json
+++ b/packages/playground/legacy/package.json
@@ -10,6 +10,7 @@
     "preview": "vite preview"
   },
   "devDependencies": {
-    "@vitejs/plugin-legacy": "workspace:*"
+    "@vitejs/plugin-legacy": "workspace:*",
+    "express": "^4.17.1"
   }
 }
diff --git a/packages/playground/multiple-entrypoints/package.json b/packages/playground/multiple-entrypoints/package.json
index 7b4dab889c472e..6c338a64518ddb 100644
--- a/packages/playground/multiple-entrypoints/package.json
+++ b/packages/playground/multiple-entrypoints/package.json
@@ -7,5 +7,9 @@
     "build": "vite build",
     "debug": "node --inspect-brk ../../vite/bin/vite",
     "preview": "vite preview"
+  },
+  "devDependencies": {
+    "fast-glob": "^3.2.11",
+    "sass": "^1.43.4"
   }
 }
diff --git a/packages/playground/optimize-deps/__tests__/optimize-deps.spec.ts b/packages/playground/optimize-deps/__tests__/optimize-deps.spec.ts
index 706998c288fa50..d95a6d984cd9aa 100644
--- a/packages/playground/optimize-deps/__tests__/optimize-deps.spec.ts
+++ b/packages/playground/optimize-deps/__tests__/optimize-deps.spec.ts
@@ -46,7 +46,7 @@ test('dedupe', async () => {
   expect(await page.textContent('.dedupe button')).toBe('count is 1')
 })
 
-test('cjs borwser field (axios)', async () => {
+test('cjs browser field (axios)', async () => {
   expect(await page.textContent('.cjs-browser-field')).toBe('pong')
 })
 
@@ -62,6 +62,16 @@ test('import * from optimized dep', async () => {
   expect(await page.textContent('.import-star')).toMatch(`[success]`)
 })
 
+test('import from dep with .notjs files', async () => {
+  expect(await page.textContent('.not-js')).toMatch(`[success]`)
+})
+
+test('dep with dynamic import', async () => {
+  expect(await page.textContent('.dep-with-dynamic-import')).toMatch(
+    `[success]`
+  )
+})
+
 test('dep with css import', async () => {
   expect(await getColor('h1')).toBe('red')
 })
@@ -87,3 +97,11 @@ test('import from hidden dir', async () => {
 test('import optimize-excluded package that imports optimized-included package', async () => {
   expect(await page.textContent('.nested-include')).toBe('nested-include')
 })
+
+test('import aliased package with colon', async () => {
+  expect(await page.textContent('.url')).toBe('vitejs.dev')
+})
+
+test('variable names are reused in different scripts', async () => {
+  expect(await page.textContent('.reused-variable-names')).toBe('reused')
+})
diff --git a/packages/playground/optimize-deps/dep-not-js/foo.js b/packages/playground/optimize-deps/dep-not-js/foo.js
new file mode 100644
index 00000000000000..3d809780820c7b
--- /dev/null
+++ b/packages/playground/optimize-deps/dep-not-js/foo.js
@@ -0,0 +1 @@
+export const foo = '[success] imported from .notjs file'
diff --git a/packages/playground/optimize-deps/dep-not-js/index.notjs b/packages/playground/optimize-deps/dep-not-js/index.notjs
new file mode 100644
index 00000000000000..b4ef3a6936a797
--- /dev/null
+++ b/packages/playground/optimize-deps/dep-not-js/index.notjs
@@ -0,0 +1,4 @@
+
+import { foo } from './foo'
+export const notjsValue = foo
+
diff --git a/packages/playground/optimize-deps/dep-not-js/package.json b/packages/playground/optimize-deps/dep-not-js/package.json
new file mode 100644
index 00000000000000..39ebafb6217b6e
--- /dev/null
+++ b/packages/playground/optimize-deps/dep-not-js/package.json
@@ -0,0 +1,6 @@
+{
+  "name": "dep-not-js",
+  "private": true,
+  "version": "1.0.0",
+  "main": "index.notjs"
+}
diff --git a/packages/playground/optimize-deps/dep-with-dynamic-import/dynamic.js b/packages/playground/optimize-deps/dep-with-dynamic-import/dynamic.js
new file mode 100644
index 00000000000000..ea435dc36b7d48
--- /dev/null
+++ b/packages/playground/optimize-deps/dep-with-dynamic-import/dynamic.js
@@ -0,0 +1 @@
+export const foo = '[success] dependency with dynamic import'
diff --git a/packages/playground/optimize-deps/dep-with-dynamic-import/index.js b/packages/playground/optimize-deps/dep-with-dynamic-import/index.js
new file mode 100644
index 00000000000000..68a78d10d6e2d2
--- /dev/null
+++ b/packages/playground/optimize-deps/dep-with-dynamic-import/index.js
@@ -0,0 +1,4 @@
+export const lazyFoo = async function () {
+  const { foo } = await import('./dynamic.js')
+  return foo
+}
diff --git a/packages/playground/optimize-deps/dep-with-dynamic-import/package.json b/packages/playground/optimize-deps/dep-with-dynamic-import/package.json
new file mode 100644
index 00000000000000..81c5d2dda6a62a
--- /dev/null
+++ b/packages/playground/optimize-deps/dep-with-dynamic-import/package.json
@@ -0,0 +1,6 @@
+{
+  "name": "dep-with-dynamic-import",
+  "private": true,
+  "version": "0.0.0",
+  "main": "index.js"
+}
diff --git a/packages/playground/optimize-deps/index.html b/packages/playground/optimize-deps/index.html
index dfb274656f1baf..2be896d00acba9 100644
--- a/packages/playground/optimize-deps/index.html
+++ b/packages/playground/optimize-deps/index.html
@@ -38,6 +38,12 @@ 

Optimizing force included dep even when it's linked

import * as ...

+

Import from dependency with .notjs files

+
+ +

Import from dependency with dynamic import

+
+

Dep w/ special file format supported via plugins

@@ -53,6 +59,18 @@

Dep from hidden dir

Nested include

Module path:
+

Alias with colon

+
URL:
+ +

Reused variable names

+
This should show reused:
+ + + + + + diff --git a/packages/playground/optimize-deps/package.json b/packages/playground/optimize-deps/package.json index 0606343e0dce3c..2752e691da6fb2 100644 --- a/packages/playground/optimize-deps/package.json +++ b/packages/playground/optimize-deps/package.json @@ -17,12 +17,15 @@ "dep-esbuild-plugin-transform": "file:./dep-esbuild-plugin-transform", "dep-linked": "link:./dep-linked", "dep-linked-include": "link:./dep-linked-include", + "dep-not-js": "file:./dep-not-js", + "dep-with-dynamic-import": "file:./dep-with-dynamic-import", "lodash-es": "^4.17.21", "nested-exclude": "file:./nested-exclude", "phoenix": "^1.6.2", "react": "^17.0.2", "react-dom": "^17.0.2", "resolve-linked": "workspace:0.0.0", + "url": "^0.11.0", "vue": "^3.2.25", "vuex": "^4.0.0" }, diff --git a/packages/playground/optimize-deps/vite.config.js b/packages/playground/optimize-deps/vite.config.js index 45a50aaf85ede6..a989cf1961de11 100644 --- a/packages/playground/optimize-deps/vite.config.js +++ b/packages/playground/optimize-deps/vite.config.js @@ -1,3 +1,4 @@ +const fs = require('fs') const vue = require('@vitejs/plugin-vue') /** @@ -5,7 +6,10 @@ const vue = require('@vitejs/plugin-vue') */ module.exports = { resolve: { - dedupe: ['react'] + dedupe: ['react'], + alias: { + 'node:url': 'url' + } }, optimizeDeps: { @@ -36,6 +40,7 @@ module.exports = { plugins: [ vue(), + notjs(), // for axios request test { name: 'mock', @@ -48,3 +53,39 @@ module.exports = { } ] } + +// Handles .notjs file, basically remove wrapping and tags +function notjs() { + return { + name: 'notjs', + config() { + return { + optimizeDeps: { + extensions: ['.notjs'], + esbuildOptions: { + plugins: [ + { + name: 'esbuild-notjs', + setup(build) { + build.onLoad({ filter: /\.notjs$/ }, ({ path }) => { + let contents = fs.readFileSync(path, 'utf-8') + contents = contents + .replace('', '') + .replace('', '') + return { contents, loader: 'js' } + }) + } + } + ] + } + } + } + }, + transform(code, id) { + if (id.endsWith('.notjs')) { + code = code.replace('', '').replace('', '') + return { code } + } + } + } +} diff --git a/packages/playground/package.json b/packages/playground/package.json index 58ef368099e82f..75b1d15d299319 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -3,6 +3,7 @@ "private": true, "version": "1.0.0", "devDependencies": { + "convert-source-map": "^1.8.0", "css-color-names": "^1.0.1" } } diff --git a/packages/playground/resolve/__tests__/resolve.spec.ts b/packages/playground/resolve/__tests__/resolve.spec.ts index 97e4a5dd0add7b..46f8f6138b39a4 100644 --- a/packages/playground/resolve/__tests__/resolve.spec.ts +++ b/packages/playground/resolve/__tests__/resolve.spec.ts @@ -16,6 +16,13 @@ test('deep import with exports field', async () => { expect(await page.textContent('.exports-deep')).toMatch('[success]') }) +test('deep import with query with exports field', async () => { + // since it is imported with `?url` it should return a url + expect(await page.textContent('.exports-deep-query')).toMatch( + isBuild ? /base64/ : '/exports-path/deep.json' + ) +}) + test('deep import with exports field + exposed dir', async () => { expect(await page.textContent('.exports-deep-exposed-dir')).toMatch( '[success]' @@ -54,6 +61,18 @@ test('dont add extension to directory name (./dir-with-ext.js/index.js)', async expect(await page.textContent('.dir-with-ext')).toMatch('[success]') }) +test('resolve to the `browser` field instead of `module` when the importer is a `require` call', async () => { + expect( + await page.textContent('.require-pkg-with-browser-and-module-field') + ).toMatch('[success]') +}) + +test('resolve to the `main` field instead of `module` when the importer is a `require` call', async () => { + expect(await page.textContent('.require-pkg-with-esm-entries')).toMatch( + '[success]' + ) +}) + test('a ts module can import another ts module using its corresponding js file name', async () => { expect(await page.textContent('.ts-extension')).toMatch('[success]') }) diff --git a/packages/playground/resolve/exports-path/deep.json b/packages/playground/resolve/exports-path/deep.json new file mode 100644 index 00000000000000..97e19265d6c843 --- /dev/null +++ b/packages/playground/resolve/exports-path/deep.json @@ -0,0 +1,3 @@ +{ + "foo": "json" +} diff --git a/packages/playground/resolve/exports-path/package.json b/packages/playground/resolve/exports-path/package.json index 045fc85db128d2..7355da2f63f616 100644 --- a/packages/playground/resolve/exports-path/package.json +++ b/packages/playground/resolve/exports-path/package.json @@ -8,6 +8,7 @@ "require": "./cjs.js" }, "./deep.js": "./deep.js", + "./deep.json": "./deep.json", "./dir/": "./dir/", "./dir-mapped/*": { "import": "./dir/*", diff --git a/packages/playground/resolve/index.html b/packages/playground/resolve/index.html index db0a4bc54f1ad7..2478c89b495f49 100644 --- a/packages/playground/resolve/index.html +++ b/packages/playground/resolve/index.html @@ -12,6 +12,9 @@

Entry resolving with exports field

Deep import with exports field

fail

+

Deep import with query with exports field

+

fail

+

Deep import with exports field + exposed directory

fail

@@ -38,12 +41,35 @@

fail

+

+ A ts module can import another tsx module using its corresponding jsx file + name +

+

fail

+ +

+ A ts module can import another tsx module using its corresponding js file name +

+

fail

+

Resolve file name containing dot

fail

Browser Field

fail

+

+ Resolve to the `browser` field instead of `module` when the importer is a + `require` call +

+

fail

+ +

+ Resolve to the `main` field instead of `module` when the importer is a + `require` call +

+

fail

+

CSS Entry

@@ -100,6 +126,10 @@

resolve package that contains # in path

import { msg as deepMsg } from 'resolve-exports-path/deep.js' text('.exports-deep', deepMsg) + // deep import w/ exports w/ query + import deepPath from 'resolve-exports-path/deep.json?url' + text('.exports-deep-query', deepPath) + // deep import w/ exposed dir import { msg as exposedDirMsg } from 'resolve-exports-path/dir/dir' text('.exports-deep-exposed-dir', exposedDirMsg) @@ -130,6 +160,12 @@

resolve package that contains # in path

import { msg as tsExtensionMsg } from './ts-extension' text('.ts-extension', tsExtensionMsg) + import { msgJsx as tsJsxExtensionMsg } from './ts-extension' + text('.jsx-extension', tsJsxExtensionMsg) + + import { msgTsx as tsTsxExtensionMsg } from './ts-extension' + text('.tsx-extension', tsTsxExtensionMsg) + // filename with dot import { bar } from './util/bar.util' text('.dot', bar()) @@ -144,10 +180,11 @@

resolve package that contains # in path

import e from 'resolve-browser-field/ext-index/index.js' import f from 'resolve-browser-field/ext-index' import g from 'resolve-browser-field/no-ext-index/index.js' // no substitution + import h from 'resolve-browser-field/no-ext?query' import { ra, rb, rc, rd, re, rf, rg } from 'resolve-browser-field/relative' - const success = [main, a, c, d, e, f, ra, rc, rd, re, rf] + const success = [main, a, c, d, e, f, h, ra, rc, rd, re, rf] const noSuccess = [b, g, rb, rg] if ( @@ -157,6 +194,12 @@

resolve package that contains # in path

text('.browser', main) } + import { msg as requireBrowserMsg } from 'require-pkg-with-browser-and-module-field' + text('.require-pkg-with-browser-and-module-field', requireBrowserMsg) + + import { msg as requireMainMsg } from 'require-pkg-with-esm-entries' + text('.require-pkg-with-esm-entries', requireMainMsg) + import { msg as customExtMsg } from './custom-ext' text('.custom-ext', customExtMsg) diff --git a/packages/playground/resolve/package.json b/packages/playground/resolve/package.json index 5e0f53b4c8468a..4b8d497b3dbb27 100644 --- a/packages/playground/resolve/package.json +++ b/packages/playground/resolve/package.json @@ -12,6 +12,8 @@ "@babel/runtime": "^7.16.0", "es5-ext": "0.10.53", "normalize.css": "^8.0.1", + "require-pkg-with-browser-and-module-field": "link:./require-pkg-with-browser-and-module-field", + "require-pkg-with-esm-entries": "link:./require-pkg-with-esm-entries", "resolve-browser-field": "link:./browser-field", "resolve-custom-condition": "link:./custom-condition", "resolve-custom-main-field": "link:./custom-main-field", diff --git a/packages/playground/resolve/require-pkg-with-browser-and-module-field/dep.cjs b/packages/playground/resolve/require-pkg-with-browser-and-module-field/dep.cjs new file mode 100644 index 00000000000000..3fb20b76d48b79 --- /dev/null +++ b/packages/playground/resolve/require-pkg-with-browser-and-module-field/dep.cjs @@ -0,0 +1,5 @@ +const BigNumber = require('bignumber.js') + +const x = new BigNumber('1111222233334444555566') + +module.exports = x.toString() diff --git a/packages/playground/resolve/require-pkg-with-browser-and-module-field/index.cjs b/packages/playground/resolve/require-pkg-with-browser-and-module-field/index.cjs new file mode 100644 index 00000000000000..86d3360ab38dcb --- /dev/null +++ b/packages/playground/resolve/require-pkg-with-browser-and-module-field/index.cjs @@ -0,0 +1,8 @@ +const dep = require('./dep.cjs') + +const msg = + dep === '1.111222233334444555566e+21' + ? '[success] require-pkg-with-browser-and-module-field' + : '[failed] require-pkg-with-browser-and-module-field' + +exports.msg = msg diff --git a/packages/playground/resolve/require-pkg-with-browser-and-module-field/package.json b/packages/playground/resolve/require-pkg-with-browser-and-module-field/package.json new file mode 100644 index 00000000000000..2a0419b331c407 --- /dev/null +++ b/packages/playground/resolve/require-pkg-with-browser-and-module-field/package.json @@ -0,0 +1,9 @@ +{ + "name": "require-pkg-with-browser-and-module-field", + "private": true, + "version": "1.0.0", + "main": "./index.cjs", + "dependencies": { + "bignumber.js": "9.0.2" + } +} diff --git a/packages/playground/resolve/require-pkg-with-esm-entries/index.cjs b/packages/playground/resolve/require-pkg-with-esm-entries/index.cjs new file mode 100644 index 00000000000000..55958fbdba26ee --- /dev/null +++ b/packages/playground/resolve/require-pkg-with-esm-entries/index.cjs @@ -0,0 +1,9 @@ +const fromEvent = require('callbag-from-event') + +const msg = + // should be the exported function instead of the ES Module record (`{ default: ... }`) + typeof fromEvent === 'function' + ? '[success] require-pkg-with-esm-entries' + : '[failed] require-pkg-with-esm-entries' + +exports.msg = msg diff --git a/packages/playground/resolve/require-pkg-with-esm-entries/package.json b/packages/playground/resolve/require-pkg-with-esm-entries/package.json new file mode 100644 index 00000000000000..b845364bb6f19a --- /dev/null +++ b/packages/playground/resolve/require-pkg-with-esm-entries/package.json @@ -0,0 +1,9 @@ +{ + "name": "require-pkg-with-esm-entries", + "private": true, + "version": "1.0.0", + "main": "./index.cjs", + "dependencies": { + "callbag-from-event": "1.3.0" + } +} diff --git a/packages/playground/resolve/ts-extension/hellojsx.tsx b/packages/playground/resolve/ts-extension/hellojsx.tsx new file mode 100644 index 00000000000000..a8f610b399b17a --- /dev/null +++ b/packages/playground/resolve/ts-extension/hellojsx.tsx @@ -0,0 +1 @@ +export const msgJsx = '[success] use .jsx extension to import a tsx module' diff --git a/packages/playground/resolve/ts-extension/hellotsx.tsx b/packages/playground/resolve/ts-extension/hellotsx.tsx new file mode 100644 index 00000000000000..b7461ca71ded6c --- /dev/null +++ b/packages/playground/resolve/ts-extension/hellotsx.tsx @@ -0,0 +1 @@ +export const msgTsx = '[success] use .js extension to import a tsx module' diff --git a/packages/playground/resolve/ts-extension/index.ts b/packages/playground/resolve/ts-extension/index.ts index e095619ee4d716..bdb326f8778e64 100644 --- a/packages/playground/resolve/ts-extension/index.ts +++ b/packages/playground/resolve/ts-extension/index.ts @@ -1,3 +1,5 @@ import { msg } from './hello.js' +import { msgJsx } from './hellojsx.jsx' +import { msgTsx } from './hellotsx.js' -export { msg } +export { msg, msgJsx, msgTsx } diff --git a/packages/playground/resolve/vite.config.js b/packages/playground/resolve/vite.config.js index be1b75e431383a..c1282f4ffc789d 100644 --- a/packages/playground/resolve/vite.config.js +++ b/packages/playground/resolve/vite.config.js @@ -40,5 +40,11 @@ module.exports = { } } } - ] + ], + optimizeDeps: { + include: [ + 'require-pkg-with-browser-and-module-field', + 'require-pkg-with-esm-entries' + ] + } } diff --git a/packages/playground/tailwind-sourcemap/__tests__/build.spec.ts b/packages/playground/tailwind-sourcemap/__tests__/build.spec.ts new file mode 100644 index 00000000000000..e36c1f52d2c1f8 --- /dev/null +++ b/packages/playground/tailwind-sourcemap/__tests__/build.spec.ts @@ -0,0 +1,13 @@ +import { isBuild } from 'testUtils' + +if (isBuild) { + test('should not output sourcemap warning (#4939)', () => { + serverLogs.forEach((log) => { + expect(log).not.toMatch('Sourcemap is likely to be incorrect') + }) + }) +} else { + test('this file only includes test for build', () => { + expect(true).toBe(true) + }) +} diff --git a/packages/playground/tailwind-sourcemap/__tests__/serve.spec.ts b/packages/playground/tailwind-sourcemap/__tests__/serve.spec.ts new file mode 100644 index 00000000000000..d961f75e4536e5 --- /dev/null +++ b/packages/playground/tailwind-sourcemap/__tests__/serve.spec.ts @@ -0,0 +1,13 @@ +import { isBuild } from 'testUtils' + +if (!isBuild) { + test('should not output missing source file warning', () => { + serverLogs.forEach((log) => { + expect(log).not.toMatch(/Sourcemap for .+ points to missing source files/) + }) + }) +} else { + test('this file only includes test for serve', () => { + expect(true).toBe(true) + }) +} diff --git a/packages/playground/tailwind-sourcemap/index.html b/packages/playground/tailwind-sourcemap/index.html new file mode 100644 index 00000000000000..95c8c5da7716d1 --- /dev/null +++ b/packages/playground/tailwind-sourcemap/index.html @@ -0,0 +1,9 @@ +
+

Tailwind Sourcemap

+ +

foo

+
+ + diff --git a/packages/playground/tailwind-sourcemap/package.json b/packages/playground/tailwind-sourcemap/package.json new file mode 100644 index 00000000000000..5c374f3bf47f1b --- /dev/null +++ b/packages/playground/tailwind-sourcemap/package.json @@ -0,0 +1,14 @@ +{ + "name": "test-tailwind-sourcemap", + "private": true, + "version": "0.0.0", + "scripts": { + "dev": "vite", + "build": "vite build", + "debug": "node --inspect-brk ../../vite/bin/vite", + "preview": "vite preview" + }, + "dependencies": { + "tailwindcss": "^3.0.23" + } +} diff --git a/packages/playground/tailwind-sourcemap/postcss.config.js b/packages/playground/tailwind-sourcemap/postcss.config.js new file mode 100644 index 00000000000000..eab3760cbc7b42 --- /dev/null +++ b/packages/playground/tailwind-sourcemap/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: { + tailwindcss: { config: __dirname + '/tailwind.config.js' } + } +} diff --git a/packages/playground/tailwind-sourcemap/tailwind.config.js b/packages/playground/tailwind-sourcemap/tailwind.config.js new file mode 100644 index 00000000000000..f89a536ccd742f --- /dev/null +++ b/packages/playground/tailwind-sourcemap/tailwind.config.js @@ -0,0 +1,7 @@ +module.exports = { + content: ['./index.html'], + theme: { + extend: {} + }, + plugins: [] +} diff --git a/packages/playground/tailwind-sourcemap/tailwind.css b/packages/playground/tailwind-sourcemap/tailwind.css new file mode 100644 index 00000000000000..b5c61c956711f9 --- /dev/null +++ b/packages/playground/tailwind-sourcemap/tailwind.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/packages/playground/tailwind-sourcemap/vite.config.js b/packages/playground/tailwind-sourcemap/vite.config.js new file mode 100644 index 00000000000000..70fea77247bcd4 --- /dev/null +++ b/packages/playground/tailwind-sourcemap/vite.config.js @@ -0,0 +1,11 @@ +/** + * @type {import('vite').UserConfig} + */ +module.exports = { + css: { + devSourcemap: true + }, + build: { + sourcemap: true + } +} diff --git a/packages/playground/tailwind/src/views/Page.vue b/packages/playground/tailwind/src/views/Page.vue index ec59b44238c733..764a2a18e54fdb 100644 --- a/packages/playground/tailwind/src/views/Page.vue +++ b/packages/playground/tailwind/src/views/Page.vue @@ -2,7 +2,9 @@

|Page title|

{{ val }}
-
+
Tailwind style
diff --git a/packages/playground/testUtils.ts b/packages/playground/testUtils.ts index 0ae0c6e8766e95..7454c88452e9b2 100644 --- a/packages/playground/testUtils.ts +++ b/packages/playground/testUtils.ts @@ -7,6 +7,8 @@ import path from 'path' import colors from 'css-color-names' import type { ElementHandle } from 'playwright-chromium' import type { Manifest } from 'vite' +import { normalizePath } from 'vite' +import { fromComment } from 'convert-source-map' export function slash(p: string): string { return p.replace(/\\/g, '/') @@ -64,6 +66,11 @@ export async function getBg(el: string | ElementHandle): Promise { return el.evaluate((el) => getComputedStyle(el as Element).backgroundImage) } +export async function getBgColor(el: string | ElementHandle): Promise { + el = await toEl(el) + return el.evaluate((el) => getComputedStyle(el as Element).backgroundColor) +} + export function readFile(filename: string): string { return fs.readFileSync(path.resolve(testDir, filename), 'utf-8') } @@ -133,3 +140,17 @@ export async function untilUpdated( * Send the rebuild complete message in build watch */ export { notifyRebuildComplete } from '../../scripts/jestPerTestSetup' + +export const extractSourcemap = (content: string) => { + const lines = content.trim().split('\n') + return fromComment(lines[lines.length - 1]).toObject() +} + +export const formatSourcemapForSnapshot = (map: any) => { + const root = normalizePath(testDir) + const m = { ...map } + delete m.file + delete m.names + m.sources = m.sources.map((source) => source.replace(root, '/root')) + return m +} diff --git a/packages/playground/vue-jsx/Query.jsx b/packages/playground/vue-jsx/Query.jsx new file mode 100644 index 00000000000000..60de93eafb7b1c --- /dev/null +++ b/packages/playground/vue-jsx/Query.jsx @@ -0,0 +1,12 @@ +import { defineComponent, ref } from 'vue' + +export default defineComponent(() => { + const count = ref(6) + const inc = () => count.value++ + + return () => ( + + ) +}) diff --git a/packages/playground/vue-jsx/__tests__/vue-jsx.spec.ts b/packages/playground/vue-jsx/__tests__/vue-jsx.spec.ts index b929f61fe965c3..999fdc19af51ec 100644 --- a/packages/playground/vue-jsx/__tests__/vue-jsx.spec.ts +++ b/packages/playground/vue-jsx/__tests__/vue-jsx.spec.ts @@ -7,6 +7,7 @@ test('should render', async () => { expect(await page.textContent('.default-tsx')).toMatch('3') expect(await page.textContent('.script')).toMatch('4') expect(await page.textContent('.src-import')).toMatch('5') + expect(await page.textContent('.jsx-with-query')).toMatch('6') expect(await page.textContent('.other-ext')).toMatch('Other Ext') }) @@ -23,6 +24,8 @@ test('should update', async () => { expect(await page.textContent('.script')).toMatch('5') await page.click('.src-import') expect(await page.textContent('.src-import')).toMatch('6') + await page.click('.jsx-with-query') + expect(await page.textContent('.jsx-with-query')).toMatch('7') }) if (!isBuild) { @@ -102,4 +105,11 @@ if (!isBuild) { expect(await page.textContent('.script')).toMatch('5') }) + + test('hmr: setup jsx in .vue', async () => { + editFile('setup-syntax-jsx.vue', (code) => + code.replace('let count = ref(100)', 'let count = ref(1000)') + ) + await untilUpdated(() => page.textContent('.setup-jsx'), '1000') + }) } diff --git a/packages/playground/vue-jsx/main.jsx b/packages/playground/vue-jsx/main.jsx index 200702c2cc69a1..e304e7788e49e7 100644 --- a/packages/playground/vue-jsx/main.jsx +++ b/packages/playground/vue-jsx/main.jsx @@ -4,6 +4,9 @@ import { default as TsxDefault } from './Comp' import OtherExt from './OtherExt.tesx' import JsxScript from './Script.vue' import JsxSrcImport from './SrcImport.vue' +import JsxSetupSyntax from './setup-syntax-jsx.vue' +// eslint-disable-next-line +import JsxWithQuery from './Query.jsx?query=true' function App() { return ( @@ -15,6 +18,8 @@ function App() { + + ) } diff --git a/packages/playground/vue-jsx/setup-syntax-jsx.vue b/packages/playground/vue-jsx/setup-syntax-jsx.vue new file mode 100644 index 00000000000000..0b16be7e773280 --- /dev/null +++ b/packages/playground/vue-jsx/setup-syntax-jsx.vue @@ -0,0 +1,17 @@ + + + diff --git a/packages/playground/vue-jsx/vite.config.js b/packages/playground/vue-jsx/vite.config.js index 3ec89a003d79f4..d6eb84e05f4e4a 100644 --- a/packages/playground/vue-jsx/vite.config.js +++ b/packages/playground/vue-jsx/vite.config.js @@ -9,7 +9,28 @@ module.exports = { vueJsxPlugin({ include: [/\.tesx$/, /\.[jt]sx$/] }), - vuePlugin() + vuePlugin(), + { + name: 'jsx-query-plugin', + transform(code, id) { + if (id.includes('?query=true')) { + return ` +import { createVNode as _createVNode } from "vue"; +import { defineComponent, ref } from 'vue'; +export default defineComponent(() => { + const count = ref(6); + + const inc = () => count.value++; + + return () => _createVNode("button", { + "class": "jsx-with-query", + "onClick": inc + }, [count.value]); +}); +` + } + } + } ], build: { // to make tests faster diff --git a/packages/playground/vue-sourcemap/Css.vue b/packages/playground/vue-sourcemap/Css.vue new file mode 100644 index 00000000000000..19668de8d33965 --- /dev/null +++ b/packages/playground/vue-sourcemap/Css.vue @@ -0,0 +1,23 @@ + + + + + + + diff --git a/packages/playground/vue-sourcemap/Js.vue b/packages/playground/vue-sourcemap/Js.vue new file mode 100644 index 00000000000000..3a5577099f67d3 --- /dev/null +++ b/packages/playground/vue-sourcemap/Js.vue @@ -0,0 +1,11 @@ + + + + + diff --git a/packages/playground/vue-sourcemap/Less.vue b/packages/playground/vue-sourcemap/Less.vue new file mode 100644 index 00000000000000..f12a3e55f2111c --- /dev/null +++ b/packages/playground/vue-sourcemap/Less.vue @@ -0,0 +1,9 @@ + + + diff --git a/packages/playground/vue-sourcemap/Main.vue b/packages/playground/vue-sourcemap/Main.vue new file mode 100644 index 00000000000000..b9b03596f5aea5 --- /dev/null +++ b/packages/playground/vue-sourcemap/Main.vue @@ -0,0 +1,20 @@ + + + diff --git a/packages/playground/vue-sourcemap/Sass.vue b/packages/playground/vue-sourcemap/Sass.vue new file mode 100644 index 00000000000000..0fded031a52c72 --- /dev/null +++ b/packages/playground/vue-sourcemap/Sass.vue @@ -0,0 +1,8 @@ + + + diff --git a/packages/playground/vue-sourcemap/SassWithImport.vue b/packages/playground/vue-sourcemap/SassWithImport.vue new file mode 100644 index 00000000000000..7a00420a00bb3a --- /dev/null +++ b/packages/playground/vue-sourcemap/SassWithImport.vue @@ -0,0 +1,11 @@ + + + diff --git a/packages/playground/vue-sourcemap/Ts.vue b/packages/playground/vue-sourcemap/Ts.vue new file mode 100644 index 00000000000000..e0d96bb4725abd --- /dev/null +++ b/packages/playground/vue-sourcemap/Ts.vue @@ -0,0 +1,11 @@ + + + + + diff --git a/packages/playground/vue-sourcemap/__tests__/build.spec.ts b/packages/playground/vue-sourcemap/__tests__/build.spec.ts new file mode 100644 index 00000000000000..e36c1f52d2c1f8 --- /dev/null +++ b/packages/playground/vue-sourcemap/__tests__/build.spec.ts @@ -0,0 +1,13 @@ +import { isBuild } from 'testUtils' + +if (isBuild) { + test('should not output sourcemap warning (#4939)', () => { + serverLogs.forEach((log) => { + expect(log).not.toMatch('Sourcemap is likely to be incorrect') + }) + }) +} else { + test('this file only includes test for build', () => { + expect(true).toBe(true) + }) +} diff --git a/packages/playground/vue-sourcemap/__tests__/serve.spec.ts b/packages/playground/vue-sourcemap/__tests__/serve.spec.ts new file mode 100644 index 00000000000000..08b4c04face111 --- /dev/null +++ b/packages/playground/vue-sourcemap/__tests__/serve.spec.ts @@ -0,0 +1,329 @@ +import { + extractSourcemap, + formatSourcemapForSnapshot, + isBuild +} from 'testUtils' +import { URL } from 'url' + +if (!isBuild) { + const getStyleTagContentIncluding = async (content: string) => { + const styles = await page.$$('style') + for (const style of styles) { + const text = await style.textContent() + if (text.includes(content)) { + return text + } + } + throw new Error('Not found') + } + + test('js', async () => { + const res = await page.request.get(new URL('./Js.vue', page.url()).href) + const js = await res.text() + const map = extractSourcemap(js) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + Object { + "mappings": "AAKA,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;;;;;AAGP;AACd,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;wBARlB,oBAAiB,WAAd,MAAU", + "sources": Array [ + "/root/Js.vue", + ], + "sourcesContent": Array [ + " + + + + + ", + ], + "version": 3, + } + `) + }) + + test('ts', async () => { + const res = await page.request.get(new URL('./Ts.vue', page.url()).href) + const js = await res.text() + const map = extractSourcemap(js) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + Object { + "mappings": ";AAKA,QAAQ,IAAI,WAAW;;;;AAIvB,YAAQ,IAAI,UAAU;;;;;;;;uBARpB,oBAAiB,WAAd,MAAU", + "sources": Array [ + "/root/Ts.vue", + ], + "sourcesContent": Array [ + " + + + + + ", + ], + "version": 3, + } + `) + }) + + test('css', async () => { + const css = await getStyleTagContentIncluding('.css ') + const map = extractSourcemap(css) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + Object { + "mappings": ";AAOA;EACE,UAAU;AACZ", + "sources": Array [ + "/root/Css.vue", + ], + "sourcesContent": Array [ + " + + + + + + + ", + ], + "version": 3, + } + `) + }) + + test('css module', async () => { + const css = await getStyleTagContentIncluding('._css-module_') + const map = extractSourcemap(css) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + Object { + "mappings": ";AAaA;EACE,UAAU;AACZ", + "sources": Array [ + "/root/Css.vue", + ], + "sourcesContent": Array [ + " + + + + + + + ", + ], + "version": 3, + } + `) + }) + + test('css scoped', async () => { + const css = await getStyleTagContentIncluding('.css-scoped[data-v-') + const map = extractSourcemap(css) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + Object { + "mappings": ";AAmBA;EACE,UAAU;AACZ", + "sources": Array [ + "/root/Css.vue", + ], + "sourcesContent": Array [ + " + + + + + + + ", + ], + "version": 3, + } + `) + }) + + test('sass', async () => { + const css = await getStyleTagContentIncluding('.sass ') + const map = extractSourcemap(css) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + Object { + "mappings": "AAKA;EACE", + "sources": Array [ + "/root/Sass.vue", + ], + "sourcesContent": Array [ + " + + + ", + ], + "version": 3, + } + `) + }) + + test('sass with import', async () => { + const css = await getStyleTagContentIncluding('.sass-with-import ') + const map = extractSourcemap(css) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + Object { + "mappings": "AAAA;EACE;;ACOF;EACE", + "sources": Array [ + "/root/sassWithImportImported.sass", + "/root/SassWithImport.vue", + ], + "sourcesContent": Array [ + ".sass-with-import-imported + color: red + ", + " + + + ", + ], + "version": 3, + } + `) + }) + + test('less with additionalData', async () => { + const css = await getStyleTagContentIncluding('.less ') + const map = extractSourcemap(css) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + Object { + "mappings": "AAKA;EACE", + "sources": Array [ + "/root/Less.vue", + ], + "sourcesContent": Array [ + " + + + ", + ], + "version": 3, + } + `) + }) + + test('src imported', async () => { + const css = await getStyleTagContentIncluding('.src-import[data-v-') + const map = extractSourcemap(css) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + Object { + "mappings": "AAAA;EACE,UAAU;AACZ", + "sources": Array [ + "/root/src-import/src-import.css", + ], + "sourcesContent": Array [ + ".src-import { + color: red; + } + ", + ], + "version": 3, + } + `) + }) + + test('src imported sass', async () => { + const css = await getStyleTagContentIncluding('.src-import-sass[data-v-') + const map = extractSourcemap(css) + expect(formatSourcemapForSnapshot(map)).toMatchInlineSnapshot(` + Object { + "mappings": "AAAA;EACE;;ACCF;EACE", + "sources": Array [ + "/root/src-import/src-import-imported.sass", + "/root/src-import/src-import.sass", + ], + "sourcesContent": Array [ + ".src-import-sass-imported + color: red + ", + "@import './src-import-imported' + + .src-import-sass + color: red + ", + ], + "version": 3, + } + `) + }) +} else { + test('this file only includes test for serve', () => { + expect(true).toBe(true) + }) +} diff --git a/packages/playground/vue-sourcemap/index.html b/packages/playground/vue-sourcemap/index.html new file mode 100644 index 00000000000000..57f325518a2c25 --- /dev/null +++ b/packages/playground/vue-sourcemap/index.html @@ -0,0 +1,7 @@ +
+ diff --git a/packages/playground/vue-sourcemap/package.json b/packages/playground/vue-sourcemap/package.json new file mode 100644 index 00000000000000..286940b01efa58 --- /dev/null +++ b/packages/playground/vue-sourcemap/package.json @@ -0,0 +1,19 @@ +{ + "name": "test-vue-sourcemap", + "private": true, + "version": "0.0.0", + "scripts": { + "dev": "vite", + "build": "vite build", + "debug": "node --inspect-brk ../../vite/bin/vite", + "preview": "vite preview" + }, + "devDependencies": { + "@vitejs/plugin-vue": "workspace:*", + "less": "^4.1.2", + "sass": "^1.43.4" + }, + "dependencies": { + "vue": "^3.2.31" + } +} diff --git a/packages/playground/vue-sourcemap/sassWithImportImported.sass b/packages/playground/vue-sourcemap/sassWithImportImported.sass new file mode 100644 index 00000000000000..8092b37048cbdd --- /dev/null +++ b/packages/playground/vue-sourcemap/sassWithImportImported.sass @@ -0,0 +1,2 @@ +.sass-with-import-imported + color: red diff --git a/packages/playground/vue-sourcemap/src-import/SrcImport.vue b/packages/playground/vue-sourcemap/src-import/SrcImport.vue new file mode 100644 index 00000000000000..406c6a6b45382d --- /dev/null +++ b/packages/playground/vue-sourcemap/src-import/SrcImport.vue @@ -0,0 +1,8 @@ + + + + diff --git a/packages/playground/vue-sourcemap/src-import/src-import-imported.sass b/packages/playground/vue-sourcemap/src-import/src-import-imported.sass new file mode 100644 index 00000000000000..2ed87d933e58a6 --- /dev/null +++ b/packages/playground/vue-sourcemap/src-import/src-import-imported.sass @@ -0,0 +1,2 @@ +.src-import-sass-imported + color: red diff --git a/packages/playground/vue-sourcemap/src-import/src-import.css b/packages/playground/vue-sourcemap/src-import/src-import.css new file mode 100644 index 00000000000000..da61ff0fb6cb27 --- /dev/null +++ b/packages/playground/vue-sourcemap/src-import/src-import.css @@ -0,0 +1,3 @@ +.src-import { + color: red; +} diff --git a/packages/playground/vue-sourcemap/src-import/src-import.sass b/packages/playground/vue-sourcemap/src-import/src-import.sass new file mode 100644 index 00000000000000..c7e0314fda541c --- /dev/null +++ b/packages/playground/vue-sourcemap/src-import/src-import.sass @@ -0,0 +1,4 @@ +@import './src-import-imported' + +.src-import-sass + color: red diff --git a/packages/playground/vue-sourcemap/vite.config.js b/packages/playground/vue-sourcemap/vite.config.js new file mode 100644 index 00000000000000..2a48cad3cb00d4 --- /dev/null +++ b/packages/playground/vue-sourcemap/vite.config.js @@ -0,0 +1,19 @@ +const vuePlugin = require('@vitejs/plugin-vue') + +/** + * @type {import('vite').UserConfig} + */ +module.exports = { + css: { + devSourcemap: true, + preprocessorOptions: { + less: { + additionalData: '@color: red;' + } + } + }, + plugins: [vuePlugin()], + build: { + sourcemap: true + } +} diff --git a/packages/playground/vue/Main.vue b/packages/playground/vue/Main.vue index d10ae401f7aa8e..87319acdf6f736 100644 --- a/packages/playground/vue/Main.vue +++ b/packages/playground/vue/Main.vue @@ -20,6 +20,7 @@ + diff --git a/packages/playground/vue/workerTest.js b/packages/playground/vue/workerTest.js new file mode 100644 index 00000000000000..fcde5e19b30677 --- /dev/null +++ b/packages/playground/vue/workerTest.js @@ -0,0 +1 @@ +self.postMessage('worker load!') diff --git a/packages/playground/wasm/__tests__/wasm.spec.ts b/packages/playground/wasm/__tests__/wasm.spec.ts index b292f0ddc6e7f8..112617212251fa 100644 --- a/packages/playground/wasm/__tests__/wasm.spec.ts +++ b/packages/playground/wasm/__tests__/wasm.spec.ts @@ -9,3 +9,7 @@ test('should work when output', async () => { await page.click('.output-wasm .run') await untilUpdated(() => page.textContent('.output-wasm .result'), '24') }) + +test('should work when wasm in worker', async () => { + await untilUpdated(() => page.textContent('.worker-wasm .result'), '3') +}) diff --git a/packages/playground/wasm/add.wasm b/packages/playground/wasm/add.wasm new file mode 100644 index 00000000000000..76e95b227902b0 Binary files /dev/null and b/packages/playground/wasm/add.wasm differ diff --git a/packages/playground/wasm/index.html b/packages/playground/wasm/index.html index 27bdc8167e064e..ecb0b66e913fbb 100644 --- a/packages/playground/wasm/index.html +++ b/packages/playground/wasm/index.html @@ -12,9 +12,20 @@

When wasm is output, result should be 24

+
+

worker wasm

+ +
+ + .classname { + color: green; + } + + diff --git a/packages/playground/worker/module-and-worker.js b/packages/playground/worker/module-and-worker.js new file mode 100644 index 00000000000000..659e556f08e4a6 --- /dev/null +++ b/packages/playground/worker/module-and-worker.js @@ -0,0 +1,5 @@ +import constant from './modules/module' + +self.postMessage(constant) + +export const module = 'module and worker' diff --git a/packages/playground/worker/newUrl/module.js b/packages/playground/worker/modules/module.js similarity index 100% rename from packages/playground/worker/newUrl/module.js rename to packages/playground/worker/modules/module.js diff --git a/packages/playground/worker/modules/module1.js b/packages/playground/worker/modules/module1.js new file mode 100644 index 00000000000000..191db09d29c44f --- /dev/null +++ b/packages/playground/worker/modules/module1.js @@ -0,0 +1 @@ +export const msg1 = 'module1' diff --git a/packages/playground/worker/modules/module2.js b/packages/playground/worker/modules/module2.js new file mode 100644 index 00000000000000..60447933b8b16e --- /dev/null +++ b/packages/playground/worker/modules/module2.js @@ -0,0 +1,3 @@ +export * from './module' +export * from './module1' +export const msg2 = 'module2' diff --git a/packages/playground/worker/modules/module3.js b/packages/playground/worker/modules/module3.js new file mode 100644 index 00000000000000..33355423bc030e --- /dev/null +++ b/packages/playground/worker/modules/module3.js @@ -0,0 +1,2 @@ +export * from './module' +export const msg3 = 'module3' diff --git a/packages/playground/worker/test-plugin.tsx b/packages/playground/worker/modules/test-plugin.tsx similarity index 100% rename from packages/playground/worker/test-plugin.tsx rename to packages/playground/worker/modules/test-plugin.tsx diff --git a/packages/playground/worker/workerImport.js b/packages/playground/worker/modules/workerImport.js similarity index 100% rename from packages/playground/worker/workerImport.js rename to packages/playground/worker/modules/workerImport.js diff --git a/packages/playground/worker/my-worker.ts b/packages/playground/worker/my-worker.ts index 550382be72c331..dd6061885128c7 100644 --- a/packages/playground/worker/my-worker.ts +++ b/packages/playground/worker/my-worker.ts @@ -1,5 +1,5 @@ -import { msg, mode } from './workerImport' -import { bundleWithPlugin } from './test-plugin' +import { msg, mode } from './modules/workerImport' +import { bundleWithPlugin } from './modules/test-plugin' self.onmessage = (e) => { if (e.data === 'ping') { diff --git a/packages/playground/worker/newUrl/url-worker.js b/packages/playground/worker/newUrl/url-worker.js deleted file mode 100644 index afd91bfe613dc2..00000000000000 --- a/packages/playground/worker/newUrl/url-worker.js +++ /dev/null @@ -1,3 +0,0 @@ -import constant from './module' - -self.postMessage(constant) diff --git a/packages/playground/worker/package.json b/packages/playground/worker/package.json index 131df8c4cbf336..ba4e7fe87e4a98 100644 --- a/packages/playground/worker/package.json +++ b/packages/playground/worker/package.json @@ -5,8 +5,20 @@ "scripts": { "dev": "vite", "build": "vite build", - "debug": "node --inspect-brk ../../vite/bin/vite", - "preview": "vite preview" + "preview": "vite 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", + "dev:sourcemap": "cross-env WORKER_MODE=sourcemap vite --config ./vite.config-sourcemap.js dev", + "build:sourcemap": "cross-env WORKER_MODE=sourcemap vite --config ./vite.config-sourcemap.js build", + "preview:sourcemap": "cross-env WORKER_MODE=sourcemap vite --config ./vite.config-sourcemap.js preview", + "dev:sourcemap-hidden": "cross-env WORKER_MODE=hidden vite --config ./vite.config-sourcemap.js dev", + "build:sourcemap-hidden": "cross-env WORKER_MODE=hidden vite --config ./vite.config-sourcemap.js build", + "preview:sourcemap-hidden": "cross-env WORKER_MODE=hidden vite --config ./vite.config-sourcemap.js preview", + "dev:sourcemap-inline": "cross-env WORKER_MODE=inline vite --config ./vite.config-sourcemap.js dev", + "build:sourcemap-inline": "cross-env WORKER_MODE=inline vite --config ./vite.config-sourcemap.js build", + "preview:sourcemap-inline": "cross-env WORKER_MODE=inline vite --config ./vite.config-sourcemap.js preview", + "debug": "node --inspect-brk ../../vite/bin/vite" }, "devDependencies": { "@vitejs/plugin-vue-jsx": "workspace:*" diff --git a/packages/playground/worker/possible-ts-output-worker.mjs b/packages/playground/worker/possible-ts-output-worker.mjs index 2bcce3faa8a50e..25f1a447617cd9 100644 --- a/packages/playground/worker/possible-ts-output-worker.mjs +++ b/packages/playground/worker/possible-ts-output-worker.mjs @@ -1,4 +1,4 @@ -import { msg, mode } from './workerImport' +import { msg, mode } from './modules/workerImport' self.onmessage = (e) => { if (e.data === 'ping') { diff --git a/packages/playground/worker/public/classic.js b/packages/playground/worker/public/classic.js new file mode 100644 index 00000000000000..c074cc050c2587 --- /dev/null +++ b/packages/playground/worker/public/classic.js @@ -0,0 +1 @@ +self.constant = 'A classic' diff --git a/packages/playground/worker/sub-worker.js b/packages/playground/worker/sub-worker.js new file mode 100644 index 00000000000000..eff49dfbb46ba6 --- /dev/null +++ b/packages/playground/worker/sub-worker.js @@ -0,0 +1,5 @@ +self.onmessage = (event) => { + if (event.data === 'ping') { + self.postMessage(`pong ${import.meta.url}`) + } +} diff --git a/packages/playground/worker/newUrl/url-shared-worker.js b/packages/playground/worker/url-shared-worker.js similarity index 69% rename from packages/playground/worker/newUrl/url-shared-worker.js rename to packages/playground/worker/url-shared-worker.js index f52de169243056..3535d5c277ec84 100644 --- a/packages/playground/worker/newUrl/url-shared-worker.js +++ b/packages/playground/worker/url-shared-worker.js @@ -1,4 +1,4 @@ -import constant from './module' +import constant from './modules/module' self.onconnect = (event) => { const port = event.ports[0] diff --git a/packages/playground/worker/url-worker.js b/packages/playground/worker/url-worker.js new file mode 100644 index 00000000000000..c25cbefdff89ec --- /dev/null +++ b/packages/playground/worker/url-worker.js @@ -0,0 +1 @@ +self.postMessage('A string' + import.meta.env.BASE_URL + import.meta.url) diff --git a/packages/playground/worker/vite.config-es.js b/packages/playground/worker/vite.config-es.js new file mode 100644 index 00000000000000..a65dece2d0db21 --- /dev/null +++ b/packages/playground/worker/vite.config-es.js @@ -0,0 +1,29 @@ +const vueJsx = require('@vitejs/plugin-vue-jsx') +const vite = require('vite') +const path = require('path') + +module.exports = vite.defineConfig({ + base: '/es/', + enforce: 'pre', + worker: { + format: 'es', + plugins: [vueJsx()] + }, + build: { + outDir: 'dist/es' + }, + plugins: [ + { + name: 'resolve-format-es', + + transform(code, id) { + if (id.includes('main.js')) { + return code.replace( + `/* flag: will replace in vite config import("./format-es.js") */`, + `import("./main-format-es")` + ) + } + } + } + ] +}) diff --git a/packages/playground/worker/vite.config-sourcemap.js b/packages/playground/worker/vite.config-sourcemap.js new file mode 100644 index 00000000000000..ea1c66a33a44d7 --- /dev/null +++ b/packages/playground/worker/vite.config-sourcemap.js @@ -0,0 +1,24 @@ +const vueJsx = require('@vitejs/plugin-vue-jsx') +const vite = require('vite') + +module.exports = vite.defineConfig((sourcemap) => { + sourcemap = process.env.WORKER_MODE || sourcemap + if (sourcemap === 'sourcemap') { + sourcemap = true + } + return { + base: `/iife-${ + typeof sourcemap === 'boolean' ? 'sourcemap' : 'sourcemap-' + sourcemap + }/`, + worker: { + format: 'iife', + plugins: [vueJsx()] + }, + build: { + outDir: `dist/iife-${ + typeof sourcemap === 'boolean' ? 'sourcemap' : 'sourcemap-' + sourcemap + }/`, + sourcemap: sourcemap + } + } +}) diff --git a/packages/playground/worker/vite.config.js b/packages/playground/worker/vite.config.js new file mode 100644 index 00000000000000..b7760bc4d7a240 --- /dev/null +++ b/packages/playground/worker/vite.config.js @@ -0,0 +1,13 @@ +const vueJsx = require('@vitejs/plugin-vue-jsx') +const vite = require('vite') + +module.exports = vite.defineConfig({ + base: '/iife/', + worker: { + format: 'iife', + plugins: [vueJsx()] + }, + build: { + outDir: 'dist/iife' + } +}) diff --git a/packages/playground/worker/vite.config.ts b/packages/playground/worker/vite.config.ts deleted file mode 100644 index 6bf980f46e2362..00000000000000 --- a/packages/playground/worker/vite.config.ts +++ /dev/null @@ -1,11 +0,0 @@ -import vueJsx from '@vitejs/plugin-vue-jsx' -import { defineConfig } from 'vite' - -export default defineConfig({ - build: { - target: process.env.NODE_ENV === 'production' ? 'chrome60' : 'esnext' - }, - worker: { - plugins: [vueJsx()] - } -}) diff --git a/packages/playground/worker/worker-nested-worker.js b/packages/playground/worker/worker-nested-worker.js new file mode 100644 index 00000000000000..6d4d1e4969005f --- /dev/null +++ b/packages/playground/worker/worker-nested-worker.js @@ -0,0 +1,13 @@ +import SubWorker from './sub-worker?worker' + +const subWorker = new SubWorker() + +self.onmessage = (event) => { + if (event.data === 'ping') { + subWorker.postMessage('ping') + } +} + +subWorker.onmessage = (event) => { + self.postMessage(event.data) +} diff --git a/packages/playground/worker/worker/main-classic.js b/packages/playground/worker/worker/main-classic.js new file mode 100644 index 00000000000000..4ef7776a56876e --- /dev/null +++ b/packages/playground/worker/worker/main-classic.js @@ -0,0 +1,28 @@ +// prettier-ignore +function text(el, text) { + document.querySelector(el).textContent = text +} + +let classicWorker = new Worker( + new URL('../classic-worker.js', import.meta.url) /* , */ + // test comment +) + +// just test for case: ') ... ,' mean no worker options parmas +classicWorker = new Worker(new URL('../classic-worker.js', import.meta.url)) + +classicWorker.addEventListener('message', ({ data }) => { + text('.classic-worker', JSON.stringify(data)) +}) +classicWorker.postMessage('ping') + +const classicSharedWorker = new SharedWorker( + new URL('../classic-shared-worker.js', import.meta.url), + { + type: 'classic' + } +) +classicSharedWorker.port.addEventListener('message', (ev) => { + text('.classic-shared-worker', JSON.stringify(ev.data)) +}) +classicSharedWorker.port.start() diff --git a/packages/playground/worker/worker/main-format-es.js b/packages/playground/worker/worker/main-format-es.js new file mode 100644 index 00000000000000..801c13469151a3 --- /dev/null +++ b/packages/playground/worker/worker/main-format-es.js @@ -0,0 +1,41 @@ +// run when format es +import NestedWorker from '../emit-chunk-nested-worker?worker' + +function text(el, text) { + document.querySelector(el).textContent = text +} + +text('.format-es', 'format es:') + +const nestedWorker = new NestedWorker() +const dataList = [] +nestedWorker.addEventListener('message', (ev) => { + dataList.push(ev.data) + text( + '.emti-chunk-worker', + JSON.stringify( + dataList.sort( + (a, b) => JSON.stringify(a).length - JSON.stringify(b).length + ) + ) + ) +}) + +const dynamicImportWorker = new Worker( + new URL('../emit-chunk-dynamic-import-worker.js', import.meta.url), + { + type: 'module' + } +) +dynamicImportWorker.addEventListener('message', (ev) => { + text('.emti-chunk-dynamic-import-worker', JSON.stringify(ev.data)) +}) + +const moduleWorker = new Worker( + new URL('../module-and-worker.js', import.meta.url), + { type: 'module' } +) + +moduleWorker.addEventListener('message', (ev) => { + text('.module-and-worker-worker', JSON.stringify(ev.data)) +}) diff --git a/packages/playground/worker/worker/main-module.js b/packages/playground/worker/worker/main-module.js new file mode 100644 index 00000000000000..417cf1728c4b09 --- /dev/null +++ b/packages/playground/worker/worker/main-module.js @@ -0,0 +1,85 @@ +import myWorker from '../my-worker?worker' +import InlineWorker from '../my-worker?worker&inline' +import mySharedWorker from '../my-shared-worker?sharedworker&name=shared' +import TSOutputWorker from '../possible-ts-output-worker?worker' +import NestedWorker from '../worker-nested-worker?worker' +import { mode } from '../modules/workerImport' + +function text(el, text) { + document.querySelector(el).textContent = text +} + +document.querySelector('.mode-true').textContent = mode + +const worker = new myWorker() +worker.addEventListener('message', (e) => { + text('.pong', e.data.msg) + text('.mode', e.data.mode) + text('.bundle-with-plugin', e.data.bundleWithPlugin) +}) + +document.querySelector('.ping').addEventListener('click', () => { + worker.postMessage('ping') +}) + +const inlineWorker = new InlineWorker() +inlineWorker.addEventListener('message', (e) => { + text('.pong-inline', e.data.msg) +}) + +document.querySelector('.ping-inline').addEventListener('click', () => { + console.log('111') + inlineWorker.postMessage('ping') +}) + +const sharedWorker = new mySharedWorker() +document.querySelector('.tick-shared').addEventListener('click', () => { + sharedWorker.port.postMessage('tick') +}) + +sharedWorker.port.addEventListener('message', (event) => { + text('.tick-count', event.data) +}) + +sharedWorker.port.start() + +const tsOutputWorker = new TSOutputWorker() +tsOutputWorker.addEventListener('message', (e) => { + text('.pong-ts-output', e.data.msg) +}) + +document.querySelector('.ping-ts-output').addEventListener('click', () => { + tsOutputWorker.postMessage('ping') +}) + +const nestedWorker = new NestedWorker() +nestedWorker.addEventListener('message', (ev) => { + if (typeof ev.data === 'string') { + text('.nested-worker', JSON.stringify(ev.data)) + } +}) +nestedWorker.postMessage('ping') + +const workerOptions = { type: 'module' } +// url import worker +const w = new Worker( + new URL('../url-worker.js', import.meta.url), + /* @vite-ignore */ workerOptions +) +w.addEventListener('message', (ev) => + text('.worker-import-meta-url', JSON.stringify(ev.data)) +) + +const genWorkerName = () => 'module' +const w2 = new SharedWorker( + new URL('../url-shared-worker.js', import.meta.url), + { + /* @vite-ignore */ + name: genWorkerName(), + type: 'module' + } +) +w2.port.addEventListener('message', (ev) => { + text('.shared-worker-import-meta-url', JSON.stringify(ev.data)) +}) +w2.port.start() diff --git a/packages/playground/worker/worker/main.js b/packages/playground/worker/worker/main.js new file mode 100644 index 00000000000000..953b5ef1bf3b53 --- /dev/null +++ b/packages/playground/worker/worker/main.js @@ -0,0 +1,3 @@ +/* flag: will replace in vite config import("./format-es.js") */ +import('./main-module') +import('./main-classic') diff --git a/packages/plugin-legacy/CHANGELOG.md b/packages/plugin-legacy/CHANGELOG.md index e92ca1e12357fe..ced87d2efd665c 100644 --- a/packages/plugin-legacy/CHANGELOG.md +++ b/packages/plugin-legacy/CHANGELOG.md @@ -1,3 +1,17 @@ +## 1.8.0 (2022-03-30) + +* fix(deps): update all non-major dependencies (#6782) ([e38be3e](https://github.com/vitejs/vite/commit/e38be3e)), closes [#6782](https://github.com/vitejs/vite/issues/6782) +* fix(deps): update all non-major dependencies (#7392) ([b63fc3b](https://github.com/vitejs/vite/commit/b63fc3b)), closes [#7392](https://github.com/vitejs/vite/issues/7392) +* fix(plugin-legacy): always fallback legacy build when CSP (#6535) ([a118a1d](https://github.com/vitejs/vite/commit/a118a1d)), closes [#6535](https://github.com/vitejs/vite/issues/6535) +* fix(plugin-legacy): polyfill latest features (#7514) ([cb388e2](https://github.com/vitejs/vite/commit/cb388e2)), closes [#7514](https://github.com/vitejs/vite/issues/7514) +* fix(plugin-legacy): require Vite 2.8.0 (#6272) (#6869) ([997b8f1](https://github.com/vitejs/vite/commit/997b8f1)), closes [#6272](https://github.com/vitejs/vite/issues/6272) [#6869](https://github.com/vitejs/vite/issues/6869) +* chore(deps): update all non-major dependencies (#6905) ([839665c](https://github.com/vitejs/vite/commit/839665c)), closes [#6905](https://github.com/vitejs/vite/issues/6905) +* docs(vite-legacy): Note about using `regenerator-runtime` in Content Security Policy environment (#7 ([0fd6422](https://github.com/vitejs/vite/commit/0fd6422)), closes [#7234](https://github.com/vitejs/vite/issues/7234) +* workflow: separate version bumping and publishing on release (#6879) ([fe8ef39](https://github.com/vitejs/vite/commit/fe8ef39)), closes [#6879](https://github.com/vitejs/vite/issues/6879) +* release: plugin-legacy@1.7.1 ([19a58dd](https://github.com/vitejs/vite/commit/19a58dd)) + + + ## [1.7.1](https://github.com/vitejs/vite/compare/plugin-legacy@1.7.0...plugin-legacy@1.7.1) (2022-02-11) ### Bug Fixes diff --git a/packages/plugin-legacy/README.md b/packages/plugin-legacy/README.md index c56b769061e267..ec7e630c87755a 100644 --- a/packages/plugin-legacy/README.md +++ b/packages/plugin-legacy/README.md @@ -165,7 +165,9 @@ The legacy plugin requires inline scripts for [Safari 10.1 `nomodule` fix](https - `sha256-MS6/3FCg4WjP9gwgaBGwLpRCY6fZBgwmhVCdrPrNf3E=` - `sha256-tQjf8gvb2ROOMapIxFvFAYBeUJ0v1HCbOcSmDNXGtDo=` -- `sha256-T9h4ixy0FtNsCwAyTfBtIY6uV5ZhMeNQIlL42GAKEME=` +- `sha256-xYj09txJ9OsgySe5ommpqul6FiaJZRrwe3KTD7wbV6w=` +- `sha256-4m6wOIrq/wFDmi9Xh3mFM2mwI4ik9n3TMgHk6xDtLxk=` +- `sha256-uS7/g9fhQwNZS1f/MqYqqKv8y9hCu36IfX9XZB5L7YY=` These values (without the `sha256-` prefix) can also be retrieved via @@ -173,6 +175,8 @@ These values (without the `sha256-` prefix) can also be retrieved via const { cspHashes } = require('@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. + ## References - [Vue CLI modern mode](https://cli.vuejs.org/guide/browser-compatibility.html#modern-mode) diff --git a/packages/plugin-legacy/index.js b/packages/plugin-legacy/index.js index b66c4714e19c09..41f7157ebfc533 100644 --- a/packages/plugin-legacy/index.js +++ b/packages/plugin-legacy/index.js @@ -18,7 +18,11 @@ const safari10NoModuleFix = `!function(){var e=document,t=e.createElement("scrip const legacyPolyfillId = 'vite-legacy-polyfill' const legacyEntryId = 'vite-legacy-entry' const systemJSInlineCode = `System.import(document.getElementById('${legacyEntryId}').getAttribute('data-src'))` -const dynamicFallbackInlineCode = `!function(){try{new Function("m","return import(m)")}catch(o){console.warn("vite: loading legacy build because dynamic import is unsupported, syntax error above should be ignored");var e=document.getElementById("${legacyPolyfillId}"),n=document.createElement("script");n.src=e.src,n.onload=function(){${systemJSInlineCode}},document.body.appendChild(n)}}();` + +const detectDynamicImportVarName = '__vite_is_dynamic_import_support' +const detectDynamicImportVarInitCode = `var ${detectDynamicImportVarName}=false;` +const detectDynamicImportCode = `try{import("_").catch(()=>1);}catch(e){}window.${detectDynamicImportVarName}=true;` +const dynamicFallbackInlineCode = `!function(){if(window.${detectDynamicImportVarName})return;console.warn("vite: loading legacy build because dynamic import is unsupported, syntax error above should be ignored");var e=document.getElementById("${legacyPolyfillId}"),n=document.createElement("script");n.src=e.src,n.onload=function(){${systemJSInlineCode}},document.body.appendChild(n)}();` const forceDynamicImportUsage = `export function __vite_legacy_guard(){import('data:text/javascript,')};` @@ -326,7 +330,10 @@ function viteLegacyPlugin(options = {}) { loose: false, useBuiltIns: needPolyfills ? 'usage' : false, corejs: needPolyfills - ? { version: 3, proposals: false } + ? { + version: require('core-js/package.json').version, + proposals: false + } : undefined, shippedProposals: true, ignoreBrowserslistConfig: options.ignoreBrowserslistConfig @@ -430,6 +437,18 @@ function viteLegacyPlugin(options = {}) { // 5. inject dynamic import fallback entry if (genDynamicFallback && legacyPolyfillFilename && legacyEntryFilename) { + tags.push({ + tag: 'script', + attrs: { type: 'module' }, + children: detectDynamicImportVarInitCode, + injectTo: 'head' + }) + tags.push({ + tag: 'script', + attrs: { type: 'module' }, + children: detectDynamicImportCode, + injectTo: 'head' + }) tags.push({ tag: 'script', attrs: { type: 'module' }, @@ -695,5 +714,7 @@ viteLegacyPlugin.default = viteLegacyPlugin viteLegacyPlugin.cspHashes = [ createHash('sha256').update(safari10NoModuleFix).digest('base64'), createHash('sha256').update(systemJSInlineCode).digest('base64'), + createHash('sha256').update(detectDynamicImportVarInitCode).digest('base64'), + createHash('sha256').update(detectDynamicImportCode).digest('base64'), createHash('sha256').update(dynamicFallbackInlineCode).digest('base64') ] diff --git a/packages/plugin-legacy/package.json b/packages/plugin-legacy/package.json index e464c18b4dca1d..aa8c478e4dae18 100644 --- a/packages/plugin-legacy/package.json +++ b/packages/plugin-legacy/package.json @@ -1,6 +1,6 @@ { "name": "@vitejs/plugin-legacy", - "version": "1.7.1", + "version": "1.8.0", "license": "MIT", "author": "Evan You", "files": [ @@ -22,9 +22,9 @@ }, "homepage": "https://github.com/vitejs/vite/tree/main/packages/plugin-legacy#readme", "dependencies": { - "@babel/standalone": "^7.17.2", - "core-js": "^3.21.0", - "magic-string": "^0.25.7", + "@babel/standalone": "^7.17.8", + "core-js": "^3.21.1", + "magic-string": "^0.26.1", "regenerator-runtime": "^0.13.9", "systemjs": "^6.12.1" }, diff --git a/packages/plugin-react/CHANGELOG.md b/packages/plugin-react/CHANGELOG.md index b1d1b8bddba63e..c05c0989d6beb4 100644 --- a/packages/plugin-react/CHANGELOG.md +++ b/packages/plugin-react/CHANGELOG.md @@ -1,3 +1,14 @@ +## 1.3.0 (2022-03-30) + +* feat(plugin-react): adding jsxPure option (#7088) ([d451435](https://github.com/vitejs/vite/commit/d451435)), closes [#7088](https://github.com/vitejs/vite/issues/7088) +* fix(deps): update all non-major dependencies (#6782) ([e38be3e](https://github.com/vitejs/vite/commit/e38be3e)), closes [#6782](https://github.com/vitejs/vite/issues/6782) +* fix(deps): update all non-major dependencies (#7392) ([b63fc3b](https://github.com/vitejs/vite/commit/b63fc3b)), closes [#7392](https://github.com/vitejs/vite/issues/7392) +* chore: fix publish, build vite before plugin-react and plugin-vue (#6988) ([620a9bd](https://github.com/vitejs/vite/commit/620a9bd)), closes [#6988](https://github.com/vitejs/vite/issues/6988) +* chore(deps): update all non-major dependencies (#6905) ([839665c](https://github.com/vitejs/vite/commit/839665c)), closes [#6905](https://github.com/vitejs/vite/issues/6905) +* workflow: separate version bumping and publishing on release (#6879) ([fe8ef39](https://github.com/vitejs/vite/commit/fe8ef39)), closes [#6879](https://github.com/vitejs/vite/issues/6879) + + + # [1.2.0](https://github.com/vitejs/vite/compare/plugin-react@1.1.4...plugin-react@1.2.0) (2022-02-09) diff --git a/packages/plugin-react/README.md b/packages/plugin-react/README.md index 588f947ec8b08c..e8d27d0e57242b 100644 --- a/packages/plugin-react/README.md +++ b/packages/plugin-react/README.md @@ -75,7 +75,7 @@ react({ }) ``` -This option does not enable _code transformation_. That is handled by ESBuild. +This option does not enable _code transformation_. That is handled by esbuild. **Note:** TypeScript syntax is handled automatically. diff --git a/packages/plugin-react/package.json b/packages/plugin-react/package.json index 67df1d30b89b0c..8313fc5a81d648 100644 --- a/packages/plugin-react/package.json +++ b/packages/plugin-react/package.json @@ -1,6 +1,6 @@ { "name": "@vitejs/plugin-react", - "version": "1.2.0", + "version": "1.3.0", "license": "MIT", "author": "Evan You", "contributors": [ @@ -18,7 +18,7 @@ "build-bundle": "esbuild src/index.ts --bundle --platform=node --target=node12 --external:@babel/* --external:@rollup/* --external:resolve --external:react-refresh/* --outfile=dist/index.js && npm run patch-dist", "patch-dist": "ts-node ../../scripts/patchEsbuildDist.ts dist/index.js viteReact", "build-types": "tsc -p . --emitDeclarationOnly --outDir temp && api-extractor run && rimraf temp", - "prepublishOnly": "npm run build" + "prepublishOnly": "(cd ../vite && npm run build) && npm run build" }, "engines": { "node": ">=12.0.0" @@ -33,12 +33,12 @@ }, "homepage": "https://github.com/vitejs/vite/tree/main/packages/plugin-react#readme", "dependencies": { - "@babel/core": "^7.17.2", - "@babel/plugin-transform-react-jsx": "^7.16.7", + "@babel/core": "^7.17.8", + "@babel/plugin-transform-react-jsx": "^7.17.3", "@babel/plugin-transform-react-jsx-development": "^7.16.7", "@babel/plugin-transform-react-jsx-self": "^7.16.7", "@babel/plugin-transform-react-jsx-source": "^7.16.7", - "@rollup/pluginutils": "^4.1.2", + "@rollup/pluginutils": "^4.2.0", "react-refresh": "^0.11.0", "resolve": "^1.22.0" } diff --git a/packages/plugin-react/src/index.ts b/packages/plugin-react/src/index.ts index afa1e2c5422da2..76f6c6c2a799f3 100644 --- a/packages/plugin-react/src/index.ts +++ b/packages/plugin-react/src/index.ts @@ -32,6 +32,12 @@ export interface Options { * @default "react" */ jsxImportSource?: string + /** + * Set this to `true` to annotate the JSX factory with `\/* @__PURE__ *\/`. + * This option is ignored when `jsxRuntime` is not `"automatic"`. + * @default true + */ + jsxPure?: boolean /** * Babel configuration applied in both dev and prod. @@ -195,7 +201,8 @@ export default function viteReact(opts: Options = {}): PluginOption[] { ), { runtime: 'automatic', - importSource: opts.jsxImportSource + importSource: opts.jsxImportSource, + pure: opts.jsxPure !== false } ]) diff --git a/packages/plugin-vue-jsx/CHANGELOG.md b/packages/plugin-vue-jsx/CHANGELOG.md index 0ad338dbd211eb..3a1b9e681b45ea 100644 --- a/packages/plugin-vue-jsx/CHANGELOG.md +++ b/packages/plugin-vue-jsx/CHANGELOG.md @@ -1,3 +1,14 @@ +## 1.3.9 (2022-03-30) + +* fix(deps): update all non-major dependencies (#7392) ([b63fc3b](https://github.com/vitejs/vite/commit/b63fc3b)), closes [#7392](https://github.com/vitejs/vite/issues/7392) +* chore(deps): update all non-major dependencies (#6905) ([839665c](https://github.com/vitejs/vite/commit/839665c)), closes [#6905](https://github.com/vitejs/vite/issues/6905) + + + +## [1.3.8](https://github.com/vitejs/vite/compare/plugin-vue@2.2.4...plugin-vue@1.3.8) (2022-02-28) + + + ## [1.3.7](https://github.com/vitejs/vite/compare/plugin-vue@2.2.0...plugin-vue@1.3.7) (2022-02-14) diff --git a/packages/plugin-vue-jsx/index.js b/packages/plugin-vue-jsx/index.js index 56c50fe2ff5e6d..248270765d19a1 100644 --- a/packages/plugin-vue-jsx/index.js +++ b/packages/plugin-vue-jsx/index.js @@ -95,10 +95,13 @@ function vueJsxPlugin(options = {}) { } = options const filter = createFilter(include || /\.[jt]sx$/, exclude) + const [filepath] = id.split('?') - if (filter(id)) { + // use id for script blocks in Vue SFCs (e.g. `App.vue?vue&type=script&lang.jsx`) + // use filepath for plain jsx files (e.g. App.jsx) + if (filter(id) || filter(filepath)) { const plugins = [importMeta, [jsx, babelPluginOptions], ...babelPlugins] - if (id.endsWith('.tsx')) { + if (id.endsWith('.tsx') || filepath.endsWith('.tsx')) { plugins.push([ require('@babel/plugin-transform-typescript'), // @ts-ignore diff --git a/packages/plugin-vue-jsx/package.json b/packages/plugin-vue-jsx/package.json index f8289b79f4c445..c6a352eccc99a0 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": "1.3.7", + "version": "1.3.9", "license": "MIT", "author": "Evan You", "files": [ @@ -22,10 +22,10 @@ }, "homepage": "https://github.com/vitejs/vite/tree/main/packages/plugin-vue-jsx#readme", "dependencies": { - "@babel/core": "^7.17.2", + "@babel/core": "^7.17.8", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-transform-typescript": "^7.16.8", - "@rollup/pluginutils": "^4.1.2", + "@rollup/pluginutils": "^4.2.0", "@vue/babel-plugin-jsx": "^1.1.1", "hash-sum": "^2.0.0" } diff --git a/packages/plugin-vue/CHANGELOG.md b/packages/plugin-vue/CHANGELOG.md index 7fb8174fe7600f..135daffbfaaa67 100644 --- a/packages/plugin-vue/CHANGELOG.md +++ b/packages/plugin-vue/CHANGELOG.md @@ -1,3 +1,53 @@ +## 2.3.1 (2022-03-30) + +* chore(plugin-vue): revert #7527, lower vite peer dep ([447bbeb](https://github.com/vitejs/vite/commit/447bbeb)), closes [#7527](https://github.com/vitejs/vite/issues/7527) + + + +## 2.3.0 (2022-03-30) + +* chore(plugin-vue): bump vite peer dep to 2.9.0 (#7472) ([12fd1d9](https://github.com/vitejs/vite/commit/12fd1d9)), closes [#7472](https://github.com/vitejs/vite/issues/7472) +* feat(css): css.devSourcemap option (#7471) ([57f14cb](https://github.com/vitejs/vite/commit/57f14cb)), closes [#7471](https://github.com/vitejs/vite/issues/7471) +* fix(plugin-vue): respect __VUE_PROD_DEVTOOLS__ setting (#4984) ([90e812a](https://github.com/vitejs/vite/commit/90e812a)), closes [#4984](https://github.com/vitejs/vite/issues/4984) + + + +## 2.3.0-beta.0 (2022-03-22) + +* fix(deps): update all non-major dependencies (#7392) ([b63fc3b](https://github.com/vitejs/vite/commit/b63fc3b)), closes [#7392](https://github.com/vitejs/vite/issues/7392) +* feat: css sourcemap support during dev (#7173) ([38a655f](https://github.com/vitejs/vite/commit/38a655f)), closes [#7173](https://github.com/vitejs/vite/issues/7173) +* chore(deps): update all non-major dependencies (#6905) ([839665c](https://github.com/vitejs/vite/commit/839665c)), closes [#6905](https://github.com/vitejs/vite/issues/6905) +* docs(vue): add transformAssetUrls example (#7232) ([08e928c](https://github.com/vitejs/vite/commit/08e928c)), closes [#7232](https://github.com/vitejs/vite/issues/7232) + + + +## [2.2.4](https://github.com/vitejs/vite/compare/plugin-vue@2.2.3...plugin-vue@2.2.4) (2022-02-28) + + + +## [2.2.3](https://github.com/vitejs/vite/compare/plugin-vue@2.2.2...plugin-vue@2.2.3) (2022-02-28) + + +### Bug Fixes + +* **plugin-vue:** setup jsx script no hmr ([#6568](https://github.com/vitejs/vite/issues/6568)) ([c84601c](https://github.com/vitejs/vite/commit/c84601cee5232bad0f65c8fcc663e38bb457a0b3)) + + + +## [2.2.2](https://github.com/vitejs/vite/compare/plugin-vue@2.2.1...plugin-vue@2.2.2) (2022-02-18) + + + +## [2.2.1](https://github.com/vitejs/vite/compare/plugin-vue@2.2.0...plugin-vue@2.2.1) (2022-02-18) + + +### Bug Fixes + +* adjust vue template sourcemap ([#6972](https://github.com/vitejs/vite/issues/6972)) ([a774303](https://github.com/vitejs/vite/commit/a7743039f263f41e1c3971e324f893a5ef5e5508)) +* **deps:** update all non-major dependencies ([#6782](https://github.com/vitejs/vite/issues/6782)) ([e38be3e](https://github.com/vitejs/vite/commit/e38be3e6ca7bf79319d5d7188e1d347b1d6091ef)) + + + # [2.2.0](https://github.com/vitejs/vite/compare/plugin-vue@2.1.0...plugin-vue@2.2.0) (2022-02-09) diff --git a/packages/plugin-vue/README.md b/packages/plugin-vue/README.md index 81ed00e7115792..a232982e8aed59 100644 --- a/packages/plugin-vue/README.md +++ b/packages/plugin-vue/README.md @@ -51,7 +51,7 @@ export interface Options { } ``` -## Example for passing options to `@vue/compiler-dom`: +## Example for passing options to `vue/compiler-sfc`: ```ts import vue from '@vitejs/plugin-vue' @@ -62,6 +62,16 @@ export default { template: { compilerOptions: { // ... + }, + transformAssetUrls: { + // default tags + tags: { + video: ['src', 'poster'], + source: ['src'], + img: ['src'], + image: ['xlink:href', 'href'], + use: ['xlink:href', 'href'] + } } } }) diff --git a/packages/plugin-vue/package.json b/packages/plugin-vue/package.json index ca8836d8e81d36..39b3bc87a8b1df 100644 --- a/packages/plugin-vue/package.json +++ b/packages/plugin-vue/package.json @@ -1,6 +1,6 @@ { "name": "@vitejs/plugin-vue", - "version": "2.2.0", + "version": "2.3.1", "license": "MIT", "author": "Evan You", "files": [ @@ -16,7 +16,7 @@ "build-bundle": "esbuild src/index.ts --bundle --platform=node --target=node12 --external:@vue/compiler-sfc --external:vue/compiler-sfc --external:vite --outfile=dist/index.js & npm run patch-dist", "patch-dist": "ts-node ../../scripts/patchEsbuildDist.ts dist/index.js vuePlugin", "build-types": "tsc -p . --emitDeclarationOnly --outDir temp && api-extractor run && rimraf temp", - "prepublishOnly": "npm run build" + "prepublishOnly": "(cd ../vite && npm run build) && npm run build" }, "engines": { "node": ">=12.0.0" @@ -35,13 +35,13 @@ "vue": "^3.2.25" }, "devDependencies": { - "@rollup/pluginutils": "^4.1.2", + "@rollup/pluginutils": "^4.2.0", "@types/hash-sum": "^1.0.0", - "debug": "^4.3.3", + "debug": "^4.3.4", "hash-sum": "^2.0.0", "rollup": "^2.59.0", "slash": "^4.0.0", "source-map": "^0.6.1", - "vue": "^3.2.30" + "vue": "^3.2.31" } } diff --git a/packages/plugin-vue/src/handleHotUpdate.ts b/packages/plugin-vue/src/handleHotUpdate.ts index 2bce3950563367..7c2a7ef7ee2f1f 100644 --- a/packages/plugin-vue/src/handleHotUpdate.ts +++ b/packages/plugin-vue/src/handleHotUpdate.ts @@ -40,9 +40,14 @@ export async function handleHotUpdate( if (hasScriptChanged(prevDescriptor, descriptor)) { let scriptModule: ModuleNode | undefined - if (descriptor.script?.lang && !descriptor.script.src) { + if ( + (descriptor.scriptSetup?.lang && !descriptor.scriptSetup.src) || + (descriptor.script?.lang && !descriptor.script.src) + ) { const scriptModuleRE = new RegExp( - `type=script.*&lang\.${descriptor.script.lang}$` + `type=script.*&lang\.${ + descriptor.scriptSetup?.lang || descriptor.script?.lang + }$` ) scriptModule = modules.find((m) => scriptModuleRE.test(m.url)) } diff --git a/packages/plugin-vue/src/index.ts b/packages/plugin-vue/src/index.ts index fb1bce3cd61132..7bdf63b700fa15 100644 --- a/packages/plugin-vue/src/index.ts +++ b/packages/plugin-vue/src/index.ts @@ -63,7 +63,9 @@ export interface ResolvedOptions extends Options { compiler: typeof _compiler root: string sourceMap: boolean + cssDevSourcemap: boolean devServer?: ViteDevServer + devToolsEnabled?: boolean } export default function vuePlugin(rawOptions: Options = {}): Plugin { @@ -97,7 +99,9 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin { customElement, reactivityTransform, root: process.cwd(), - sourceMap: true + sourceMap: true, + cssDevSourcemap: false, + devToolsEnabled: process.env.NODE_ENV !== 'production' } // Temporal handling for 2.7 breaking change @@ -135,7 +139,10 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin { ...options, root: config.root, sourceMap: config.command === 'build' ? !!config.build.sourcemap : true, - isProduction: config.isProduction + cssDevSourcemap: config.css?.devSourcemap ?? false, + isProduction: config.isProduction, + devToolsEnabled: + !!config.define!.__VUE_PROD_DEVTOOLS__ || !config.isProduction } }, @@ -235,7 +242,8 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin { descriptor, Number(query.index), options, - this + this, + filename ) } } diff --git a/packages/plugin-vue/src/main.ts b/packages/plugin-vue/src/main.ts index 3df0e664748dd5..44b1de74721efd 100644 --- a/packages/plugin-vue/src/main.ts +++ b/packages/plugin-vue/src/main.ts @@ -27,7 +27,7 @@ export async function transformMain( ssr: boolean, asCustomElement: boolean ) { - const { devServer, isProduction } = options + const { devServer, isProduction, devToolsEnabled } = options // prev descriptor is only set and used for hmr const prevDescriptor = getPrevDescriptor(filename) @@ -102,9 +102,12 @@ export async function transformMain( if (hasScoped) { attachedProps.push([`__scopeId`, JSON.stringify(`data-v-${descriptor.id}`)]) } - if (devServer && !isProduction) { + if (devToolsEnabled || (devServer && !isProduction)) { // expose filename during serve for devtools to pickup - attachedProps.push([`__file`, JSON.stringify(filename)]) + attachedProps.push([ + `__file`, + JSON.stringify(isProduction ? path.basename(filename) : filename) + ]) } // HMR @@ -159,7 +162,7 @@ export async function transformMain( const generator = SourceMapGenerator.fromSourceMap( new SourceMapConsumer(map) ) - const offset = scriptCode.match(/\r?\n/g)?.length || 1 + const offset = (scriptCode.match(/\r?\n/g)?.length ?? 0) + 1 const templateMapConsumer = new SourceMapConsumer(templateMap) templateMapConsumer.eachMapping((m) => { generator.addMapping({ diff --git a/packages/plugin-vue/src/style.ts b/packages/plugin-vue/src/style.ts index ad9d981412f52d..cab75791bd54ec 100644 --- a/packages/plugin-vue/src/style.ts +++ b/packages/plugin-vue/src/style.ts @@ -1,6 +1,8 @@ import type { SFCDescriptor } from 'vue/compiler-sfc' -import type { TransformPluginContext } from 'rollup' +import type { ExistingRawSourceMap, TransformPluginContext } from 'rollup' import type { ResolvedOptions } from '.' +import type { RawSourceMap } from 'source-map' +import { formatPostcssSourceMap } from 'vite' // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export async function transformStyle( @@ -8,7 +10,8 @@ export async function transformStyle( descriptor: SFCDescriptor, index: number, options: ResolvedOptions, - pluginContext: TransformPluginContext + pluginContext: TransformPluginContext, + filename: string ) { const block = descriptor.styles[index] // vite already handles pre-processors and CSS module so this is only @@ -19,7 +22,18 @@ export async function transformStyle( id: `data-v-${descriptor.id}`, isProd: options.isProduction, source: code, - scoped: block.scoped + scoped: block.scoped, + ...(options.cssDevSourcemap + ? { + postcssOptions: { + map: { + from: filename, + inline: false, + annotation: false + } + } + } + : {}) }) if (result.errors.length) { @@ -36,8 +50,17 @@ export async function transformStyle( return null } + const map = result.map + ? formatPostcssSourceMap( + // version property of result.map is declared as string + // but actually it is a number + result.map as Omit as ExistingRawSourceMap, + filename + ) + : ({ mappings: '' } as any) + return { code: result.code, - map: result.map || ({ mappings: '' } as any) + map: map } } diff --git a/packages/vite/CHANGELOG.md b/packages/vite/CHANGELOG.md index c2f9a3f62ed9f0..0f91a004602caa 100644 --- a/packages/vite/CHANGELOG.md +++ b/packages/vite/CHANGELOG.md @@ -1,3 +1,274 @@ +## 2.9.1 (2022-03-31) + +* fix: allow port 0 to be provided to server (#7530) ([173e4c9](https://github.com/vitejs/vite/commit/173e4c9)), closes [#7530](https://github.com/vitejs/vite/issues/7530) +* fix: brotli let for reassignment (#7544) ([d0253d7](https://github.com/vitejs/vite/commit/d0253d7)), closes [#7544](https://github.com/vitejs/vite/issues/7544) +* fix: dynamic import warning with @vite-ignore (#7533) ([29c1ec0](https://github.com/vitejs/vite/commit/29c1ec0)), closes [#7533](https://github.com/vitejs/vite/issues/7533) +* fix: remove unneeded skipping optimization log (#7531) ([41fa2f5](https://github.com/vitejs/vite/commit/41fa2f5)), closes [#7531](https://github.com/vitejs/vite/issues/7531) +* docs(changelog): fix raw glob imports syntax (#7540) ([87fbe13](https://github.com/vitejs/vite/commit/87fbe13)), closes [#7540](https://github.com/vitejs/vite/issues/7540) +* chore: 2.9 release notes (#7525) ([4324f48](https://github.com/vitejs/vite/commit/4324f48)), closes [#7525](https://github.com/vitejs/vite/issues/7525) + + + +# [2.9.0](https://github.com/vitejs/vite/compare/v2.8.6...v2.9.0) (2022-03-30) + +### Faster Cold Start + +Before 2.9, the first time dev was run on a project Vite needed to perform a scan phase to discover dependencies and then pre-bundle them before starting the server. In 2.9 both scanning [#7379](https://github.com/vitejs/vite/issues/7379) and pre-bundling [#6758](https://github.com/vitejs/vite/issues/6758) of dependencies are now non-blocking, so the server starts right away during cold start. We also now allow requests to flow through the pipeline improving initial cold start load speed and increasing the chances of discovering new missing dependencies when re-processing and letting Vite populate the module graph and the browser to process files. In many cases, there is also no need to full-reload the page when new dependencies are discovered. + +### CSS Sourcemap support during dev (experimental) + +Vite now supports CSS sourcemaps [#7173](https://github.com/vitejs/vite/issues/7173). This feature is still experimental, and it is disabled by default to avoid incurring a performance penalty for users that don't need it. To enable it, set [css.devSourcemap](https://vitejs.dev/config/#css-devsourcemap) to `true`. + +### Avoid splitting vendor chunks by default + +Vite's default chunking strategy was a good fit for most SPAs, but it wasn't ideal in some other use cases. Vite doesn't have enough context to make the best decision here, so in Vite 2.9 the previous chunking strategy is now [opt-in](https://vitejs.dev/guide/build.html#chunking-strategy) [#6534](https://github.com/vitejs/vite/issues/6534) and Vite will no longer split vendor libs in a separate chunk. + +### Web Workers enhancements + +Web Workers now supports source map generation (see [#5417](https://github.com/vitejs/vite/issues/5417)). The implementation is also now more robust, fixing several issues encountered in previous versions ([#6599](https://github.com/vitejs/vite/issues/6599)). + +### Raw Glob Imports + +Glob imports support for the `raw` modifier syntax has changed to using `{ as: 'raw' }`, which works in the same way as the `?raw` suffix in regular imports: + +```js +const examples = import.meta.globEager('./examples/*.html', { as: 'raw' }) +``` + +The `{ assert: { type: 'raw' }}` syntax introduced in v2.8 has been deprecated. See [#7017](https://github.com/vitejs/vite/issues/7017) for more information. + +### `envDir` changes + +The `envDir` now correctly loads `.env` files in the specified directory only (defaults to `root`). Previously, it would load files above the directory, which imposed security issues. If you had relied on the previous behaviour, make sure you move your `.env` files to the correct directory, or configure the `envDir` option. + +### New tools for Plugin and Framework Authors + +#### Client Server Communication API + +Vite now provides utilities for plugins to help handle the communication with clients connected to Vite's server [#7437](https://github.com/vitejs/vite/issues/7437). Reusing the open WebSocket connection between the server and clients several use cases can be simplified ([vite-plugin-inspect](https://github.com/antfu/vite-plugin-inspect), [SliDev](https://sli.dev), and many others). Check out the [Client Server Communication docs](https://vitejs.dev/guide/api-plugin.html#client-server-communication) for more information. + +```js +// Send a message from the client to the server +if (import.meta.hot) { + import.meta.hot.send('my:from-client', { msg: 'Hey!' }) +} +``` + +```js +// And listen to client messages in a plugin + configureServer(server) { + server.ws.on('my:from-client', (data, client) => { + console.log('Message from client:', data.msg) // Hey! + // ... + }) + } +``` + +#### `importedCss` and `importedAssets` to RenderedChunk type + +Replace the internal `chunkToEmittedCssFileMap` and `chunkToEmittedAssetsMap` variables with public properties added by Vite to `RenderedChunk` objects in the `renderChunk` phase. These is useful for Vite-based frameworks that generate their own HTML. See [#6629](https://github.com/vitejs/vite/issues/6629). + +#### Optimize Custom Extensions (experimental) + +A new `optimizeDeps.extensions: string[]` option is available to enable pre-bundling of custom extensions. A respective esbuild plugin is required to handle that extension. e.g. `['.svelte', '.svelte.md']`. See [#6801](https://github.com/vitejs/vite/issues/6801) for more information. + + +### Bug Fixes + +* fix: build path error on Windows (#7383) ([e3c7c7a](https://github.com/vitejs/vite/commit/e3c7c7a)), closes [#7383](https://github.com/vitejs/vite/issues/7383) +* fix: import url worker two times (#7468) ([f05a813](https://github.com/vitejs/vite/commit/f05a813)), closes [#7468](https://github.com/vitejs/vite/issues/7468) +* fix: import with query with exports/browser field (#7098) ([9ce6732](https://github.com/vitejs/vite/commit/9ce6732)), closes [#7098](https://github.com/vitejs/vite/issues/7098) +* fix: make @fs URLs work with special characters (#7510) ([2b7dad1](https://github.com/vitejs/vite/commit/2b7dad1)), closes [#7510](https://github.com/vitejs/vite/issues/7510) +* fix: tailwind css sourcemap warning (#7480) ([90df0bb](https://github.com/vitejs/vite/commit/90df0bb)), closes [#7480](https://github.com/vitejs/vite/issues/7480) +* fix: worker match only run in js (#7500) ([9481c7d](https://github.com/vitejs/vite/commit/9481c7d)), closes [#7500](https://github.com/vitejs/vite/issues/7500) +* fix: Correctly process urls when they are rewritten to contain space (#7452) ([9ee2cf6](https://github.com/vitejs/vite/commit/9ee2cf6)), closes [#7452](https://github.com/vitejs/vite/issues/7452) +* fix: custom event payload type (#7498) ([28b0660](https://github.com/vitejs/vite/commit/28b0660)), closes [#7498](https://github.com/vitejs/vite/issues/7498) +* fix: handle relative path glob raw import, fix #7307 (#7371) ([7f8dc58](https://github.com/vitejs/vite/commit/7f8dc58)), closes [#7307](https://github.com/vitejs/vite/issues/7307) [#7371](https://github.com/vitejs/vite/issues/7371) +* fix: import.meta.url in worker (#7464) ([8ac4b12](https://github.com/vitejs/vite/commit/8ac4b12)), closes [#7464](https://github.com/vitejs/vite/issues/7464) +* fix: optimizeDeps.entries default ignore paths (#7469) ([4c95e99](https://github.com/vitejs/vite/commit/4c95e99)), closes [#7469](https://github.com/vitejs/vite/issues/7469) +* fix: errors in worker handling (#7236) ([77dc1a1](https://github.com/vitejs/vite/commit/77dc1a1)), closes [#7236](https://github.com/vitejs/vite/issues/7236) +* fix: consider undefined port when checking port (#7318) ([c7fc7c3](https://github.com/vitejs/vite/commit/c7fc7c3)), closes [#7318](https://github.com/vitejs/vite/issues/7318) +* fix: inline style css sourcemap (#7434) ([47668b5](https://github.com/vitejs/vite/commit/47668b5)), closes [#7434](https://github.com/vitejs/vite/issues/7434) +* fix: sourcemap missing source files warning with cached vue (#7442) ([a2ce20d](https://github.com/vitejs/vite/commit/a2ce20d)), closes [#7442](https://github.com/vitejs/vite/issues/7442) +* fix: update tsconfck to 1.2.1 (#7424) ([a90b03b](https://github.com/vitejs/vite/commit/a90b03b)), closes [#7424](https://github.com/vitejs/vite/issues/7424) +* fix: virtual html sourcemap warning (#7440) ([476786b](https://github.com/vitejs/vite/commit/476786b)), closes [#7440](https://github.com/vitejs/vite/issues/7440) +* fix(less): empty less file error (#7412) ([0535c70](https://github.com/vitejs/vite/commit/0535c70)), closes [#7412](https://github.com/vitejs/vite/issues/7412) +* fix(resolve): skip `module` field when the importer is a `require` call (#7438) ([fe4c1ed](https://github.com/vitejs/vite/commit/fe4c1ed)), closes [#7438](https://github.com/vitejs/vite/issues/7438) +* fix: avoid mangling code from incorrect magic-string usage (#7397) ([68d76c9](https://github.com/vitejs/vite/commit/68d76c9)), closes [#7397](https://github.com/vitejs/vite/issues/7397) +* fix(config): server restart on config dependencies changed on windows (#7366) ([c43467a](https://github.com/vitejs/vite/commit/c43467a)), closes [#7366](https://github.com/vitejs/vite/issues/7366) +* fix(deps): update all non-major dependencies (#7392) ([b63fc3b](https://github.com/vitejs/vite/commit/b63fc3b)), closes [#7392](https://github.com/vitejs/vite/issues/7392) +* fix: add version to optimized chunks, fix #7323 (#7350) ([1be1db6](https://github.com/vitejs/vite/commit/1be1db6)), closes [#7323](https://github.com/vitejs/vite/issues/7323) [#7350](https://github.com/vitejs/vite/issues/7350) +* fix: browser cache of newly discovered deps (#7378) ([392a0de](https://github.com/vitejs/vite/commit/392a0de)), closes [#7378](https://github.com/vitejs/vite/issues/7378) +* fix: do not warn (about not being able to bundle non module scripts) when src is an external url (#7 ([0646fe8](https://github.com/vitejs/vite/commit/0646fe8)), closes [#7380](https://github.com/vitejs/vite/issues/7380) +* fix: overwrite deps info browserHash only on commit (#7359) ([1e9615d](https://github.com/vitejs/vite/commit/1e9615d)), closes [#7359](https://github.com/vitejs/vite/issues/7359) +* fix: delayed full page reload (#7347) ([fa0820a](https://github.com/vitejs/vite/commit/fa0820a)), closes [#7347](https://github.com/vitejs/vite/issues/7347) +* fix: early discovery of missing deps, fix #7333 (#7346) ([7d2f37c](https://github.com/vitejs/vite/commit/7d2f37c)), closes [#7333](https://github.com/vitejs/vite/issues/7333) [#7346](https://github.com/vitejs/vite/issues/7346) +* fix: unhandled exception on eager transformRequest (#7345) ([c3260a4](https://github.com/vitejs/vite/commit/c3260a4)), closes [#7345](https://github.com/vitejs/vite/issues/7345) +* fix: update to esbuild 0.14.27, fix #6994 (#7320) ([65aaeee](https://github.com/vitejs/vite/commit/65aaeee)), closes [#6994](https://github.com/vitejs/vite/issues/6994) [#7320](https://github.com/vitejs/vite/issues/7320) +* fix: `ssrExternal` should not skip nested dependencies (#7154) ([f8f934a](https://github.com/vitejs/vite/commit/f8f934a)), closes [#7154](https://github.com/vitejs/vite/issues/7154) +* fix: dep with dynamic import wrong error log (#7313) ([769f535](https://github.com/vitejs/vite/commit/769f535)), closes [#7313](https://github.com/vitejs/vite/issues/7313) +* fix: avoid caching transform result of invalidated module (#7254) ([2d7ba72](https://github.com/vitejs/vite/commit/2d7ba72)), closes [#7254](https://github.com/vitejs/vite/issues/7254) +* fix: dont replace define in json (#7294) ([fc5c937](https://github.com/vitejs/vite/commit/fc5c937)), closes [#7294](https://github.com/vitejs/vite/issues/7294) +* fix: main browserHash after stable optimization rerun (#7284) ([98eefa8](https://github.com/vitejs/vite/commit/98eefa8)), closes [#7284](https://github.com/vitejs/vite/issues/7284) +* fix: needs es interop check for newly discovered deps (#7243) ([ba3047d](https://github.com/vitejs/vite/commit/ba3047d)), closes [#7243](https://github.com/vitejs/vite/issues/7243) +* fix: pending requests after module invalidation (#7283) ([a1044d7](https://github.com/vitejs/vite/commit/a1044d7)), closes [#7283](https://github.com/vitejs/vite/issues/7283) +* fix: use browserHash for imports from node_modules (#7278) ([161f8ea](https://github.com/vitejs/vite/commit/161f8ea)), closes [#7278](https://github.com/vitejs/vite/issues/7278) +* fix: use hmr port if specified (#7282) ([3ee04c0](https://github.com/vitejs/vite/commit/3ee04c0)), closes [#7282](https://github.com/vitejs/vite/issues/7282) +* fix: use relative paths in _metadata.json (#7299) ([8b945f5](https://github.com/vitejs/vite/commit/8b945f5)), closes [#7299](https://github.com/vitejs/vite/issues/7299) +* fix(asset): allow non-existent url (#7306) ([6bc45a2](https://github.com/vitejs/vite/commit/6bc45a2)), closes [#7306](https://github.com/vitejs/vite/issues/7306) +* fix(hmr): hmr style tag no support in html (#7262) ([fae120a](https://github.com/vitejs/vite/commit/fae120a)), closes [#7262](https://github.com/vitejs/vite/issues/7262) +* fix: `import.meta.url` should not throw (#7219) ([5de3a98](https://github.com/vitejs/vite/commit/5de3a98)), closes [#7219](https://github.com/vitejs/vite/issues/7219) +* fix: allow `localhost` as a valid hostname (#7092) ([4194cce](https://github.com/vitejs/vite/commit/4194cce)), closes [#7092](https://github.com/vitejs/vite/issues/7092) +* fix: build optimize deps metada location (#7214) ([dc46adf](https://github.com/vitejs/vite/commit/dc46adf)), closes [#7214](https://github.com/vitejs/vite/issues/7214) +* fix: define plugin not ignore file names (#6340) ([7215a03](https://github.com/vitejs/vite/commit/7215a03)), closes [#6340](https://github.com/vitejs/vite/issues/6340) +* fix: deprecate `{ assert: { type: raw }}` in favor of `{ as: raw }` (fix #7017) (#7215) ([87ecce5](https://github.com/vitejs/vite/commit/87ecce5)), closes [#7017](https://github.com/vitejs/vite/issues/7017) [#7215](https://github.com/vitejs/vite/issues/7215) +* fix: execute classic worker in dev mode (#7099) ([3c0a609](https://github.com/vitejs/vite/commit/3c0a609)), closes [#7099](https://github.com/vitejs/vite/issues/7099) +* fix: handle files with multiple comments (#7202) ([3f5b645](https://github.com/vitejs/vite/commit/3f5b645)), closes [#7202](https://github.com/vitejs/vite/issues/7202) +* fix: honor the host param when creating a websocket server (#5617) ([882c8a8](https://github.com/vitejs/vite/commit/882c8a8)), closes [#5617](https://github.com/vitejs/vite/issues/5617) +* fix: import css in less/scss (fix 3293) (#7147) ([9b51a3a](https://github.com/vitejs/vite/commit/9b51a3a)), closes [#7147](https://github.com/vitejs/vite/issues/7147) +* fix: optimizeDeps.include missing in known imports fallback (#7218) ([6c08c86](https://github.com/vitejs/vite/commit/6c08c86)), closes [#7218](https://github.com/vitejs/vite/issues/7218) +* fix: prevent loading env outside of root (#6995) ([e0a4d81](https://github.com/vitejs/vite/commit/e0a4d81)), closes [#6995](https://github.com/vitejs/vite/issues/6995) +* fix: reoptimize deps on esbuild options change (#6855) ([4517c2b](https://github.com/vitejs/vite/commit/4517c2b)), closes [#6855](https://github.com/vitejs/vite/issues/6855) +* fix: replacing compression with modern version (#6557) ([5648d09](https://github.com/vitejs/vite/commit/5648d09)), closes [#6557](https://github.com/vitejs/vite/issues/6557) +* fix: restart optimize (#7004) ([47fbe29](https://github.com/vitejs/vite/commit/47fbe29)), closes [#7004](https://github.com/vitejs/vite/issues/7004) +* fix: reusing variable names in html module scripts (fix #6851) (#6818) ([c46b56d](https://github.com/vitejs/vite/commit/c46b56d)), closes [#6851](https://github.com/vitejs/vite/issues/6851) [#6818](https://github.com/vitejs/vite/issues/6818) +* fix: revert #6340, definePlugin tests, warning box (#7174) ([6cb0647](https://github.com/vitejs/vite/commit/6cb0647)), closes [#6340](https://github.com/vitejs/vite/issues/6340) [#7174](https://github.com/vitejs/vite/issues/7174) +* fix: update postcss-load-config to load PostCSS plugins based on their config file path (#6856) ([f02f961](https://github.com/vitejs/vite/commit/f02f961)), closes [#6856](https://github.com/vitejs/vite/issues/6856) +* fix(hmr): client pinging behind a proxy on websocket disconnect (fix #4501) (#5466) ([96573db](https://github.com/vitejs/vite/commit/96573db)), closes [#4501](https://github.com/vitejs/vite/issues/4501) [#5466](https://github.com/vitejs/vite/issues/5466) +* fix(html): build mode ignore html define transform (#6663) ([79dd003](https://github.com/vitejs/vite/commit/79dd003)), closes [#6663](https://github.com/vitejs/vite/issues/6663) +* fix(json): load json module error (#6352) ([c8a7ea8](https://github.com/vitejs/vite/commit/c8a7ea8)), closes [#6352](https://github.com/vitejs/vite/issues/6352) +* fix(optimizer): add missing keys to hash (#7189) ([b0c0efe](https://github.com/vitejs/vite/commit/b0c0efe)), closes [#7189](https://github.com/vitejs/vite/issues/7189) +* fix(resolve): try .tsx extension for .js import from typescript module (#7005) ([72b8cb6](https://github.com/vitejs/vite/commit/72b8cb6)), closes [#7005](https://github.com/vitejs/vite/issues/7005) +* fix(server): base middleware redirect with search and hash (#6574) ([a516e85](https://github.com/vitejs/vite/commit/a516e85)), closes [#6574](https://github.com/vitejs/vite/issues/6574) +* fix(server): ensure consistency for url to file mapping in importAnalysis and static middleware (#65 ([b214115](https://github.com/vitejs/vite/commit/b214115)), closes [#6518](https://github.com/vitejs/vite/issues/6518) +* fix(ssr): bypass missing resolve error in SSR (#7164) ([a4927c5](https://github.com/vitejs/vite/commit/a4927c5)), closes [#7164](https://github.com/vitejs/vite/issues/7164) + + +### Features + +* feat(worker): Add sourcemap support for worker bundles (#5417) ([465b6b9](https://github.com/vitejs/vite/commit/465b6b9)), closes [#5417](https://github.com/vitejs/vite/issues/5417) +* feat(type): support typing for custom events (#7476) ([50a8765](https://github.com/vitejs/vite/commit/50a8765)), closes [#7476](https://github.com/vitejs/vite/issues/7476) +* refactor(types): share hot context type (#7475) ([64ddff0](https://github.com/vitejs/vite/commit/64ddff0)), closes [#7475](https://github.com/vitejs/vite/issues/7475) +* feat: support importing css with ?raw (#5796) ([fedb106](https://github.com/vitejs/vite/commit/fedb106)), closes [#5796](https://github.com/vitejs/vite/issues/5796) +* feat(css): css.devSourcemap option (#7471) ([57f14cb](https://github.com/vitejs/vite/commit/57f14cb)), closes [#7471](https://github.com/vitejs/vite/issues/7471) +* feat(dev): expose APIs for client-server communication (#7437) ([e29ea8e](https://github.com/vitejs/vite/commit/e29ea8e)), closes [#7437](https://github.com/vitejs/vite/issues/7437) +* feat: hide optimized deps found during scan phase logs (#7419) ([f4934e8](https://github.com/vitejs/vite/commit/f4934e8)), closes [#7419](https://github.com/vitejs/vite/issues/7419) +* feat: non-blocking scanning of dependencies (#7379) ([676f545](https://github.com/vitejs/vite/commit/676f545)), closes [#7379](https://github.com/vitejs/vite/issues/7379) +* feat: css sourcemap support during dev (#7173) ([38a655f](https://github.com/vitejs/vite/commit/38a655f)), closes [#7173](https://github.com/vitejs/vite/issues/7173) +* feat: expose ssrRewriteStacktrace (#7091) ([d4ae45d](https://github.com/vitejs/vite/commit/d4ae45d)), closes [#7091](https://github.com/vitejs/vite/issues/7091) +* feat: add `importedCss` and `importedAssets` to RenderedChunk type (#6629) ([8d0fc90](https://github.com/vitejs/vite/commit/8d0fc90)), closes [#6629](https://github.com/vitejs/vite/issues/6629) +* feat: non-blocking pre bundling of dependencies (#6758) ([24bb3e4](https://github.com/vitejs/vite/commit/24bb3e4)), closes [#6758](https://github.com/vitejs/vite/issues/6758) +* feat: optimize custom extensions (#6801) ([c11af23](https://github.com/vitejs/vite/commit/c11af23)), closes [#6801](https://github.com/vitejs/vite/issues/6801) +* feat: show all prebundle deps when debug (#6726) ([e626055](https://github.com/vitejs/vite/commit/e626055)), closes [#6726](https://github.com/vitejs/vite/issues/6726) +* feat(glob): import.meta.glob support alias path (#6526) ([86882ad](https://github.com/vitejs/vite/commit/86882ad)), closes [#6526](https://github.com/vitejs/vite/issues/6526) +* feat(perf): tsconfck perf improvement (#7055) ([993ea39](https://github.com/vitejs/vite/commit/993ea39)), closes [#7055](https://github.com/vitejs/vite/issues/7055) +* feat(worker): bundle worker emit asset file (#6599) ([0ade335](https://github.com/vitejs/vite/commit/0ade335)), closes [#6599](https://github.com/vitejs/vite/issues/6599) +* refactor: avoid splitting vendor chunk by default (#6534) ([849e845](https://github.com/vitejs/vite/commit/849e845)), closes [#6534](https://github.com/vitejs/vite/issues/6534) + + +### Beta Changelogs + + +#### [2.9.0-beta.11](https://github.com/vitejs/vite/compare/v2.9.0-beta.10...v2.9.0-beta.11) (2022-03-29) + +See [2.9.0-beta.11 changelog](https://github.com/vitejs/vite/blob/v2.9.0-beta.11/packages/vite/CHANGELOG.md) + + +#### [2.9.0-beta.10](https://github.com/vitejs/vite/compare/v2.9.0-beta.9...v2.9.0-beta.10) (2022-03-28) + +See [2.9.0-beta.10 changelog](https://github.com/vitejs/vite/blob/v2.9.0-beta.10/packages/vite/CHANGELOG.md) + + +#### [2.9.0-beta.9](https://github.com/vitejs/vite/compare/v2.9.0-beta.8...v2.9.0-beta.9) (2022-03-26) + +See [2.9.0-beta.9 changelog](https://github.com/vitejs/vite/blob/v2.9.0-beta.9/packages/vite/CHANGELOG.md) + + +#### [2.9.0-beta.8](https://github.com/vitejs/vite/compare/v2.9.0-beta.7...v2.9.0-beta.8) (2022-03-24) + +See [2.9.0-beta.8 changelog](https://github.com/vitejs/vite/blob/v2.9.0-beta.8/packages/vite/CHANGELOG.md) + + +#### [2.9.0-beta.7](https://github.com/vitejs/vite/compare/v2.9.0-beta.6...v2.9.0-beta.7) (2022-03-23) + +See [2.9.0-beta.7 changelog](https://github.com/vitejs/vite/blob/v2.9.0-beta.7/packages/vite/CHANGELOG.md) + + +#### [2.9.0-beta.6](https://github.com/vitejs/vite/compare/v2.9.0-beta.5...v2.9.0-beta.6) (2022-03-22) + +See [2.9.0-beta.6 changelog](https://github.com/vitejs/vite/blob/v2.9.0-beta.6/packages/vite/CHANGELOG.md) + + +#### [2.9.0-beta.5](https://github.com/vitejs/vite/compare/v2.9.0-beta.4...v2.9.0-beta.5) (2022-03-22) + +See [2.9.0-beta.5 changelog](https://github.com/vitejs/vite/blob/v2.9.0-beta.5/packages/vite/CHANGELOG.md) + + +#### [2.9.0-beta.4](https://github.com/vitejs/vite/compare/v2.9.0-beta.3...v2.9.0-beta.4) (2022-03-19) + +See [2.9.0-beta.4 changelog](https://github.com/vitejs/vite/blob/v2.9.0-beta.4/packages/vite/CHANGELOG.md) + + +#### [2.9.0-beta.3](https://github.com/vitejs/vite/compare/v2.9.0-beta.2...v2.9.0-beta.3) (2022-03-16) + +See [2.9.0-beta.3 changelog](https://github.com/vitejs/vite/blob/v2.9.0-beta.3/packages/vite/CHANGELOG.md) + + +#### [2.9.0-beta.2](https://github.com/vitejs/vite/compare/v2.9.0-beta.1...v2.9.0-beta.2) (2022-03-14) + +See [2.9.0-beta.2 changelog](https://github.com/vitejs/vite/blob/v2.9.0-beta.2/packages/vite/CHANGELOG.md) + + +#### [2.9.0-beta.1](https://github.com/vitejs/vite/compare/v2.9.0-beta.0...v2.9.0-beta.1) (2022-03-14) + +See [2.9.0-beta.1 changelog](https://github.com/vitejs/vite/blob/v2.9.0-beta.1/packages/vite/CHANGELOG.md) + + +#### [2.9.0-beta.0](https://github.com/vitejs/vite/compare/v2.8.6...v2.9.0-beta.0) (2022-03-09) + +See [2.9.0-beta.0 changelog](https://github.com/vitejs/vite/blob/v2.9.0-beta.0/packages/vite/CHANGELOG.md) + + + +## [2.8.6](https://github.com/vitejs/vite/compare/v2.8.5...v2.8.6) (2022-03-01) + + +### Bug Fixes + +* revert [#7052](https://github.com/vitejs/vite/issues/7052), hmr style tag no support in html ([#7136](https://github.com/vitejs/vite/issues/7136)) ([5c116ec](https://github.com/vitejs/vite/commit/5c116ecde0ad43409334853457d68481a22e19d4)) +* throw Error when can't preload CSS ([#7108](https://github.com/vitejs/vite/issues/7108)) ([d9f8edb](https://github.com/vitejs/vite/commit/d9f8edbd5b243f60212cc4bb9271c01b7e3fdd76)) + + + +## [2.8.5](https://github.com/vitejs/vite/compare/v2.8.4...v2.8.5) (2022-02-28) + + +### Bug Fixes + +* ?html-proxy with trailing = added by some servers ([#7093](https://github.com/vitejs/vite/issues/7093)) ([5818ac9](https://github.com/vitejs/vite/commit/5818ac927861783ea2b05450761fed30f40e7399)) +* allow optional trailing comma in asset `import.meta.url` ([#6983](https://github.com/vitejs/vite/issues/6983)) ([2debb9f](https://github.com/vitejs/vite/commit/2debb9f4cbb6003e7d24444cf049b45582d82ff1)) +* cannot reassign process.env.NODE_ENV in ssr ([#6989](https://github.com/vitejs/vite/issues/6989)) ([983feb2](https://github.com/vitejs/vite/commit/983feb2cdc5180dc46c3f5fc5b99baaa8d6b7078)) +* **config:** Warn about terserOptions in more cases ([#7101](https://github.com/vitejs/vite/issues/7101)) ([79428ad](https://github.com/vitejs/vite/commit/79428ad5b849455e14f95d1b439ae296ba231221)) +* don't override user config ([#7034](https://github.com/vitejs/vite/issues/7034)) ([8fd8f6e](https://github.com/vitejs/vite/commit/8fd8f6e0e501c9e46bc3e179c900d31fa5cafce1)) +* fileToBuiltUrl got undefined when file type is `.ico` ([#7106](https://github.com/vitejs/vite/issues/7106)) ([7a1a552](https://github.com/vitejs/vite/commit/7a1a552ba710bad5714ef0fbb16fdd29ac58ae0b)) +* **glob:** css imports injecting a ?used query to export the css string ([#6949](https://github.com/vitejs/vite/issues/6949)) ([0b3f4ef](https://github.com/vitejs/vite/commit/0b3f4ef231004e072bf1b037f63bc4ef169d938e)) +* **hmr:** hmr style tag no support in html ([#7052](https://github.com/vitejs/vite/issues/7052)) ([a9dfce3](https://github.com/vitejs/vite/commit/a9dfce38108e796e0de0e3b43ced34d60883cef3)) +* image -> image/x-icon ([#7120](https://github.com/vitejs/vite/issues/7120)) ([065ceca](https://github.com/vitejs/vite/commit/065ceca5c7b8f1843e220fbdbe8a0da4cbb78935)) +* import with query with exports field ([#7073](https://github.com/vitejs/vite/issues/7073)) ([88ded7f](https://github.com/vitejs/vite/commit/88ded7f16382d83603511de043785e01ee1e4a3a)) +* prebundle dep with colon ([#7006](https://github.com/vitejs/vite/issues/7006)) ([2136f2b](https://github.com/vitejs/vite/commit/2136f2bb960d1a81ac3b3ca04d9ebd89dba44661)) +* recycle serve to avoid preventing Node self-exit ([#6895](https://github.com/vitejs/vite/issues/6895)) ([d6b2c53](https://github.com/vitejs/vite/commit/d6b2c53c6f0bcc4ffa9cdf48375f9bbcc98f79f7)) +* resolve [@import](https://github.com/import) of the proxied