diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a87561a8e4146c..f086627de5cfe0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,7 +24,7 @@ If you want to use break point and explore code execution you can use the ["Run 2. Click on the "Run and Debug" icon in the activity bar of the editor. -3. Click on the "Javascript Debug Terminal" button. +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`. @@ -79,7 +79,7 @@ Each test can be run under either dev server mode or build mode. - `pnpm run test-build` runs tests only under build mode. -- You can also use `pnpm run test-serve -- [match]` or `pnpm run test-build -- [match]` to run tests in a specific playground package, e.g. `pnpm run test-serve -- css` will run tests for both `playground/css` and `playground/css-codesplit` under serve mode. +- You can also use `pnpm run test-serve -- [match]` or `pnpm run test-build -- [match]` to run tests in a specific playground package, e.g. `pnpm run test-serve -- asset` will run tests for both `playground/asset` and `vite/src/node/__tests__/asset` under serve mode and `vite/src/node/__tests__/**/*` just run in serve mode. Note package matching is not available for the `pnpm test` script, which always runs all tests. @@ -229,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` @@ -238,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 a8d8cb36079f0a..346de1a78f7dc9 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -101,7 +101,9 @@ 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. +Environmental Variables can be obtained from `process.env` as usual. + +Note that 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' @@ -156,6 +158,8 @@ export default defineConfig(({ 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 @@ -355,7 +359,7 @@ export default defineConfig(({ 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({ @@ -366,9 +370,9 @@ export default defineConfig(({ command, mode }) => { }) ``` - 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. + 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({ @@ -378,7 +382,7 @@ export default defineConfig(({ command, mode }) => { }) ``` - Set to `false` to disable ESbuild transforms. + Set to `false` to disable esbuild transforms. ### assetsInclude @@ -550,14 +554,12 @@ export default defineConfig(({ command, mode }) => { ### server.hmr -- **Type:** `boolean | { protocol?: string, host?: string, port?: number | false, path?: string, timeout?: number, overlay?: boolean, clientPort?: number, server?: Server }` +- **Type:** `boolean | { protocol?: string, host?: string, port?: number, path?: string, timeout?: number, overlay?: boolean, clientPort?: number, server?: Server }` Disable or configure HMR connection (in cases where the HMR websocket must use a different address from the http server). Set `server.hmr.overlay` to `false` to disable the server error overlay. - Set `server.hmr.port` to `false` when connecting to a domain without a port. - `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. 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. @@ -849,7 +851,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. diff --git a/docs/guide/api-javascript.md b/docs/guide/api-javascript.md index ddaa04279737f5..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` diff --git a/docs/guide/api-plugin.md b/docs/guide/api-plugin.md index 228755dd6f85c2..50353765261e34 100644 --- a/docs/guide/api-plugin.md +++ b/docs/guide/api-plugin.md @@ -113,7 +113,7 @@ Virtual modules are a useful scheme that allows you to pass build time informati ```js export default function myPlugin() { - const virtualModuleId = '@my-virtual-module' + const virtualModuleId = 'virtual:my-module' const resolvedVirtualModuleId = '\0' + virtualModuleId return { @@ -135,7 +135,7 @@ export default function myPlugin() { Which allows importing the module in JavaScript: ```js -import { msg } from '@my-virtual-module' +import { msg } from 'virtual:my-module' console.log(msg) ``` @@ -186,8 +186,10 @@ Vite plugins can also provide hooks that serve Vite-specific purposes. These hoo const partialConfigPlugin = () => ({ name: 'return-partial', config: () => ({ - alias: { - foo: 'bar' + resolve: { + alias: { + foo: 'bar' + } } }) }) @@ -499,7 +501,7 @@ Since Vite 2.9, we provide some utilities for plugins to help handle the communi ### Server to Client -On the plugin side, we could use `server.ws.send` to boardcast events to all the clients: +On the plugin side, we could use `server.ws.send` to broadcast events to all the clients: ```js // vite.config.js diff --git a/docs/guide/assets.md b/docs/guide/assets.md index fd5aa46f49467f..9776dcdd032f35 100644 --- a/docs/guide/assets.md +++ b/docs/guide/assets.md @@ -103,8 +103,17 @@ 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. ::: + +::: warning Esbuild target config is necessary +This pattern needs esbuild target to be set to `es2020` or higher. `vite@2.x` use `es2019` as default target. Set [build-target](https://vitejs.dev/config/#build-target) and [optimizedeps.esbuildoptions.target](https://vitejs.dev/config/#optimizedeps-esbuildoptions) to `es2020` or higher if you intend to use this partten. +::: diff --git a/docs/guide/env-and-mode.md b/docs/guide/env-and-mode.md index d3a6a575bce64c..b2b1264e85a8e4 100644 --- a/docs/guide/env-and-mode.md +++ b/docs/guide/env-and-mode.md @@ -37,12 +37,12 @@ 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. ::: -Loaded env variables are also exposed to your client source code via `import.meta.env`. +Loaded env variables are also exposed to your client source code via `import.meta.env` as strings. To prevent accidentally leaking env variables to the client, only variables prefixed with `VITE_` are exposed to your Vite-processed code. e.g. the following file: @@ -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/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 89ca7698394246..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). diff --git a/package.json b/package.json index 878fd5c7de506f..de02e27949560c 100644 --- a/package.json +++ b/package.json @@ -34,18 +34,18 @@ "ci-docs": "run-s build-vite build-plugin-vue build-docs" }, "devDependencies": { - "@microsoft/api-extractor": "^7.19.5", + "@microsoft/api-extractor": "^7.21.2", "@types/fs-extra": "^9.0.13", "@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.16.0", - "@typescript-eslint/parser": "^5.16.0", + "@typescript-eslint/eslint-plugin": "^5.18.0", + "@typescript-eslint/parser": "^5.18.0", "conventional-changelog-cli": "^2.2.2", "cross-env": "^7.0.3", "esbuild": "^0.14.27", - "eslint": "^8.12.0", + "eslint": "^8.13.0", "eslint-define-config": "^1.3.0", "eslint-plugin-node": "^11.1.0", "execa": "^5.1.1", @@ -56,12 +56,12 @@ "node-fetch": "^2.6.6", "npm-run-all": "^4.1.5", "picocolors": "^1.0.0", - "playwright-chromium": "^1.20.1", - "prettier": "2.6.1", + "playwright-chromium": "^1.20.2", + "prettier": "2.6.2", "prompts": "^2.4.2", "rimraf": "^3.0.2", "rollup": "^2.59.0", - "semver": "^7.3.5", + "semver": "^7.3.6", "simple-git-hooks": "^2.7.0", "sirv": "^2.0.2", "ts-jest": "^27.1.4", @@ -85,11 +85,18 @@ "eslint --ext .ts" ] }, - "packageManager": "pnpm@6.32.3", + "packageManager": "pnpm@6.32.6", "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..cac7f2664ecaed 100644 --- a/packages/create-vite/CHANGELOG.md +++ b/packages/create-vite/CHANGELOG.md @@ -1,3 +1,22 @@ +## 2.9.1 (2022-04-13) + +* chore: fix term cases (#7553) ([c296130](https://github.com/vitejs/vite/commit/c296130)), closes [#7553](https://github.com/vitejs/vite/issues/7553) +* chore: update @types/react version (#7655) ([eb57627](https://github.com/vitejs/vite/commit/eb57627)), closes [#7655](https://github.com/vitejs/vite/issues/7655) +* chore: update vue template setup api doc url (#7628) ([4433df4](https://github.com/vitejs/vite/commit/4433df4)), closes [#7628](https://github.com/vitejs/vite/issues/7628) +* chore(create-vite-app): upgrade react to 18 (#7597) ([8b21029](https://github.com/vitejs/vite/commit/8b21029)), closes [#7597](https://github.com/vitejs/vite/issues/7597) +* chore(create-vite): add isolatedModules (#7697) ([8f28350](https://github.com/vitejs/vite/commit/8f28350)), closes [#7697](https://github.com/vitejs/vite/issues/7697) + + + +## 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 ec8199455ef86f..dcaf3962c987cf 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.1", "license": "MIT", "author": "Evan You", "bin": { diff --git a/packages/create-vite/template-lit-ts/package.json b/packages/create-vite/template-lit-ts/package.json index 5c0a7c7948ee58..6a928d05bb9e84 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.2", "typescript": "^4.5.4" } } diff --git a/packages/create-vite/template-lit-ts/tsconfig.json b/packages/create-vite/template-lit-ts/tsconfig.json index 03ecaf410c88be..2ec691c81c2b38 100644 --- a/packages/create-vite/template-lit-ts/tsconfig.json +++ b/packages/create-vite/template-lit-ts/tsconfig.json @@ -11,6 +11,7 @@ "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "moduleResolution": "node", + "isolatedModules": true, "allowSyntheticDefaultImports": true, "experimentalDecorators": true, "forceConsistentCasingInFileNames": true, diff --git a/packages/create-vite/template-lit/package.json b/packages/create-vite/template-lit/package.json index ca3c71428f22c9..7889bec19759ff 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.2" } } diff --git a/packages/create-vite/template-preact-ts/package.json b/packages/create-vite/template-preact-ts/package.json index df1726ba6c4f7b..aaf8aea0372e52 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.2" } } diff --git a/packages/create-vite/template-preact/package.json b/packages/create-vite/template-preact/package.json index 2865df70374acf..19198fc9e66d67 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.2" } } diff --git a/packages/create-vite/template-react-ts/package.json b/packages/create-vite/template-react-ts/package.json index 3b1e21b7dbca8c..ea89f3a68d8c45 100644 --- a/packages/create-vite/template-react-ts/package.json +++ b/packages/create-vite/template-react-ts/package.json @@ -8,14 +8,14 @@ "preview": "vite preview" }, "dependencies": { - "react": "^17.0.2", - "react-dom": "^17.0.2" + "react": "^18.0.0", + "react-dom": "^18.0.0" }, "devDependencies": { - "@types/react": "^17.0.33", - "@types/react-dom": "^17.0.10", - "@vitejs/plugin-react": "^1.0.7", - "typescript": "^4.5.4", - "vite": "^2.8.0" + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.0", + "@vitejs/plugin-react": "^1.3.0", + "typescript": "^4.6.3", + "vite": "^2.9.2" } } diff --git a/packages/create-vite/template-react-ts/src/main.tsx b/packages/create-vite/template-react-ts/src/main.tsx index 606a3cf44ec02b..4a1b15096e15b1 100644 --- a/packages/create-vite/template-react-ts/src/main.tsx +++ b/packages/create-vite/template-react-ts/src/main.tsx @@ -1,11 +1,10 @@ import React from 'react' -import ReactDOM from 'react-dom' -import './index.css' +import ReactDOM from 'react-dom/client' import App from './App' +import './index.css' -ReactDOM.render( +ReactDOM.createRoot(document.getElementById('root')!).render( - , - document.getElementById('root') + ) diff --git a/packages/create-vite/template-react/package.json b/packages/create-vite/template-react/package.json index 7b0f87c6bc95f5..f81b751dc8f30c 100644 --- a/packages/create-vite/template-react/package.json +++ b/packages/create-vite/template-react/package.json @@ -8,11 +8,13 @@ "preview": "vite preview" }, "dependencies": { - "react": "^17.0.2", - "react-dom": "^17.0.2" + "react": "^18.0.0", + "react-dom": "^18.0.0" }, "devDependencies": { - "@vitejs/plugin-react": "^1.0.7", - "vite": "^2.8.0" + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.0", + "@vitejs/plugin-react": "^1.3.0", + "vite": "^2.9.2" } } diff --git a/packages/create-vite/template-react/src/main.jsx b/packages/create-vite/template-react/src/main.jsx index 606a3cf44ec02b..9af0bb638e42c0 100644 --- a/packages/create-vite/template-react/src/main.jsx +++ b/packages/create-vite/template-react/src/main.jsx @@ -1,11 +1,10 @@ import React from 'react' -import ReactDOM from 'react-dom' -import './index.css' +import ReactDOM from 'react-dom/client' import App from './App' +import './index.css' -ReactDOM.render( +ReactDOM.createRoot(document.getElementById('root')).render( - , - document.getElementById('root') + ) 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..bed1e3caedeef0 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.2" } } diff --git a/packages/create-vite/template-svelte-ts/tsconfig.json b/packages/create-vite/template-svelte-ts/tsconfig.json index 4d6c04cf0ab13b..96bfd81aaf1203 100644 --- a/packages/create-vite/template-svelte-ts/tsconfig.json +++ b/packages/create-vite/template-svelte-ts/tsconfig.json @@ -13,7 +13,8 @@ * of JS in `.svelte` files. */ "allowJs": true, - "checkJs": true + "checkJs": true, + "isolatedModules": true }, "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], "references": [{ "path": "./tsconfig.node.json" }] 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..661a174421d156 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.2" } } diff --git a/packages/create-vite/template-vanilla-ts/package.json b/packages/create-vite/template-vanilla-ts/package.json index 9b6cc582bfdb11..adedc3d4e83a65 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.2" } } diff --git a/packages/create-vite/template-vanilla-ts/tsconfig.json b/packages/create-vite/template-vanilla-ts/tsconfig.json index 1885c8f9b00106..05f80b91398b98 100644 --- a/packages/create-vite/template-vanilla-ts/tsconfig.json +++ b/packages/create-vite/template-vanilla-ts/tsconfig.json @@ -8,6 +8,7 @@ "strict": true, "sourceMap": true, "resolveJsonModule": true, + "isolatedModules": true, "esModuleInterop": true, "noEmit": true, "noUnusedLocals": true, diff --git a/packages/create-vite/template-vanilla/package.json b/packages/create-vite/template-vanilla/package.json index f409412bbdc272..ee68e7cd13e903 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.2" } } diff --git a/packages/create-vite/template-vue-ts/README.md b/packages/create-vite/template-vue-ts/README.md index b53dcfb1a715e6..e432516724c1a7 100644 --- a/packages/create-vite/template-vue-ts/README.md +++ b/packages/create-vite/template-vue-ts/README.md @@ -1,16 +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 ` diff --git a/packages/create-vite/template-vue-ts/src/components/HelloWorld.vue b/packages/create-vite/template-vue-ts/src/components/HelloWorld.vue index 2d61249ac32f9c..38dae70739a15a 100644 --- a/packages/create-vite/template-vue-ts/src/components/HelloWorld.vue +++ b/packages/create-vite/template-vue-ts/src/components/HelloWorld.vue @@ -11,7 +11,7 @@ const count = ref(0)

Recommended IDE setup: - VSCode + VS Code + Volar

diff --git a/packages/create-vite/template-vue/README.md b/packages/create-vite/template-vue/README.md index c0793a82398e08..eea15cef41ea60 100644 --- a/packages/create-vite/template-vue/README.md +++ b/packages/create-vite/template-vue/README.md @@ -4,4 +4,4 @@ This template should help get you started developing with Vue 3 in Vite. The tem ## Recommended IDE Setup -- [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) +- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) diff --git a/packages/create-vite/template-vue/package.json b/packages/create-vite/template-vue/package.json index 3136fcda2a0bc7..531986717154ee 100644 --- a/packages/create-vite/template-vue/package.json +++ b/packages/create-vite/template-vue/package.json @@ -11,7 +11,7 @@ "vue": "^3.2.25" }, "devDependencies": { - "@vitejs/plugin-vue": "^2.2.0", - "vite": "^2.8.0" + "@vitejs/plugin-vue": "^2.3.1", + "vite": "^2.9.2" } } diff --git a/packages/create-vite/template-vue/src/App.vue b/packages/create-vite/template-vue/src/App.vue index 742233037df99e..09bbb6a561285f 100644 --- a/packages/create-vite/template-vue/src/App.vue +++ b/packages/create-vite/template-vue/src/App.vue @@ -1,6 +1,6 @@ diff --git a/packages/create-vite/template-vue/src/components/HelloWorld.vue b/packages/create-vite/template-vue/src/components/HelloWorld.vue index 48a5ca9095156b..aa607e31e0ad7c 100644 --- a/packages/create-vite/template-vue/src/components/HelloWorld.vue +++ b/packages/create-vite/template-vue/src/components/HelloWorld.vue @@ -13,7 +13,7 @@ const count = ref(0)

Recommended IDE setup: - VSCode + VS Code + Volar

diff --git a/packages/playground/assets/__tests__/assets.spec.ts b/packages/playground/assets/__tests__/assets.spec.ts index f53c783c52b606..75c0e57952db24 100644 --- a/packages/playground/assets/__tests__/assets.spec.ts +++ b/packages/playground/assets/__tests__/assets.spec.ts @@ -263,6 +263,7 @@ if (isBuild) { } }) } + describe('css and assets in css in build watch', () => { if (isBuild) { test('css will not be lost and css does not contain undefined', async () => { @@ -271,7 +272,26 @@ describe('css and assets in css in build watch', () => { const cssFile = findAssetFile(/index\.\w+\.css$/, 'foo') expect(cssFile).not.toBe('') expect(cssFile).not.toMatch(/undefined/) - watcher?.close() + }) + + test('import module.css', async () => { + expect(await getColor('#foo')).toBe('red') + editFile( + 'css/foo.module.css', + (code) => code.replace('red', 'blue'), + true + ) + await notifyRebuildComplete(watcher) + await page.reload() + expect(await getColor('#foo')).toBe('blue') + }) + + test('import with raw query', async () => { + expect(await page.textContent('.raw-query')).toBe('foo') + editFile('static/foo.txt', (code) => code.replace('foo', 'zoo'), true) + await notifyRebuildComplete(watcher) + await page.reload() + expect(await page.textContent('.raw-query')).toBe('zoo') }) } }) @@ -287,3 +307,10 @@ if (!isBuild) { await untilUpdated(() => getColor('.import-css'), 'rgb(0, 255, 136)') }) } + +test('html import word boundary', async () => { + expect(await page.textContent('.obj-import-express')).toMatch( + 'ignore object import prop' + ) + expect(await page.textContent('.string-import-express')).toMatch('no load') +}) diff --git a/packages/playground/assets/css/foo.module.css b/packages/playground/assets/css/foo.module.css new file mode 100644 index 00000000000000..196612f252d254 --- /dev/null +++ b/packages/playground/assets/css/foo.module.css @@ -0,0 +1,3 @@ +.foo-module { + color: red; +} diff --git a/packages/playground/assets/index.html b/packages/playground/assets/index.html index 7534ecbe1677bf..6678a2da7c2106 100644 --- a/packages/playground/assets/index.html +++ b/packages/playground/assets/index.html @@ -176,9 +176,28 @@

new URL(`non-existent`, import.meta.url)

simple script tag import-expression

+ +

url in style tag

url

@@ -212,6 +231,10 @@

@import

@import CSS from publicDir should load (this should be red)

+

import module css

+ +

+ @@ -268,6 +291,12 @@

document.querySelector('.import-meta-url-img-comma-nl').src = metaUrlWithCommaNL + import classNames from './css/foo.module.css' + document.querySelector('#foo').className = classNames['foo-module'] + + import someString from './static/foo.txt?raw' + document.querySelector('.raw-query').textContent = someString + const metaUrlNonExistent = new URL('non-existent', import.meta.url).pathname text('.non-existent-import-meta-url', metaUrlNonExistent) diff --git a/packages/playground/assets/static/foo.txt b/packages/playground/assets/static/foo.txt new file mode 100644 index 00000000000000..19102815663d23 --- /dev/null +++ b/packages/playground/assets/static/foo.txt @@ -0,0 +1 @@ +foo \ No newline at end of file diff --git a/packages/playground/cli-module/__tests__/serve.js b/packages/playground/cli-module/__tests__/serve.js index 2b354f566524bf..cf873fd481830b 100644 --- a/packages/playground/cli-module/__tests__/serve.js +++ b/packages/playground/cli-module/__tests__/serve.js @@ -5,10 +5,10 @@ const path = require('path') // eslint-disable-next-line node/no-restricted-require const execa = require('execa') -const { workspaceRoot } = require('../../testUtils') +const { workspaceRoot, ports } = require('../../testUtils') const isWindows = process.platform === 'win32' -const port = (exports.port = 9511) // make sure this port is unique across tests with custom servers +const port = (exports.port = ports['cli-module']) const viteBin = path.join(workspaceRoot, 'packages', 'vite', 'bin', 'vite.js') /** diff --git a/packages/playground/cli/__tests__/serve.js b/packages/playground/cli/__tests__/serve.js index 5dd058f4e1a83c..3ad375d9d1f543 100644 --- a/packages/playground/cli/__tests__/serve.js +++ b/packages/playground/cli/__tests__/serve.js @@ -5,10 +5,10 @@ const path = require('path') // eslint-disable-next-line node/no-restricted-require const execa = require('execa') -const { workspaceRoot } = require('../../testUtils') +const { workspaceRoot, ports } = require('../../testUtils') const isWindows = process.platform === 'win32' -const port = (exports.port = 9510) // make sure this port is unique across tests with custom servers +const port = (exports.port = ports.cli) const viteBin = path.join(workspaceRoot, 'packages', 'vite', 'bin', 'vite.js') /** diff --git a/packages/playground/css-sourcemap/__tests__/serve.spec.ts b/packages/playground/css-sourcemap/__tests__/serve.spec.ts index 0c6696b0dff7a2..11e33a78af8424 100644 --- a/packages/playground/css-sourcemap/__tests__/serve.spec.ts +++ b/packages/playground/css-sourcemap/__tests__/serve.spec.ts @@ -1,11 +1,11 @@ -import { fromComment } from 'convert-source-map' import { URL } from 'url' -import { normalizePath } from 'vite' -import { isBuild, testDir } from 'testUtils' +import { + extractSourcemap, + formatSourcemapForSnapshot, + isBuild +} from 'testUtils' if (!isBuild) { - const root = normalizePath(testDir) - const getStyleTagContentIncluding = async (content: string) => { const styles = await page.$$('style') for (const style of styles) { @@ -17,19 +17,6 @@ if (!isBuild) { throw new Error('Not found') } - const extractSourcemap = (content: string) => { - const lines = content.trim().split('\n') - return fromComment(lines[lines.length - 1]).toObject() - } - - const formatSourcemapForSnapshot = (map: any) => { - const m = { ...map } - delete m.file - delete m.names - m.sources = m.sources.map((source) => source.replace(root, '/root')) - return m - } - test('inline css', async () => { const css = await getStyleTagContentIncluding('.inline ') const map = extractSourcemap(css) diff --git a/packages/playground/css-sourcemap/package.json b/packages/playground/css-sourcemap/package.json index c29f18d4dee0d7..c7e9e61372cefa 100644 --- a/packages/playground/css-sourcemap/package.json +++ b/packages/playground/css-sourcemap/package.json @@ -9,7 +9,6 @@ "preview": "vite preview" }, "devDependencies": { - "convert-source-map": "^1.8.0", "less": "^4.1.2", "magic-string": "^0.25.7", "sass": "^1.43.4", diff --git a/packages/playground/css/__tests__/css.spec.ts b/packages/playground/css/__tests__/css.spec.ts index 3fe4a09bcc94c8..6ca00e760349b1 100644 --- a/packages/playground/css/__tests__/css.spec.ts +++ b/packages/playground/css/__tests__/css.spec.ts @@ -242,6 +242,20 @@ test('css modules w/ sass', async () => { await untilUpdated(() => getColor(imported), 'blue') }) +test('inline css modules', async () => { + const css = await page.textContent('.modules-inline') + expect(css).toMatch(/\.inline-module__apply-color-inline___[\w-]{5}/) +}) + +if (isBuild) { + test('@charset hoist', async () => { + serverLogs.forEach((log) => { + // no warning from esbuild css minifier + expect(log).not.toMatch('"@charset" must be the first rule in the file') + }) + }) +} + test('@import dependency w/ style entry', async () => { expect(await getColor('.css-dep')).toBe('purple') }) @@ -324,7 +338,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) @@ -383,3 +397,11 @@ test('import css in less', async () => { expect(await getColor('.css-in-less')).toBe('yellow') expect(await getColor('.css-in-less-2')).toBe('blue') }) + +test("relative path rewritten in Less's data-uri", async () => { + // relative path passed to Less's data-uri is rewritten to absolute, + // the Less inlines it + expect(await getBg('.form-box-data-uri')).toMatch( + /^url\("data:image\/svg\+xml,%3Csvg/ + ) +}) diff --git a/packages/playground/css/__tests__/postcss-plugins-different-dir.spec.ts b/packages/playground/css/__tests__/postcss-plugins-different-dir.spec.ts index 19e9a43ae4ff6e..8bedc26ee354c8 100644 --- a/packages/playground/css/__tests__/postcss-plugins-different-dir.spec.ts +++ b/packages/playground/css/__tests__/postcss-plugins-different-dir.spec.ts @@ -1,10 +1,10 @@ -import { getColor, getBgColor } from '../../testUtils' +import { getColor, getBgColor, ports } 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 port = ports['css/postcss-plugins-different-dir'] const server = await createServer({ root: path.join(__dirname, '..', '..', 'tailwind'), logLevel: 'silent', diff --git a/packages/playground/css/charset.css b/packages/playground/css/charset.css new file mode 100644 index 00000000000000..5c42b279f8404c --- /dev/null +++ b/packages/playground/css/charset.css @@ -0,0 +1,5 @@ +@charset "utf-8"; + +.utf8 { + color: green; +} diff --git a/packages/playground/css/index.html b/packages/playground/css/index.html index 060aed7fb1b27f..fef6a0be393748 100644 --- a/packages/playground/css/index.html +++ b/packages/playground/css/index.html @@ -49,6 +49,10 @@

CSS

Imported Less string:


 
+  
+ tests Less's `data-uri()` function with relative image paths +
+

Stylus: This should be blue

Stylus additionalData: This should be orange @@ -89,6 +93,12 @@

CSS


 
+  

Inline CSS module:

+

+
+  

CSS with @charset:

+

+
   

@import dependency w/ style enrtrypoints: this should be purple

@@ -105,7 +115,7 @@

CSS

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

Inlined import - this should NOT be red.

diff --git a/packages/playground/css/inline.module.css b/packages/playground/css/inline.module.css new file mode 100644 index 00000000000000..9566e21e2cd1af --- /dev/null +++ b/packages/playground/css/inline.module.css @@ -0,0 +1,3 @@ +.apply-color-inline { + color: turquoise; +} diff --git a/packages/playground/css/less.less b/packages/playground/css/less.less index 69ffa830862014..49cbd3c3bb336e 100644 --- a/packages/playground/css/less.less +++ b/packages/playground/css/less.less @@ -1,6 +1,9 @@ @import '@/nested/nested'; @import './nested/css-in-less.less'; +// Test data-uri calls with relative images. +@import './less/components/form.less'; + @color: blue; .less { diff --git a/packages/playground/css/less/components/form.less b/packages/playground/css/less/components/form.less new file mode 100644 index 00000000000000..feaaea94ce1bba --- /dev/null +++ b/packages/playground/css/less/components/form.less @@ -0,0 +1,4 @@ +.form-box-data-uri { + // data-uri() calls with relative paths should be replaced just like urls. + background-image: data-uri('../images/backgrounds/form-select.svg'); +} diff --git a/packages/playground/css/less/images/backgrounds/form-select.svg b/packages/playground/css/less/images/backgrounds/form-select.svg new file mode 100644 index 00000000000000..8aaf69c09e03f4 --- /dev/null +++ b/packages/playground/css/less/images/backgrounds/form-select.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/playground/css/main.js b/packages/playground/css/main.js index 6edd840a87c5e7..0d03aafbf0ec7f 100644 --- a/packages/playground/css/main.js +++ b/packages/playground/css/main.js @@ -38,6 +38,12 @@ text( JSON.stringify(composesPathResolvingMod, null, 2) ) +import inlineMod from './inline.module.css?inline' +text('.modules-inline', inlineMod) + +import charset from './charset.css' +text('.charset-css', charset) + import './dep.css' import './glob-dep.css' diff --git a/packages/playground/css/postcss-caching/css.spec.ts b/packages/playground/css/postcss-caching/css.spec.ts index 6c85d127003680..e8ba73154b6bc8 100644 --- a/packages/playground/css/postcss-caching/css.spec.ts +++ b/packages/playground/css/postcss-caching/css.spec.ts @@ -1,9 +1,9 @@ -import { getColor } from '../../testUtils' +import { getColor, ports } from '../../testUtils' import { createServer } from 'vite' import path from 'path' test('postcss config', async () => { - const port = 5005 + const port = ports['css/postcss-caching'] const startServer = async (root) => { const server = await createServer({ root, diff --git a/packages/playground/dynamic-import/__tests__/dynamic-import.spec.ts b/packages/playground/dynamic-import/__tests__/dynamic-import.spec.ts index 9f8276d5e4d855..c7157ef4652ec6 100644 --- a/packages/playground/dynamic-import/__tests__/dynamic-import.spec.ts +++ b/packages/playground/dynamic-import/__tests__/dynamic-import.spec.ts @@ -8,6 +8,10 @@ test('should load literal dynamic import', async () => { test('should load full dynamic import from public', async () => { await page.click('.qux') await untilUpdated(() => page.textContent('.view'), 'Qux view', true) + // No warning should be logged as we are using @vite-ignore + expect( + serverLogs.some((log) => log.includes('cannot be analyzed by vite')) + ).toBe(false) }) test('should load data URL of `blob:`', async () => { diff --git a/packages/playground/dynamic-import/nested/index.js b/packages/playground/dynamic-import/nested/index.js index 1a118ecc79051b..5518c56a35a2cc 100644 --- a/packages/playground/dynamic-import/nested/index.js +++ b/packages/playground/dynamic-import/nested/index.js @@ -35,7 +35,7 @@ document.querySelector('.mxd2').addEventListener('click', async () => { const test = { jss: '../mxd.js' } const ttest = test const view = 'mxd' - const { default: mxdDynamic } = await import(test.jss) + const { default: mxdDynamic } = await import(/*@vite-ignore*/ test.jss) text('.view', mxdStatic === mxdDynamic) }) 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 9e4f728a593a91..951e14ad2cce91 100644 --- a/packages/playground/fs-serve/root/src/index.html +++ b/packages/playground/fs-serve/root/src/index.html @@ -11,6 +11,8 @@

Safe Fetch

Safe Fetch Subdirectory


 

+

+

 
 

Unsafe Fetch


@@ -19,6 +21,8 @@ 

Unsafe Fetch

Safe /@fs/ Fetch


 

+

+

 
 

Unsafe /@fs/ Fetch


@@ -56,6 +60,16 @@ 

Denied

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') .then((r) => { @@ -92,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/hmr/__tests__/hmr.spec.ts b/packages/playground/hmr/__tests__/hmr.spec.ts index 6ddc2345ae4fb4..7325c9fe47943a 100644 --- a/packages/playground/hmr/__tests__/hmr.spec.ts +++ b/packages/playground/hmr/__tests__/hmr.spec.ts @@ -160,4 +160,38 @@ if (!isBuild) { expect(textprev).not.toMatch('direct') expect(textpost).not.toMatch('direct') }) + + test('not loaded dynamic import', async () => { + await page.goto(viteTestUrl + '/dynamic-import/index.html') + + let btn = await page.$('button') + expect(await btn.textContent()).toBe('Counter 0') + await btn.click() + expect(await btn.textContent()).toBe('Counter 1') + + // Modifying `index.ts` triggers a page reload, as expected + editFile('dynamic-import/index.ts', (code) => code) + await page.waitForNavigation() + btn = await page.$('button') + expect(await btn.textContent()).toBe('Counter 0') + + await btn.click() + expect(await btn.textContent()).toBe('Counter 1') + + // #7561 + // `dep.ts` defines `import.module.hot.accept` and has not been loaded. + // Therefore, modifying it has no effect (doesn't trigger a page reload). + // (Note that, a dynamic import that is never loaded and that does not + // define `accept.module.hot.accept` may wrongfully trigger a full page + // reload, see discussion at #7561.) + editFile('dynamic-import/dep.ts', (code) => code) + try { + await page.waitForNavigation({ timeout: 1000 }) + } catch (err) { + const errMsg = 'page.waitForNavigation: Timeout 1000ms exceeded.' + expect(err.message.slice(0, errMsg.length)).toBe(errMsg) + } + btn = await page.$('button') + expect(await btn.textContent()).toBe('Counter 1') + }) } diff --git a/packages/playground/hmr/dynamic-import/dep.ts b/packages/playground/hmr/dynamic-import/dep.ts new file mode 100644 index 00000000000000..aca649f226f770 --- /dev/null +++ b/packages/playground/hmr/dynamic-import/dep.ts @@ -0,0 +1,2 @@ +// This file is never loaded +import.meta.hot.accept(() => {}) diff --git a/packages/playground/hmr/dynamic-import/index.html b/packages/playground/hmr/dynamic-import/index.html new file mode 100644 index 00000000000000..f5290ad4f1e507 --- /dev/null +++ b/packages/playground/hmr/dynamic-import/index.html @@ -0,0 +1,2 @@ + + diff --git a/packages/playground/hmr/dynamic-import/index.ts b/packages/playground/hmr/dynamic-import/index.ts new file mode 100644 index 00000000000000..0230140278989f --- /dev/null +++ b/packages/playground/hmr/dynamic-import/index.ts @@ -0,0 +1,12 @@ +const btn = document.querySelector('button') +let count = 0 +const update = () => { + btn.textContent = `Counter ${count}` +} +btn.onclick = () => { + count++ + update() +} +function neverCalled() { + import('./dep') +} 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/legacy/__tests__/legacy.spec.ts b/packages/playground/legacy/__tests__/legacy.spec.ts index b8025694437502..65bd39ff32b1d1 100644 --- a/packages/playground/legacy/__tests__/legacy.spec.ts +++ b/packages/playground/legacy/__tests__/legacy.spec.ts @@ -83,4 +83,8 @@ if (isBuild) { test('should emit css file', async () => { expect(listAssets().some((filename) => filename.endsWith('.css'))) }) + + test('includes structuredClone polyfill which is supported after core-js v3', () => { + expect(findAssetFile(/polyfills-legacy/)).toMatch('"structuredClone"') + }) } diff --git a/packages/playground/legacy/__tests__/ssr/serve.js b/packages/playground/legacy/__tests__/ssr/serve.js index df43f180afb188..c7ef2ed3520e53 100644 --- a/packages/playground/legacy/__tests__/ssr/serve.js +++ b/packages/playground/legacy/__tests__/ssr/serve.js @@ -2,8 +2,9 @@ // this is automtically detected by scripts/jestPerTestSetup.ts and will replace // the default e2e test serve behavior const path = require('path') +const { ports } = require('../../../testUtils') -const port = (exports.port = 9527) +const port = (exports.port = ports['legacy/ssr']) /** * @param {string} root diff --git a/packages/playground/legacy/index.html b/packages/playground/legacy/index.html index bdc2feac6b4fbe..d481766463cd4f 100644 --- a/packages/playground/legacy/index.html +++ b/packages/playground/legacy/index.html @@ -1,6 +1,7 @@

+
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/lib/__tests__/serve.js b/packages/playground/lib/__tests__/serve.js index 15c64de40276d1..eac6980286af52 100644 --- a/packages/playground/lib/__tests__/serve.js +++ b/packages/playground/lib/__tests__/serve.js @@ -5,8 +5,9 @@ const path = require('path') const http = require('http') const sirv = require('sirv') +const { ports } = require('../../testUtils') -const port = (exports.port = 9527) +const port = (exports.port = ports.lib) /** * @param {string} root diff --git a/packages/playground/optimize-missing-deps/__test__/serve.js b/packages/playground/optimize-missing-deps/__test__/serve.js index 9f293024f83913..89a6ce3593cd0e 100644 --- a/packages/playground/optimize-missing-deps/__test__/serve.js +++ b/packages/playground/optimize-missing-deps/__test__/serve.js @@ -3,8 +3,9 @@ // the default e2e test serve behavior const path = require('path') +const { ports } = require('../../testUtils') -const port = (exports.port = 9529) +const port = (exports.port = ports['optimize-missing-deps']) /** * @param {string} root 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/preload/vite.config.js b/packages/playground/preload/vite.config.js index 96fb82f51ed349..90684f41829953 100644 --- a/packages/playground/preload/vite.config.js +++ b/packages/playground/preload/vite.config.js @@ -3,6 +3,7 @@ const vuePlugin = require('@vitejs/plugin-vue') module.exports = { plugins: [vuePlugin()], build: { + minify: 'terser', terserOptions: { format: { beautify: true diff --git a/packages/playground/resolve/__tests__/resolve.spec.ts b/packages/playground/resolve/__tests__/resolve.spec.ts index c8c85d8df9b806..2deb2fab7f8d40 100644 --- a/packages/playground/resolve/__tests__/resolve.spec.ts +++ b/packages/playground/resolve/__tests__/resolve.spec.ts @@ -17,7 +17,10 @@ test('deep import with exports field', async () => { }) test('deep import with query with exports field', async () => { - expect(await page.textContent('.exports-deep-query')).not.toMatch('fail') + // 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 () => { diff --git a/packages/playground/resolve/index.html b/packages/playground/resolve/index.html index 2c4ed7b9aa760c..1920ebb675d24c 100644 --- a/packages/playground/resolve/index.html +++ b/packages/playground/resolve/index.html @@ -171,10 +171,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 ( diff --git a/packages/playground/ssr-deps/__tests__/serve.js b/packages/playground/ssr-deps/__tests__/serve.js index 5ba5724f2b7a94..6c2584601c9331 100644 --- a/packages/playground/ssr-deps/__tests__/serve.js +++ b/packages/playground/ssr-deps/__tests__/serve.js @@ -3,8 +3,9 @@ // the default e2e test serve behavior const path = require('path') +const { ports } = require('../../testUtils') -const port = (exports.port = 9530) +const port = (exports.port = ports['ssr-deps']) /** * @param {string} root diff --git a/packages/playground/ssr-html/__tests__/serve.js b/packages/playground/ssr-html/__tests__/serve.js index 5ba5724f2b7a94..d119397700cf75 100644 --- a/packages/playground/ssr-html/__tests__/serve.js +++ b/packages/playground/ssr-html/__tests__/serve.js @@ -3,8 +3,9 @@ // the default e2e test serve behavior const path = require('path') +const { ports } = require('../../testUtils') -const port = (exports.port = 9530) +const port = (exports.port = ports['ssr-html']) /** * @param {string} root diff --git a/packages/playground/ssr-pug/__tests__/serve.js b/packages/playground/ssr-pug/__tests__/serve.js index 5ba5724f2b7a94..392aa831ebb82d 100644 --- a/packages/playground/ssr-pug/__tests__/serve.js +++ b/packages/playground/ssr-pug/__tests__/serve.js @@ -3,8 +3,9 @@ // the default e2e test serve behavior const path = require('path') +const { ports } = require('../../testUtils') -const port = (exports.port = 9530) +const port = (exports.port = ports['ssr-pug']) /** * @param {string} root diff --git a/packages/playground/ssr-react/__tests__/serve.js b/packages/playground/ssr-react/__tests__/serve.js index 1bc028c03dc27c..07476e0726e268 100644 --- a/packages/playground/ssr-react/__tests__/serve.js +++ b/packages/playground/ssr-react/__tests__/serve.js @@ -3,8 +3,9 @@ // the default e2e test serve behavior const path = require('path') +const { ports } = require('../../testUtils') -const port = (exports.port = 9528) +const port = (exports.port = ports['ssr-react']) /** * @param {string} root diff --git a/packages/playground/ssr-vue/__tests__/serve.js b/packages/playground/ssr-vue/__tests__/serve.js index 1e220fed9630e4..5bcd5a4639877a 100644 --- a/packages/playground/ssr-vue/__tests__/serve.js +++ b/packages/playground/ssr-vue/__tests__/serve.js @@ -3,8 +3,9 @@ // the default e2e test serve behavior const path = require('path') +const { ports } = require('../../testUtils') -const port = (exports.port = 9527) +const port = (exports.port = ports['ssr-vue']) /** * @param {string} root diff --git a/packages/playground/ssr-webworker/__tests__/serve.js b/packages/playground/ssr-webworker/__tests__/serve.js index f4f207b85026c6..38a957b0a333ea 100644 --- a/packages/playground/ssr-webworker/__tests__/serve.js +++ b/packages/playground/ssr-webworker/__tests__/serve.js @@ -3,8 +3,9 @@ // the default e2e test serve behavior const path = require('path') +const { ports } = require('../../testUtils') -const port = (exports.port = 9528) +const port = (exports.port = ports['ssr-webworker']) /** * @param {string} root 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/testUtils.ts b/packages/playground/testUtils.ts index 0c8186d4ed121d..427fea6d947a4f 100644 --- a/packages/playground/testUtils.ts +++ b/packages/playground/testUtils.ts @@ -7,6 +7,25 @@ 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' + +// make sure these ports are unique +export const ports = { + cli: 9510, + 'cli-module': 9511, + 'legacy/ssr': 9520, + lib: 9521, + 'optimize-missing-deps': 9522, + 'ssr-deps': 9600, + 'ssr-html': 9601, + 'ssr-pug': 9602, + 'ssr-react': 9603, + 'ssr-vue': 9604, + 'ssr-webworker': 9605, + 'css/postcss-caching': 5005, + 'css/postcss-plugins-different-dir': 5006 +} export function slash(p: string): string { return p.replace(/\\/g, '/') @@ -138,3 +157,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/vite.config.js b/packages/playground/vue-jsx/vite.config.js index d6eb84e05f4e4a..2f4ea255c95094 100644 --- a/packages/playground/vue-jsx/vite.config.js +++ b/packages/playground/vue-jsx/vite.config.js @@ -35,5 +35,8 @@ export default defineComponent(() => { build: { // to make tests faster minify: false + }, + optimizeDeps: { + disabled: true } } 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/Main.vue b/packages/playground/vue-sourcemap/Main.vue index 04ddf50071ccb3..b9b03596f5aea5 100644 --- a/packages/playground/vue-sourcemap/Main.vue +++ b/packages/playground/vue-sourcemap/Main.vue @@ -1,5 +1,7 @@ + + diff --git a/packages/playground/vue-sourcemap/__tests__/serve.spec.ts b/packages/playground/vue-sourcemap/__tests__/serve.spec.ts index 193b0afb9ba73f..08b4c04face111 100644 --- a/packages/playground/vue-sourcemap/__tests__/serve.spec.ts +++ b/packages/playground/vue-sourcemap/__tests__/serve.spec.ts @@ -1,10 +1,11 @@ -import { fromComment } from 'convert-source-map' -import { normalizePath } from 'vite' -import { isBuild, testDir } from 'testUtils' +import { + extractSourcemap, + formatSourcemapForSnapshot, + isBuild +} from 'testUtils' +import { URL } from 'url' if (!isBuild) { - const root = normalizePath(testDir) - const getStyleTagContentIncluding = async (content: string) => { const styles = await page.$$('style') for (const style of styles) { @@ -16,18 +17,63 @@ if (!isBuild) { throw new Error('Not found') } - const extractSourcemap = (content: string) => { - const lines = content.trim().split('\n') - return fromComment(lines[lines.length - 1]).toObject() - } + 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 [ + " - const formatSourcemapForSnapshot = (map: any) => { - const m = { ...map } - delete m.file - delete m.names - m.sources = m.sources.map((source) => source.replace(root, '/root')) - return m - } + + + + ", + ], + "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 ') diff --git a/packages/playground/vue-sourcemap/package.json b/packages/playground/vue-sourcemap/package.json index 5672b5e3d9d57d..286940b01efa58 100644 --- a/packages/playground/vue-sourcemap/package.json +++ b/packages/playground/vue-sourcemap/package.json @@ -10,7 +10,6 @@ }, "devDependencies": { "@vitejs/plugin-vue": "workspace:*", - "convert-source-map": "^1.8.0", "less": "^4.1.2", "sass": "^1.43.4" }, 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/worker/__tests__/es/es-worker.spec.ts b/packages/playground/worker/__tests__/es/es-worker.spec.ts index 51497a0f5ebadd..c7fd0d6c19e4bc 100644 --- a/packages/playground/worker/__tests__/es/es-worker.spec.ts +++ b/packages/playground/worker/__tests__/es/es-worker.spec.ts @@ -60,7 +60,7 @@ if (isBuild) { // assert correct files test('inlined code generation', async () => { const files = fs.readdirSync(assetsDir) - expect(files.length).toBe(20) + expect(files.length).toBe(22) const index = files.find((f) => f.includes('main-module')) const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8') const worker = files.find((f) => f.includes('my-worker')) @@ -94,7 +94,7 @@ test('classic worker', async () => { test('emit chunk', async () => { expect(await page.textContent('.emti-chunk-worker')).toMatch( - '{"msg1":"module1","msg2":"module2","msg3":"module3"}' + '["A string",{"type":"emit-chunk-sub-worker","data":"A string"},{"type":"module-and-worker:worker","data":"A string"},{"type":"module-and-worker:module","data":"module and worker"},{"type":"emit-chunk-sub-worker","data":{"module":"module and worker","msg1":"module1","msg2":"module2","msg3":"module3"}}]' ) expect(await page.textContent('.emti-chunk-dynamic-import-worker')).toMatch( '"A string/es/"' diff --git a/packages/playground/worker/__tests__/iife/vite.config.js b/packages/playground/worker/__tests__/iife/vite.config.js new file mode 100644 index 00000000000000..4204f532b7ac1c --- /dev/null +++ b/packages/playground/worker/__tests__/iife/vite.config.js @@ -0,0 +1 @@ +module.exports = require('../../vite.config') diff --git a/packages/playground/worker/__tests__/worker.spec.ts b/packages/playground/worker/__tests__/iife/worker.spec.ts similarity index 97% rename from packages/playground/worker/__tests__/worker.spec.ts rename to packages/playground/worker/__tests__/iife/worker.spec.ts index 263c49cff52fb9..fa9f72fe76131c 100644 --- a/packages/playground/worker/__tests__/worker.spec.ts +++ b/packages/playground/worker/__tests__/iife/worker.spec.ts @@ -1,6 +1,6 @@ import fs from 'fs' import path from 'path' -import { untilUpdated, isBuild, testDir } from '../../testUtils' +import { untilUpdated, isBuild, testDir } from '../../../testUtils' import type { Page } from 'playwright-chromium' test('normal', async () => { diff --git a/packages/playground/worker/__tests__/sourcemap-hidden/sourcemap-hidden-worker.spec.ts b/packages/playground/worker/__tests__/sourcemap-hidden/sourcemap-hidden-worker.spec.ts new file mode 100644 index 00000000000000..d846a5de2311d0 --- /dev/null +++ b/packages/playground/worker/__tests__/sourcemap-hidden/sourcemap-hidden-worker.spec.ts @@ -0,0 +1,129 @@ +import fs from 'fs' +import path from 'path' +import { untilUpdated, isBuild, testDir } from '../../../testUtils' +import { Page } from 'playwright-chromium' + +if (isBuild) { + const assetsDir = path.resolve(testDir, 'dist/iife-sourcemap-hidden/assets') + // assert correct files + test('sourcemap generation for web workers', async () => { + const files = fs.readdirSync(assetsDir) + // should have 2 worker chunk + expect(files.length).toBe(25) + const index = files.find((f) => f.includes('main-module')) + const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8') + const indexSourcemap = getSourceMapUrl(content) + const worker = files.find((f) => /^my-worker\.\w+\.js$/.test(f)) + const workerContent = fs.readFileSync( + path.resolve(assetsDir, worker), + 'utf-8' + ) + const workerSourcemap = getSourceMapUrl(workerContent) + const sharedWorker = files.find((f) => + /^my-shared-worker\.\w+\.js$/.test(f) + ) + const sharedWorkerContent = fs.readFileSync( + path.resolve(assetsDir, sharedWorker), + 'utf-8' + ) + const sharedWorkerSourcemap = getSourceMapUrl(sharedWorkerContent) + const possibleTsOutputWorker = files.find((f) => + /^possible-ts-output-worker\.\w+\.js$/.test(f) + ) + const possibleTsOutputWorkerContent = fs.readFileSync( + path.resolve(assetsDir, possibleTsOutputWorker), + 'utf-8' + ) + const possibleTsOutputWorkerSourcemap = getSourceMapUrl( + possibleTsOutputWorkerContent + ) + const workerNestedWorker = files.find((f) => + /^worker-nested-worker\.\w+\.js$/.test(f) + ) + const workerNestedWorkerContent = fs.readFileSync( + path.resolve(assetsDir, workerNestedWorker), + 'utf-8' + ) + const workerNestedWorkerSourcemap = getSourceMapUrl( + workerNestedWorkerContent + ) + const subWorker = files.find((f) => /^sub-worker\.\w+\.js$/.test(f)) + const subWorkerContent = fs.readFileSync( + path.resolve(assetsDir, subWorker), + 'utf-8' + ) + const subWorkerSourcemap = getSourceMapUrl(subWorkerContent) + + expect(files).toContainEqual(expect.stringMatching(/^index\.\w+\.js\.map$/)) + expect(files).toContainEqual( + expect.stringMatching(/^my-worker\.\w+\.js\.map$/) + ) + expect(files).toContainEqual( + expect.stringMatching(/^my-shared-worker\.\w+\.js\.map$/) + ) + expect(files).toContainEqual( + expect.stringMatching(/^possible-ts-output-worker\.\w+\.js\.map$/) + ) + expect(files).toContainEqual( + expect.stringMatching(/^worker-nested-worker\.\w+\.js\.map$/) + ) + expect(files).toContainEqual( + expect.stringMatching(/^sub-worker\.\w+\.js\.map$/) + ) + + // sourcemap should exist and have a data URL + expect(indexSourcemap).toBe(null) + expect(workerSourcemap).toBe(null) + expect(sharedWorkerSourcemap).toBe(null) + expect(possibleTsOutputWorkerSourcemap).toBe(null) + expect(workerNestedWorkerSourcemap).toBe(null) + expect(subWorkerSourcemap).toBe(null) + + // worker should have all imports resolved and no exports + expect(workerContent).not.toMatch(`import`) + expect(workerContent).not.toMatch(`export`) + + // shared worker should have all imports resolved and no exports + expect(sharedWorkerContent).not.toMatch(`import`) + expect(sharedWorkerContent).not.toMatch(`export`) + + // chunk + expect(content).toMatch( + `new Worker("/iife-sourcemap-hidden/assets/my-worker` + ) + expect(content).toMatch(`new Worker("data:application/javascript;base64`) + expect(content).toMatch( + `new Worker("/iife-sourcemap-hidden/assets/possible-ts-output-worker` + ) + expect(content).toMatch( + `new Worker("/iife-sourcemap-hidden/assets/worker-nested-worker` + ) + expect(content).toMatch( + `new SharedWorker("/iife-sourcemap-hidden/assets/my-shared-worker` + ) + + // inlined + expect(content).toMatch(`(window.URL||window.webkitURL).createObjectURL`) + expect(content).toMatch(`window.Blob`) + + expect(workerNestedWorkerContent).toMatch( + `new Worker("/iife-sourcemap-hidden/assets/sub-worker` + ) + }) +} else { + // Workaround so that testing serve does not emit + // "Your test suite must contain at least one test" + test('true', () => { + expect(true).toBe(true) + }) +} + +function getSourceMapUrl(code: string): string { + const regex = /\/\/[#@]\s(?:source(?:Mapping)?URL)=\s*(\S+)/g + const results = regex.exec(code) + + if (results && results.length >= 2) { + return results[1] + } + return null +} diff --git a/packages/playground/worker/__tests__/sourcemap-hidden/vite.config.js b/packages/playground/worker/__tests__/sourcemap-hidden/vite.config.js new file mode 100644 index 00000000000000..d51907577e9deb --- /dev/null +++ b/packages/playground/worker/__tests__/sourcemap-hidden/vite.config.js @@ -0,0 +1 @@ +module.exports = require('../../vite.config-sourcemap')('hidden') diff --git a/packages/playground/worker/__tests__/sourcemap-inline/sourcemap-inline-worker.spec.ts b/packages/playground/worker/__tests__/sourcemap-inline/sourcemap-inline-worker.spec.ts new file mode 100644 index 00000000000000..ceda7dae1fec7c --- /dev/null +++ b/packages/playground/worker/__tests__/sourcemap-inline/sourcemap-inline-worker.spec.ts @@ -0,0 +1,112 @@ +import fs from 'fs' +import path from 'path' +import { untilUpdated, isBuild, testDir } from '../../../testUtils' +import { Page } from 'playwright-chromium' + +if (isBuild) { + const assetsDir = path.resolve(testDir, 'dist/iife-sourcemap-inline/assets') + // assert correct files + test('sourcemap generation for web workers', async () => { + const files = fs.readdirSync(assetsDir) + // should have 2 worker chunk + expect(files.length).toBe(13) + const index = files.find((f) => f.includes('main-module')) + const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8') + const indexSourcemap = getSourceMapUrl(content) + const worker = files.find((f) => /^my-worker\.\w+\.js$/.test(f)) + const workerContent = fs.readFileSync( + path.resolve(assetsDir, worker), + 'utf-8' + ) + const workerSourcemap = getSourceMapUrl(workerContent) + const sharedWorker = files.find((f) => + /^my-shared-worker\.\w+\.js$/.test(f) + ) + const sharedWorkerContent = fs.readFileSync( + path.resolve(assetsDir, sharedWorker), + 'utf-8' + ) + const sharedWorkerSourcemap = getSourceMapUrl(sharedWorkerContent) + const possibleTsOutputWorker = files.find((f) => + /^possible-ts-output-worker\.\w+\.js$/.test(f) + ) + const possibleTsOutputWorkerContent = fs.readFileSync( + path.resolve(assetsDir, possibleTsOutputWorker), + 'utf-8' + ) + const possibleTsOutputWorkerSourcemap = getSourceMapUrl( + possibleTsOutputWorkerContent + ) + const workerNestedWorker = files.find((f) => + /^worker-nested-worker\.\w+\.js$/.test(f) + ) + const workerNestedWorkerContent = fs.readFileSync( + path.resolve(assetsDir, workerNestedWorker), + 'utf-8' + ) + const workerNestedWorkerSourcemap = getSourceMapUrl( + workerNestedWorkerContent + ) + const subWorker = files.find((f) => /^sub-worker\.\w+\.js$/.test(f)) + const subWorkerContent = fs.readFileSync( + path.resolve(assetsDir, subWorker), + 'utf-8' + ) + const subWorkerSourcemap = getSourceMapUrl(subWorkerContent) + + // sourcemap should exist and have a data URL + expect(indexSourcemap).toMatch(/^data:/) + expect(workerSourcemap).toMatch(/^data:/) + expect(sharedWorkerSourcemap).toMatch(/^data:/) + expect(possibleTsOutputWorkerSourcemap).toMatch(/^data:/) + expect(workerNestedWorkerSourcemap).toMatch(/^data:/) + expect(subWorkerSourcemap).toMatch(/^data:/) + + // worker should have all imports resolved and no exports + expect(workerContent).not.toMatch(`import`) + expect(workerContent).not.toMatch(`export`) + + // shared worker should have all imports resolved and no exports + expect(sharedWorkerContent).not.toMatch(`import`) + expect(sharedWorkerContent).not.toMatch(`export`) + + // chunk + expect(content).toMatch( + `new Worker("/iife-sourcemap-inline/assets/my-worker` + ) + expect(content).toMatch(`new Worker("data:application/javascript;base64`) + expect(content).toMatch( + `new Worker("/iife-sourcemap-inline/assets/possible-ts-output-worker` + ) + expect(content).toMatch( + `new Worker("/iife-sourcemap-inline/assets/worker-nested-worker` + ) + expect(content).toMatch( + `new SharedWorker("/iife-sourcemap-inline/assets/my-shared-worker` + ) + + // inlined + expect(content).toMatch(`(window.URL||window.webkitURL).createObjectURL`) + expect(content).toMatch(`window.Blob`) + + expect(workerNestedWorkerContent).toMatch( + `new Worker("/iife-sourcemap-inline/assets/sub-worker` + ) + }) +} else { + // Workaround so that testing serve does not emit + // "Your test suite must contain at least one test" + test('true', () => { + expect(true).toBe(true) + }) +} + +function getSourceMapUrl(code: string): string { + const regex = /\/\/[#@]\s(?:source(?:Mapping)?URL)=\s*(\S+)/g + const results = regex.exec(code) + + if (results && results.length >= 2) { + return results[1] + } + return null +} diff --git a/packages/playground/worker/__tests__/sourcemap-inline/vite.config.js b/packages/playground/worker/__tests__/sourcemap-inline/vite.config.js new file mode 100644 index 00000000000000..abe37cd56accd6 --- /dev/null +++ b/packages/playground/worker/__tests__/sourcemap-inline/vite.config.js @@ -0,0 +1 @@ +module.exports = require('../../vite.config-sourcemap')('inline') diff --git a/packages/playground/worker/__tests__/sourcemap/sourcemap-worker.spec.ts b/packages/playground/worker/__tests__/sourcemap/sourcemap-worker.spec.ts new file mode 100644 index 00000000000000..54e4f1cb9f2d58 --- /dev/null +++ b/packages/playground/worker/__tests__/sourcemap/sourcemap-worker.spec.ts @@ -0,0 +1,131 @@ +import fs from 'fs' +import path from 'path' +import { untilUpdated, isBuild, testDir } from '../../../testUtils' +import { Page } from 'playwright-chromium' + +if (isBuild) { + const assetsDir = path.resolve(testDir, 'dist/iife-sourcemap/assets') + // assert correct files + test('sourcemap generation for web workers', async () => { + const files = fs.readdirSync(assetsDir) + // should have 2 worker chunk + expect(files.length).toBe(25) + const index = files.find((f) => f.includes('main-module')) + const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8') + const indexSourcemap = getSourceMapUrl(content) + const worker = files.find((f) => /^my-worker\.\w+\.js$/.test(f)) + const workerContent = fs.readFileSync( + path.resolve(assetsDir, worker), + 'utf-8' + ) + const workerSourcemap = getSourceMapUrl(workerContent) + const sharedWorker = files.find((f) => + /^my-shared-worker\.\w+\.js$/.test(f) + ) + const sharedWorkerContent = fs.readFileSync( + path.resolve(assetsDir, sharedWorker), + 'utf-8' + ) + const sharedWorkerSourcemap = getSourceMapUrl(sharedWorkerContent) + const possibleTsOutputWorker = files.find((f) => + /^possible-ts-output-worker\.\w+\.js$/.test(f) + ) + const possibleTsOutputWorkerContent = fs.readFileSync( + path.resolve(assetsDir, possibleTsOutputWorker), + 'utf-8' + ) + const possibleTsOutputWorkerSourcemap = getSourceMapUrl( + possibleTsOutputWorkerContent + ) + const workerNestedWorker = files.find((f) => + /^worker-nested-worker\.\w+\.js$/.test(f) + ) + const workerNestedWorkerContent = fs.readFileSync( + path.resolve(assetsDir, workerNestedWorker), + 'utf-8' + ) + const workerNestedWorkerSourcemap = getSourceMapUrl( + workerNestedWorkerContent + ) + const subWorker = files.find((f) => /^sub-worker\.\w+\.js$/.test(f)) + const subWorkerContent = fs.readFileSync( + path.resolve(assetsDir, subWorker), + 'utf-8' + ) + const subWorkerSourcemap = getSourceMapUrl(subWorkerContent) + + expect(files).toContainEqual(expect.stringMatching(/^index\.\w+\.js\.map$/)) + expect(files).toContainEqual( + expect.stringMatching(/^my-worker\.\w+\.js\.map$/) + ) + expect(files).toContainEqual( + expect.stringMatching(/^my-shared-worker\.\w+\.js\.map$/) + ) + expect(files).toContainEqual( + expect.stringMatching(/^possible-ts-output-worker\.\w+\.js\.map$/) + ) + expect(files).toContainEqual( + expect.stringMatching(/^worker-nested-worker\.\w+\.js\.map$/) + ) + expect(files).toContainEqual( + expect.stringMatching(/^sub-worker\.\w+\.js\.map$/) + ) + + // sourcemap should exist and have a data URL + expect(indexSourcemap).toMatch(/^main-module\.\w+\.js\.map$/) + expect(workerSourcemap).toMatch(/^my-worker\.\w+\.js\.map$/) + expect(sharedWorkerSourcemap).toMatch(/^my-shared-worker\.\w+\.js\.map$/) + expect(possibleTsOutputWorkerSourcemap).toMatch( + /^possible-ts-output-worker\.\w+\.js\.map$/ + ) + expect(workerNestedWorkerSourcemap).toMatch( + /^worker-nested-worker\.\w+\.js\.map$/ + ) + expect(subWorkerSourcemap).toMatch(/^sub-worker\.\w+\.js\.map$/) + + // worker should have all imports resolved and no exports + expect(workerContent).not.toMatch(`import`) + expect(workerContent).not.toMatch(`export`) + + // shared worker should have all imports resolved and no exports + expect(sharedWorkerContent).not.toMatch(`import`) + expect(sharedWorkerContent).not.toMatch(`export`) + + // chunk + expect(content).toMatch(`new Worker("/iife-sourcemap/assets/my-worker`) + expect(content).toMatch(`new Worker("data:application/javascript;base64`) + expect(content).toMatch( + `new Worker("/iife-sourcemap/assets/possible-ts-output-worker` + ) + expect(content).toMatch( + `new Worker("/iife-sourcemap/assets/worker-nested-worker` + ) + expect(content).toMatch( + `new SharedWorker("/iife-sourcemap/assets/my-shared-worker` + ) + + // inlined + expect(content).toMatch(`(window.URL||window.webkitURL).createObjectURL`) + expect(content).toMatch(`window.Blob`) + + expect(workerNestedWorkerContent).toMatch( + `new Worker("/iife-sourcemap/assets/sub-worker` + ) + }) +} else { + // Workaround so that testing serve does not emit + // "Your test suite must contain at least one test" + test('true', () => { + expect(true).toBe(true) + }) +} + +function getSourceMapUrl(code: string): string { + const regex = /\/\/[#@]\s(?:source(?:Mapping)?URL)=\s*(\S+)/g + const results = regex.exec(code) + + if (results && results.length >= 2) { + return results[1] + } + return null +} diff --git a/packages/playground/worker/__tests__/sourcemap/vite.config.js b/packages/playground/worker/__tests__/sourcemap/vite.config.js new file mode 100644 index 00000000000000..7d3aeeeb774e18 --- /dev/null +++ b/packages/playground/worker/__tests__/sourcemap/vite.config.js @@ -0,0 +1 @@ +module.exports = require('../../vite.config-sourcemap')(true) diff --git a/packages/playground/worker/emit-chunk-nested-worker.js b/packages/playground/worker/emit-chunk-nested-worker.js index dff0f5bc64c5ad..6cb72b9488cfaf 100644 --- a/packages/playground/worker/emit-chunk-nested-worker.js +++ b/packages/playground/worker/emit-chunk-nested-worker.js @@ -1,7 +1,28 @@ import SubWorker from './emit-chunk-sub-worker?worker' - const subWorker = new SubWorker() subWorker.onmessage = (event) => { - self.postMessage(event.data) + self.postMessage({ + type: 'emit-chunk-sub-worker', + data: event.data + }) } + +const moduleWorker = new Worker( + new URL('./module-and-worker.js', import.meta.url), + { type: 'module' } +) + +moduleWorker.onmessage = (event) => { + self.postMessage({ + type: 'module-and-worker:worker', + data: event.data + }) +} + +import('./module-and-worker').then((res) => { + self.postMessage({ + type: 'module-and-worker:module', + data: res.module + }) +}) diff --git a/packages/playground/worker/emit-chunk-sub-worker.js b/packages/playground/worker/emit-chunk-sub-worker.js index bd6b1f6e4f7419..5d20becc781dd7 100644 --- a/packages/playground/worker/emit-chunk-sub-worker.js +++ b/packages/playground/worker/emit-chunk-sub-worker.js @@ -1,6 +1,8 @@ -Promise.all([import('./modules/module2'), import('./modules/module3')]).then( - (data) => { - const _data = { ...data[0], ...data[1] } - self.postMessage(_data) - } -) +Promise.all([ + import('./module-and-worker'), + import('./modules/module2'), + import('./modules/module3') +]).then((data) => { + const _data = { ...data[0], ...data[1], ...data[2] } + self.postMessage(_data) +}) diff --git a/packages/playground/worker/index.html b/packages/playground/worker/index.html index 60289ff84d6a06..602aa3d06bfcac 100644 --- a/packages/playground/worker/index.html +++ b/packages/playground/worker/index.html @@ -1,3 +1,8 @@ +

worker template error match:

+ + const worker = new Worker(new URL('./worker.js', import.meta.url)) + +

format iife:

Expected values:
@@ -22,13 +27,13 @@

format iife:

- new Worker(new Url('./url-worker.js', import.meta.url), { type: 'module' }) + new Worker(new URL('./url-worker.js', import.meta.url), { type: 'module' }) .worker-import-meta-url

- new SharedWorker(new Url('./url-shared-worker.js', import.meta.url), { type: + new SharedWorker(new URL('./url-shared-worker.js', import.meta.url), { type: 'module' }) .shared-worker-import-meta-url

@@ -41,13 +46,13 @@

format iife:

- new Worker(new Url('./classic-worker.js', import.meta.url)) + new Worker(new URL('./classic-worker.js', import.meta.url)) .classic-worker

- new SharedWorker(new Url('./classic-shared-worker.js', import.meta.url), { + new SharedWorker(new URL('./classic-shared-worker.js', import.meta.url), { type: 'classic' }) .classic-shared-worker

@@ -57,7 +62,9 @@

format iife:

- worker emit chunk + worker emit chunk
+ module and worker:worker in worker file
+ module and worker:module in worker file
.emti-chunk-worker

@@ -68,6 +75,12 @@

+

+ module and worker:worker in simple file + .module-and-worker-worker +

+ +