From c7eeb8d69253d16dc9413d59cc13e45977a8c105 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Fri, 6 May 2022 14:07:41 +0800 Subject: [PATCH 01/10] chore: remove redundant pnpm version in ci (#8039) --- .github/workflows/ci.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4818124be2430f..9768ca4ebc3df2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,8 +47,6 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v2 - with: - version: 6 - name: Set node version to ${{ matrix.node_version }} uses: actions/setup-node@v3 @@ -85,8 +83,6 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v2 - with: - version: 6 - name: Set node version to 16 uses: actions/setup-node@v3 From 63cd53d2480e40db717aff78966240eb6482aba4 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Fri, 6 May 2022 16:00:31 +0800 Subject: [PATCH 02/10] fix: use Vitest for unit testing, clean regex bug (#8040) --- .eslintrc.cjs | 4 +- .github/workflows/ci.yml | 3 + CONTRIBUTING.md | 14 ++- jest.config.ts | 4 +- package.json | 8 +- packages/create-vite/__tests__/cli.spec.ts | 1 + .../src/jsx-runtime/babel-restore-jsx.spec.ts | 1 + .../src/jsx-runtime/restore-jsx.spec.ts | 1 + .../vite/src/node/__tests__/asset.spec.ts | 1 + .../vite/src/node/__tests__/build.spec.ts | 1 + .../src/node/__tests__/cleanString.spec.ts | Bin 4284 -> 4756 bytes .../vite/src/node/__tests__/config.spec.ts | 1 + packages/vite/src/node/__tests__/dev.spec.ts | 1 + .../src/node/__tests__/plugins/css.spec.ts | 3 +- .../src/node/__tests__/plugins/define.spec.ts | 1 + .../src/node/__tests__/plugins/import.spec.ts | 1 + packages/vite/src/node/__tests__/scan.spec.ts | 1 + .../vite/src/node/__tests__/utils.spec.ts | 1 + packages/vite/src/node/cleanString.ts | 9 +- .../server/__tests__/pluginContainer.spec.ts | 1 + .../node/server/__tests__/search-root.spec.ts | 1 + .../node/ssr/__tests__/ssrExternal.spec.ts | 1 + .../ssr/__tests__/ssrModuleLoader.spec.ts | 3 +- .../node/ssr/__tests__/ssrTransform.spec.ts | 1 + pnpm-lock.yaml | 97 ++++++++++++++++++ vitest.config.ts | 15 +++ 26 files changed, 160 insertions(+), 15 deletions(-) create mode 100644 vitest.config.ts diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 48a0bd7773b0d7..5e00df0d89e1e0 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -63,7 +63,7 @@ module.exports = defineConfig({ 'node/no-extraneous-import': [ 'error', { - allowModules: ['vite', 'less', 'sass'] + allowModules: ['vite', 'less', 'sass', 'vitest'] } ], 'node/no-extraneous-require': [ @@ -103,7 +103,7 @@ module.exports = defineConfig({ } }, { - files: ['packages/vite/types/**'], + files: ['packages/vite/types/**', '*.spec.ts'], rules: { 'node/no-extraneous-import': 'off' } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9768ca4ebc3df2..5173da859417be 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,6 +66,9 @@ jobs: - name: Build plugin-react run: pnpm run build-plugin-react + - name: Test unit + run: pnpm run test-unit + - name: Test serve run: pnpm run test-serve -- --runInBand diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 621f8de145835f..40d2bb28605167 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -67,13 +67,15 @@ And re-run `pnpm install` to link the package. ## Running Tests +### Integration Tests + Each package under `packages/playground/` contains a `__tests__` directory. The tests are run using [Jest](https://jestjs.io/) + [Playwright](https://playwright.dev/) with custom integrations to make writing tests simple. The detailed setup is inside `jest.config.js` and `scripts/jest*` files. Before running the tests, make sure that [Vite has been built](#repo-setup). On Windows, you may want to [activate Developer Mode](https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development) to solve [issues with symlink creation for non-admins](https://github.com/vitejs/vite/issues/7390). Also you may want to [set git `core.symlinks` to `true` to solve issues with symlinks in git](https://github.com/vitejs/vite/issues/5242). -Each test can be run under either dev server mode or build mode. +Each integration test can be run under either dev server mode or build mode. -- `pnpm test` by default runs every test in both serve and build mode. +- `pnpm test` by default runs every integration test in both serve and build mode, and also unit tests. - `pnpm run test-serve` runs tests only under serve mode. This is just calling `jest` so you can pass any Jest flags to this command. Since Jest will attempt to run tests in parallel, if your machine has many cores this may cause flaky test failures with multiple Playwright instances running at the same time. You can force the tests to run in series with `pnpm run test-serve -- --runInBand`. @@ -83,6 +85,14 @@ Each test can be run under either dev server mode or build mode. Note package matching is not available for the `pnpm test` script, which always runs all tests. +### Unit Tests + +Other than tests under `packages/playground/` for integration tests, packages might contains unit tests under their `__tests__` directory. Unit tests are powered by [Vitest](https://vitest.dev/). The detailed config is inside `vitest.config.ts` files. + +- `pnpm run test-unit` runs unit tests under each package. + +- You can also use `pnpm run test-unit -- [match]` to run related tests. + ### Test Env and Helpers Inside playground tests, a global `page` object is automatically available, which is a Playwright [`Page`](https://playwright.dev/docs/api/class-page) instance that has already navigated to the served page of the current playground. So writing a test is as simple as: diff --git a/jest.config.ts b/jest.config.ts index 11663af4e08107..941fccbae2af36 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -3,9 +3,7 @@ import type { Config } from '@jest/types' const config: Config.InitialOptions = { preset: 'ts-jest', - testMatch: process.env.VITE_TEST_BUILD - ? ['**/playground/**/*.spec.[jt]s?(x)'] - : ['**/*.spec.[jt]s?(x)'], + testMatch: ['**/playground/**/*.spec.[jt]s?(x)'], testTimeout: process.env.CI ? 50000 : 20000, globalSetup: './scripts/jestGlobalSetup.cjs', globalTeardown: './scripts/jestGlobalTeardown.cjs', diff --git a/package.json b/package.json index 269f1bb99cb826..843b6a4e030e39 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,11 @@ "preinstall": "npx only-allow pnpm", "format": "prettier --write .", "lint": "eslint packages/*/{src,types}/**", - "test": "run-s test-serve test-build", + "test": "run-s test-serve test-build test-unit", "test-serve": "jest", - "debug-serve": "cross-env VITE_DEBUG_SERVE=1 node --inspect-brk ./node_modules/.bin/jest", "test-build": "cross-env VITE_TEST_BUILD=1 jest", + "test-unit": "vitest run", + "debug-serve": "cross-env VITE_DEBUG_SERVE=1 node --inspect-brk ./node_modules/.bin/jest", "debug-build": "cross-env VITE_TEST_BUILD=1 VITE_PRESERVE_BUILD_ARTIFACTS=1 node --inspect-brk ./node_modules/.bin/jest", "docs": "vitepress dev docs", "build-docs": "vitepress build docs", @@ -68,7 +69,8 @@ "ts-node": "^10.4.0", "typescript": "~4.5.4", "vite": "workspace:*", - "vitepress": "^0.22.3" + "vitepress": "^0.22.3", + "vitest": "^0.10.4" }, "simple-git-hooks": { "pre-commit": "pnpm exec lint-staged --concurrent false", diff --git a/packages/create-vite/__tests__/cli.spec.ts b/packages/create-vite/__tests__/cli.spec.ts index c52998172149e6..fbfb606f486885 100644 --- a/packages/create-vite/__tests__/cli.spec.ts +++ b/packages/create-vite/__tests__/cli.spec.ts @@ -3,6 +3,7 @@ import type { ExecaSyncReturnValue, SyncOptions } from 'execa' import { commandSync } from 'execa' import { mkdirpSync, readdirSync, remove, writeFileSync } from 'fs-extra' import { join } from 'path' +import { test, expect, beforeAll, afterEach } from 'vitest' const CLI_PATH = join(__dirname, '..') diff --git a/packages/plugin-react/src/jsx-runtime/babel-restore-jsx.spec.ts b/packages/plugin-react/src/jsx-runtime/babel-restore-jsx.spec.ts index 59d6661bedd11b..391007f68c1329 100644 --- a/packages/plugin-react/src/jsx-runtime/babel-restore-jsx.spec.ts +++ b/packages/plugin-react/src/jsx-runtime/babel-restore-jsx.spec.ts @@ -1,5 +1,6 @@ import babelRestoreJSX from './babel-restore-jsx' import * as babel from '@babel/core' +import { describe, it, expect } from 'vitest' function jsx(code: string) { return babel.transform(code, { diff --git a/packages/plugin-react/src/jsx-runtime/restore-jsx.spec.ts b/packages/plugin-react/src/jsx-runtime/restore-jsx.spec.ts index c216e99bc3480d..4f6a34ee60d915 100644 --- a/packages/plugin-react/src/jsx-runtime/restore-jsx.spec.ts +++ b/packages/plugin-react/src/jsx-runtime/restore-jsx.spec.ts @@ -1,5 +1,6 @@ import { restoreJSX } from './restore-jsx' import * as babel from '@babel/core' +import { describe, it, expect } from 'vitest' async function jsx(sourceCode: string) { const [ast] = await restoreJSX(babel, sourceCode, 'test.js') diff --git a/packages/vite/src/node/__tests__/asset.spec.ts b/packages/vite/src/node/__tests__/asset.spec.ts index 6e6b969bcbd38c..8727aa6485eb26 100644 --- a/packages/vite/src/node/__tests__/asset.spec.ts +++ b/packages/vite/src/node/__tests__/asset.spec.ts @@ -1,3 +1,4 @@ +import { describe, test, expect } from 'vitest' import { assetFileNamesToFileName, getAssetHash } from '../plugins/asset' describe('getAssetHash', () => { diff --git a/packages/vite/src/node/__tests__/build.spec.ts b/packages/vite/src/node/__tests__/build.spec.ts index 578e3a4c68ff8d..b49847f1d955a4 100644 --- a/packages/vite/src/node/__tests__/build.spec.ts +++ b/packages/vite/src/node/__tests__/build.spec.ts @@ -1,6 +1,7 @@ import type { LibraryFormats, LibraryOptions } from '../build' import { resolveLibFilename } from '../build' import { resolve } from 'path' +import { describe, test, expect } from 'vitest' type FormatsToFileNames = [LibraryFormats, string][] const baseLibOptions: LibraryOptions = { diff --git a/packages/vite/src/node/__tests__/cleanString.spec.ts b/packages/vite/src/node/__tests__/cleanString.spec.ts index f307c4816b7cd31bdd579b94fab09618e0af1bdb..99ecbcaad444023d10ed467f6cd9b2794fa935bd 100644 GIT binary patch delta 402 zcmdm^I7M|rmP%%BL4Hw*LbXCkYH^8fINqMQ|F)_v38sYgx*{MY}!5N7~sVNYS zCQw2vCPo89X+YJ52KgY1sz=AE$7-wBC`HF9#cC_n#3V$=#U#XP$0UF?>wwfk+#3_4 zmz!FW2&75{igF-kXlm-Gb15h!Og_&fJNX{BOuc7bPG(+ea9(0TaYlZLMgmY$K|u*j if>_DXKy6@v-#~q+LqHBn(B!Js { test('handles configs with different alias schemas', () => { diff --git a/packages/vite/src/node/__tests__/dev.spec.ts b/packages/vite/src/node/__tests__/dev.spec.ts index 3eefd7b4b903c1..cdb0fc123f4b4f 100644 --- a/packages/vite/src/node/__tests__/dev.spec.ts +++ b/packages/vite/src/node/__tests__/dev.spec.ts @@ -1,4 +1,5 @@ import { resolveConfig } from '..' +import { describe, test, expect } from 'vitest' describe('resolveBuildOptions in dev', () => { test('build.rollupOptions should not have input in lib', async () => { diff --git a/packages/vite/src/node/__tests__/plugins/css.spec.ts b/packages/vite/src/node/__tests__/plugins/css.spec.ts index e0d1f04a6510b2..eeacaf482b0c31 100644 --- a/packages/vite/src/node/__tests__/plugins/css.spec.ts +++ b/packages/vite/src/node/__tests__/plugins/css.spec.ts @@ -2,6 +2,7 @@ import { cssUrlRE, cssPlugin, hoistAtRules } from '../../plugins/css' import { resolveConfig } from '../../config' import fs from 'fs' import path from 'path' +import { describe, vi, test, expect } from 'vitest' describe('search css url function', () => { test('some spaces before it', () => { @@ -69,7 +70,7 @@ describe('css path resolutions', () => { await buildStart.call({}) - const mockFs = jest + const mockFs = vi .spyOn(fs, 'readFile') // @ts-ignore jest.spyOn not recognize overrided `fs.readFile` definition. .mockImplementationOnce((p, encoding, callback) => { diff --git a/packages/vite/src/node/__tests__/plugins/define.spec.ts b/packages/vite/src/node/__tests__/plugins/define.spec.ts index 9a65f8f3a51cea..b9acc81cb790d5 100644 --- a/packages/vite/src/node/__tests__/plugins/define.spec.ts +++ b/packages/vite/src/node/__tests__/plugins/define.spec.ts @@ -1,3 +1,4 @@ +import { describe, test, expect } from 'vitest' import { definePlugin } from '../../plugins/define' import { resolveConfig } from '../../config' diff --git a/packages/vite/src/node/__tests__/plugins/import.spec.ts b/packages/vite/src/node/__tests__/plugins/import.spec.ts index f0341e81b50f3c..e232702d57d354 100644 --- a/packages/vite/src/node/__tests__/plugins/import.spec.ts +++ b/packages/vite/src/node/__tests__/plugins/import.spec.ts @@ -1,3 +1,4 @@ +import { describe, test, expect } from 'vitest' import { transformCjsImport } from '../../plugins/importAnalysis' describe('transformCjsImport', () => { diff --git a/packages/vite/src/node/__tests__/scan.spec.ts b/packages/vite/src/node/__tests__/scan.spec.ts index db11bcc45b284c..8d5a275fca0292 100644 --- a/packages/vite/src/node/__tests__/scan.spec.ts +++ b/packages/vite/src/node/__tests__/scan.spec.ts @@ -1,5 +1,6 @@ import { scriptRE, commentRE, importsRE } from '../optimizer/scan' import { multilineCommentsRE, singlelineCommentsRE } from '../utils' +import { describe, test, expect } from 'vitest' describe('optimizer-scan:script-test', () => { const scriptContent = `import { defineComponent } from 'vue' diff --git a/packages/vite/src/node/__tests__/utils.spec.ts b/packages/vite/src/node/__tests__/utils.spec.ts index 1162105c3f19c7..29fd53f3c9a32e 100644 --- a/packages/vite/src/node/__tests__/utils.spec.ts +++ b/packages/vite/src/node/__tests__/utils.spec.ts @@ -4,6 +4,7 @@ import { isWindows, resolveHostname } from '../utils' +import { describe, test, expect } from 'vitest' describe('injectQuery', () => { if (isWindows) { diff --git a/packages/vite/src/node/cleanString.ts b/packages/vite/src/node/cleanString.ts index 9b9ef656f4e017..d990ab75f15d7c 100644 --- a/packages/vite/src/node/cleanString.ts +++ b/packages/vite/src/node/cleanString.ts @@ -5,6 +5,7 @@ import { multilineCommentsRE, singlelineCommentsRE } from './utils' // /`([^`\$\{\}]|\$\{(`|\g<1>)*\})*`/g can match nested string template // but js not support match expression(\g<0>). so clean string template(`...`) in other ways. const stringsRE = /"([^"\r\n]|(?<=\\)")*"|'([^'\r\n]|(?<=\\)')*'/g +const regexRE = /\/.*?(? `${s[0]}${'\0'.repeat(s.length - 2)}${s[0]}` export function emptyString(raw: string): string { - let res = raw.replace(cleanerRE, (s: string) => - s[0] === '/' ? blankReplacer(s) : stringBlankReplacer(s) - ) + let res = raw + .replace(cleanerRE, (s: string) => + s[0] === '/' ? blankReplacer(s) : stringBlankReplacer(s) + ) + .replace(regexRE, (s) => stringBlankReplacer(s)) let lastEnd = 0 let start = 0 diff --git a/packages/vite/src/node/server/__tests__/pluginContainer.spec.ts b/packages/vite/src/node/server/__tests__/pluginContainer.spec.ts index 9fbd07e90aa089..ab0555ae7982e9 100644 --- a/packages/vite/src/node/server/__tests__/pluginContainer.spec.ts +++ b/packages/vite/src/node/server/__tests__/pluginContainer.spec.ts @@ -4,6 +4,7 @@ import type { Plugin } from '../../plugin' import { ModuleGraph } from '../moduleGraph' import type { PluginContainer } from '../pluginContainer' import { createPluginContainer } from '../pluginContainer' +import { describe, it, expect, beforeEach } from 'vitest' let resolveId: (id: string) => any let moduleGraph: ModuleGraph diff --git a/packages/vite/src/node/server/__tests__/search-root.spec.ts b/packages/vite/src/node/server/__tests__/search-root.spec.ts index 7322768286809e..ff9366e8791534 100644 --- a/packages/vite/src/node/server/__tests__/search-root.spec.ts +++ b/packages/vite/src/node/server/__tests__/search-root.spec.ts @@ -1,5 +1,6 @@ import { searchForWorkspaceRoot } from '../searchRoot' import { resolve } from 'path' +import { describe, test, expect } from 'vitest' describe('searchForWorkspaceRoot', () => { test('lerna', () => { diff --git a/packages/vite/src/node/ssr/__tests__/ssrExternal.spec.ts b/packages/vite/src/node/ssr/__tests__/ssrExternal.spec.ts index ad16534b088e2b..5fb51093405250 100644 --- a/packages/vite/src/node/ssr/__tests__/ssrExternal.spec.ts +++ b/packages/vite/src/node/ssr/__tests__/ssrExternal.spec.ts @@ -1,4 +1,5 @@ import { stripNesting } from '../ssrExternal' +import { test, expect } from 'vitest' test('stripNesting', async () => { expect(stripNesting(['c', 'p1>c1', 'p2 > c2'])).toEqual(['c', 'c1', 'c2']) diff --git a/packages/vite/src/node/ssr/__tests__/ssrModuleLoader.spec.ts b/packages/vite/src/node/ssr/__tests__/ssrModuleLoader.spec.ts index 6a45a2b70509d0..93a04734840d31 100644 --- a/packages/vite/src/node/ssr/__tests__/ssrModuleLoader.spec.ts +++ b/packages/vite/src/node/ssr/__tests__/ssrModuleLoader.spec.ts @@ -1,12 +1,13 @@ import { resolve } from 'path' import { createServer } from '../../index' +import { test, vi, expect } from 'vitest' const badjs = resolve(__dirname, './fixtures/ssrModuleLoader-bad.js') const THROW_MESSAGE = 'it is an expected error' test('always throw error when evaluating an wrong SSR module', async () => { const viteServer = await createServer() - const spy = jest.spyOn(console, 'error').mockImplementation(() => {}) + const spy = vi.spyOn(console, 'error').mockImplementation(() => {}) const expectedErrors = [] for (const i of [0, 1]) { try { diff --git a/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts b/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts index 0e9181214c2b82..9c1fdea5939793 100644 --- a/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts +++ b/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts @@ -1,6 +1,7 @@ import { transformWithEsbuild } from '../../plugins/esbuild' import { traverseHtml } from '../../plugins/html' import { ssrTransform } from '../ssrTransform' +import { test, expect } from 'vitest' test('default import', async () => { expect( diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d3aea697843c5b..3f15dbb27aae88 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,6 +45,7 @@ importers: typescript: ~4.5.4 vite: workspace:* vitepress: ^0.22.3 + vitest: ^0.10.4 devDependencies: '@microsoft/api-extractor': 7.23.0 '@types/fs-extra': 9.0.13 @@ -81,6 +82,7 @@ importers: typescript: 4.5.4 vite: link:packages/vite vitepress: 0.22.3 + vitest: 0.10.4 packages/create-vite: specifiers: @@ -2579,6 +2581,16 @@ packages: resolution: {integrity: sha512-+euflG6ygo4bn0JHtn4pYqcXwRtLvElQ7/nnjDu7iYG56H0+OhCd7d6Ug0IE3WcFpZozBKW2+80FUbv5QGk5AQ==} dev: true + /@types/chai-subset/1.3.3: + resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} + dependencies: + '@types/chai': 4.3.1 + dev: true + + /@types/chai/4.3.1: + resolution: {integrity: sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==} + dev: true + /@types/convert-source-map/1.5.2: resolution: {integrity: sha512-tHs++ZeXer40kCF2JpE51Hg7t4HPa18B1b1Dzy96S0eCw8QKECNMYMfwa1edK/x8yCN0r4e6ewvLcc5CsVGkdg==} dev: true @@ -3370,6 +3382,10 @@ packages: resolution: {integrity: sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==} dev: true + /assertion-error/1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + dev: true + /astral-regex/2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -3666,6 +3682,19 @@ packages: resolution: {integrity: sha512-kbaCEBRRVSoeNs74sCuq92MJyGrMtjWVfhltoHUCW4t4pXFvGjUBrfo47weBRViHkiV3eBYyIsfl956NtHGazw==} dev: false + /chai/4.3.6: + resolution: {integrity: sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==} + engines: {node: '>=4'} + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.2 + deep-eql: 3.0.1 + get-func-name: 2.0.0 + loupe: 2.3.4 + pathval: 1.1.1 + type-detect: 4.0.8 + dev: true + /chalk/2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -3692,6 +3721,10 @@ packages: is-regex: 1.1.4 dev: true + /check-error/1.0.2: + resolution: {integrity: sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=} + dev: true + /chokidar/3.5.2: resolution: {integrity: sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==} engines: {node: '>= 8.10.0'} @@ -4374,6 +4407,13 @@ packages: resolution: {integrity: sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=} dev: true + /deep-eql/3.0.1: + resolution: {integrity: sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==} + engines: {node: '>=0.12'} + dependencies: + type-detect: 4.0.8 + dev: true + /deep-is/0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true @@ -5356,6 +5396,10 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: true + /get-func-name/2.0.0: + resolution: {integrity: sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=} + dev: true + /get-intrinsic/1.1.1: resolution: {integrity: sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==} dependencies: @@ -6786,6 +6830,11 @@ packages: engines: {node: '>= 12.13.0'} dev: true + /local-pkg/0.4.1: + resolution: {integrity: sha512-lL87ytIGP2FU5PWwNDo0w3WhIo2gopIAxPg9RxDYF7m4rr5ahuZxP22xnJHIvaLTe4Z9P6uKKY2UHiwyB4pcrw==} + engines: {node: '>=14'} + dev: true + /locate-path/2.0.0: resolution: {integrity: sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=} engines: {node: '>=4'} @@ -6869,6 +6918,12 @@ packages: js-tokens: 4.0.0 dev: false + /loupe/2.3.4: + resolution: {integrity: sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==} + dependencies: + get-func-name: 2.0.0 + dev: true + /lru-cache/6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} @@ -7560,6 +7615,10 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + /pathval/1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + dev: true + /pend/1.2.0: resolution: {integrity: sha1-elfrVQpng/kRUzH89GY9XI4AelA=} dev: true @@ -9242,6 +9301,16 @@ packages: resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} dev: false + /tinypool/0.1.3: + resolution: {integrity: sha512-2IfcQh7CP46XGWGGbdyO4pjcKqsmVqFAPcXfPxcPXmOWt9cYkTP9HcDmGgsfijYoAEc4z9qcpM/BaBz46Y9/CQ==} + engines: {node: '>=14.0.0'} + dev: true + + /tinyspy/0.3.2: + resolution: {integrity: sha512-2+40EP4D3sFYy42UkgkFFB+kiX2Tg3URG/lVvAZFfLxgGpnWl5qQJuBw1gaLttq8UOS+2p3C0WrhJnQigLTT2Q==} + engines: {node: '>=14.0.0'} + dev: true + /tmp/0.2.1: resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==} engines: {node: '>=8.17.0'} @@ -9623,6 +9692,34 @@ packages: - react-dom dev: true + /vitest/0.10.4: + resolution: {integrity: sha512-FJ2av2PVozmyz9nqHRoC3H8j2z0OQXj8P8jS5oyMY9mfPWB06GS5k/1Ot++TkVBLQRHZCcVzjbK4BO7zqAJZGQ==} + engines: {node: '>=v14.16.0'} + hasBin: true + peerDependencies: + '@vitest/ui': '*' + c8: '*' + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@vitest/ui': + optional: true + c8: + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@types/chai': 4.3.1 + '@types/chai-subset': 1.3.3 + chai: 4.3.6 + local-pkg: 0.4.1 + tinypool: 0.1.3 + tinyspy: 0.3.2 + vite: link:packages/vite + dev: true + /void-elements/3.1.0: resolution: {integrity: sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=} engines: {node: '>=0.10.0'} diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 00000000000000..78e54e98cc02d9 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,15 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + exclude: [ + '**/node_modules/**', + '**/dist/**', + './packages/playground/**/*.*', + './packages/temp/**/*.*' + ] + }, + esbuild: { + target: 'node14' + } +}) From 5280908972219392a0d8daa2a33553868ca7072b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BF=A0=20/=20green?= Date: Fri, 6 May 2022 18:26:47 +0900 Subject: [PATCH 03/10] fix(css): hoist external @import for non-split css (#8022) --- packages/playground/lib/__tests__/lib.spec.ts | 7 +++++ packages/playground/lib/__tests__/serve.js | 14 +++++++++- packages/playground/lib/src/dynamic.css | 4 +++ packages/playground/lib/src/index.css | 3 ++ packages/playground/lib/src/main2.js | 5 ++++ .../playground/lib/vite.dyimport.config.js | 1 - packages/vite/src/node/plugins/css.ts | 28 +++++++++++-------- 7 files changed, 49 insertions(+), 13 deletions(-) create mode 100644 packages/playground/lib/src/dynamic.css create mode 100644 packages/playground/lib/src/index.css diff --git a/packages/playground/lib/__tests__/lib.spec.ts b/packages/playground/lib/__tests__/lib.spec.ts index f1e93e90d8357b..cc5887c2777fcb 100644 --- a/packages/playground/lib/__tests__/lib.spec.ts +++ b/packages/playground/lib/__tests__/lib.spec.ts @@ -35,6 +35,13 @@ if (isBuild) { ) expect(code).not.toMatch('__vitePreload') }) + + test('@import hoist', async () => { + serverLogs.forEach((log) => { + // no warning from esbuild css minifier + expect(log).not.toMatch('All "@import" rules must come first') + }) + }) } else { test('dev', async () => { expect(await page.textContent('.demo')).toBe('It works') diff --git a/packages/playground/lib/__tests__/serve.js b/packages/playground/lib/__tests__/serve.js index eac6980286af52..2534545de5c221 100644 --- a/packages/playground/lib/__tests__/serve.js +++ b/packages/playground/lib/__tests__/serve.js @@ -9,6 +9,8 @@ const { ports } = require('../../testUtils') const port = (exports.port = ports.lib) +global.serverLogs = [] + /** * @param {string} root * @param {boolean} isBuildTest @@ -16,6 +18,8 @@ const port = (exports.port = ports.lib) exports.serve = async function serve(root, isBuildTest) { // build first + setupConsoleWarnCollector() + if (!isBuildTest) { const { createServer } = require('vite') process.env.VITE_INLINE = 'inline-serve' @@ -55,7 +59,7 @@ exports.serve = async function serve(root, isBuildTest) { await build({ root, - logLevel: 'silent', + logLevel: 'warn', // output esbuild warns configFile: path.resolve(__dirname, '../vite.dyimport.config.js') }) @@ -89,3 +93,11 @@ exports.serve = async function serve(root, isBuildTest) { }) } } + +function setupConsoleWarnCollector() { + const warn = console.warn + console.warn = (...args) => { + global.serverLogs.push(args.join(' ')) + return warn.call(console, ...args) + } +} diff --git a/packages/playground/lib/src/dynamic.css b/packages/playground/lib/src/dynamic.css new file mode 100644 index 00000000000000..4378c8d328cfbe --- /dev/null +++ b/packages/playground/lib/src/dynamic.css @@ -0,0 +1,4 @@ +@import 'https://cdn.jsdelivr.net/npm/@mdi/font@5.9.55/css/materialdesignicons.min.css'; +.dynamic { + color: red; +} diff --git a/packages/playground/lib/src/index.css b/packages/playground/lib/src/index.css new file mode 100644 index 00000000000000..b0bd670bd9ecad --- /dev/null +++ b/packages/playground/lib/src/index.css @@ -0,0 +1,3 @@ +.index { + color: blue; +} diff --git a/packages/playground/lib/src/main2.js b/packages/playground/lib/src/main2.js index 0c729fad8d165c..f19a16bb128949 100644 --- a/packages/playground/lib/src/main2.js +++ b/packages/playground/lib/src/main2.js @@ -1,4 +1,9 @@ +import './index.css' + export default async function message(sel) { const message = await import('./message.js') + + await import('./dynamic.css') + document.querySelector(sel).textContent = message.default } diff --git a/packages/playground/lib/vite.dyimport.config.js b/packages/playground/lib/vite.dyimport.config.js index 76311f4b8ba138..d738503f0c9d09 100644 --- a/packages/playground/lib/vite.dyimport.config.js +++ b/packages/playground/lib/vite.dyimport.config.js @@ -6,7 +6,6 @@ const path = require('path') */ module.exports = { build: { - minify: false, lib: { entry: path.resolve(__dirname, 'src/main2.js'), formats: ['es'], diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index cd57acd1690902..c61e059867080b 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -443,13 +443,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { } }) // only external @imports and @charset should exist at this point - // hoist them to the top of the CSS chunk per spec (#1845 and #6333) - if (css.includes('@import') || css.includes('@charset')) { - css = await hoistAtRules(css) - } - if (minify && config.build.minify) { - css = await minifyCSS(css, config) - } + css = await finalizeCss(css, minify, config) return css } @@ -559,10 +553,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { let extractedCss = outputToExtractedCSSMap.get(opts) if (extractedCss && !hasEmitted) { hasEmitted = true - // minify css - if (config.build.minify) { - extractedCss = await minifyCSS(extractedCss, config) - } + extractedCss = await finalizeCss(extractedCss, true, config) this.emitFile({ name: 'style.css', type: 'asset', @@ -922,6 +913,21 @@ function combineSourcemapsIfExists( : map1 } +async function finalizeCss( + css: string, + minify: boolean, + config: ResolvedConfig +) { + // hoist external @imports and @charset to the top of the CSS chunk per spec (#1845 and #6333) + if (css.includes('@import') || css.includes('@charset')) { + css = await hoistAtRules(css) + } + if (minify && config.build.minify) { + css = await minifyCSS(css, config) + } + return css +} + interface PostCSSConfigResult { options: PostCSS.ProcessOptions plugins: PostCSS.Plugin[] From e0fe2008b248aec4813efba34db9e644b851943a Mon Sep 17 00:00:00 2001 From: Enzo Innocenzi Date: Fri, 6 May 2022 14:24:40 +0200 Subject: [PATCH 04/10] fix(plugin-vue): allow overwriting template.transformAssetUrls.includeAbsolute (fix #4836) (#6779) --- packages/plugin-vue/src/template.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-vue/src/template.ts b/packages/plugin-vue/src/template.ts index 72e9588967556e..c7eed9015d6339 100644 --- a/packages/plugin-vue/src/template.ts +++ b/packages/plugin-vue/src/template.ts @@ -139,7 +139,7 @@ export function resolveTemplateCompilerOptions( tags: transformAssetUrls as any } } else { - transformAssetUrls = { ...transformAssetUrls, ...assetUrlOptions } + transformAssetUrls = { ...assetUrlOptions, ...transformAssetUrls } } } else { transformAssetUrls = assetUrlOptions From c7356e0f8e7a8f7476db90204638d9834cb58101 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Fri, 6 May 2022 16:42:51 -0400 Subject: [PATCH 05/10] fix: invalidate ssrError when HMR update occurs (#8052) --- packages/vite/src/node/server/hmr.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/vite/src/node/server/hmr.ts b/packages/vite/src/node/server/hmr.ts index 8d33554706dee2..8eca99268e93d7 100644 --- a/packages/vite/src/node/server/hmr.ts +++ b/packages/vite/src/node/server/hmr.ts @@ -294,6 +294,7 @@ function invalidate(mod: ModuleNode, timestamp: number, seen: Set) { mod.lastHMRTimestamp = timestamp mod.transformResult = null mod.ssrModule = null + mod.ssrError = null mod.ssrTransformResult = null mod.importers.forEach((importer) => { if (!importer.acceptedHmrDeps.has(mod)) { From 8897da18a084d138dd32a5b4734220520e08e5a4 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Sat, 7 May 2022 11:07:05 +0800 Subject: [PATCH 06/10] chore: update workspace setup --- package.json | 2 +- pnpm-lock.yaml | 23 ----------------------- pnpm-workspace.yaml | 2 ++ 3 files changed, 3 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index 843b6a4e030e39..eae96bb7fa8dd1 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "preinstall": "npx only-allow pnpm", "format": "prettier --write .", "lint": "eslint packages/*/{src,types}/**", - "test": "run-s test-serve test-build test-unit", + "test": "run-s test-unit test-serve test-build", "test-serve": "jest", "test-build": "cross-env VITE_TEST_BUILD=1 jest", "test-unit": "vitest run", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3f15dbb27aae88..d1d5b496892229 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -280,32 +280,9 @@ importers: test-package-d: link:test-package-d test-package-e: link:test-package-e - packages/playground/nested-deps/test-package-a: - specifiers: {} - - packages/playground/nested-deps/test-package-b: - specifiers: {} - - packages/playground/nested-deps/test-package-c: - specifiers: {} - - packages/playground/nested-deps/test-package-d: - specifiers: - test-package-d-nested: link:./test-package-d-nested - dependencies: - test-package-d-nested: link:test-package-d-nested - packages/playground/nested-deps/test-package-d/test-package-d-nested: specifiers: {} - packages/playground/nested-deps/test-package-e: - specifiers: - test-package-e-excluded: link:./test-package-e-excluded - test-package-e-included: link:./test-package-e-included - dependencies: - test-package-e-excluded: link:test-package-e-excluded - test-package-e-included: link:test-package-e-included - packages/playground/nested-deps/test-package-e/test-package-e-excluded: specifiers: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index f8a7dd53d45fb0..a4e6b07cfdf222 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,5 @@ packages: - 'packages/*' - 'packages/playground/**' + - '!packages/temp' + - '!packages/playground/nested-deps/test-package-*' From b44d745360435d9eb607eaca239cc396ae41c1c0 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Sat, 7 May 2022 11:32:35 +0800 Subject: [PATCH 07/10] chore: revert workspace change --- pnpm-workspace.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index a4e6b07cfdf222..f8a7dd53d45fb0 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,5 +1,3 @@ packages: - 'packages/*' - 'packages/playground/**' - - '!packages/temp' - - '!packages/playground/nested-deps/test-package-*' From dc323a0a230f57de0d102782dd4e673fb6b2d06c Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Sat, 7 May 2022 11:32:52 +0800 Subject: [PATCH 08/10] chore: update lock --- pnpm-lock.yaml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d1d5b496892229..3f15dbb27aae88 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -280,9 +280,32 @@ importers: test-package-d: link:test-package-d test-package-e: link:test-package-e + packages/playground/nested-deps/test-package-a: + specifiers: {} + + packages/playground/nested-deps/test-package-b: + specifiers: {} + + packages/playground/nested-deps/test-package-c: + specifiers: {} + + packages/playground/nested-deps/test-package-d: + specifiers: + test-package-d-nested: link:./test-package-d-nested + dependencies: + test-package-d-nested: link:test-package-d-nested + packages/playground/nested-deps/test-package-d/test-package-d-nested: specifiers: {} + packages/playground/nested-deps/test-package-e: + specifiers: + test-package-e-excluded: link:./test-package-e-excluded + test-package-e-included: link:./test-package-e-included + dependencies: + test-package-e-excluded: link:test-package-e-excluded + test-package-e-included: link:test-package-e-included + packages/playground/nested-deps/test-package-e/test-package-e-excluded: specifiers: {} From fe704f1ff7a5532d9efd9999d9fc8793884e9fe8 Mon Sep 17 00:00:00 2001 From: patak Date: Sat, 7 May 2022 07:20:00 +0200 Subject: [PATCH 09/10] fix: graceful rename in windows (#8036) --- packages/vite/src/node/utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index d41dd6850ebb56..29741989ea2326 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -775,8 +775,8 @@ function gracefulRename( ) { setTimeout(function () { fs.stat(to, function (stater, st) { - if (stater && stater.code === 'ENOENT') gracefulRename(from, to, CB) - else cb(er) + if (stater && stater.code === 'ENOENT') fs.rename(from, to, CB) + else CB(er) }) }, backoff) if (backoff < 100) backoff += 10 From 1ffc0107e81d9196284a42dd450b8ff9d038b245 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Sat, 7 May 2022 13:30:08 +0800 Subject: [PATCH 10/10] fix: use `strip-literal` to strip string lterals (#8054) --- packages/vite/LICENSE.md | 29 ++++ packages/vite/package.json | 1 + .../src/node/__tests__/cleanString.spec.ts | Bin 4756 -> 0 bytes packages/vite/src/node/cleanString.ts | 145 ------------------ .../src/node/plugins/assetImportMetaUrl.ts | 4 +- packages/vite/src/node/plugins/css.ts | 2 +- packages/vite/src/node/plugins/html.ts | 4 +- .../src/node/plugins/workerImportMetaUrl.ts | 4 +- packages/vite/src/node/utils.ts | 4 + pnpm-lock.yaml | 8 + 10 files changed, 49 insertions(+), 152 deletions(-) delete mode 100644 packages/vite/src/node/__tests__/cleanString.spec.ts delete mode 100644 packages/vite/src/node/cleanString.ts diff --git a/packages/vite/LICENSE.md b/packages/vite/LICENSE.md index 30803708e30a76..80feb7f95c6941 100644 --- a/packages/vite/LICENSE.md +++ b/packages/vite/LICENSE.md @@ -3465,6 +3465,35 @@ Repository: chalk/strip-ansi --------------------------------------- +## strip-literal +License: MIT +By: Anthony Fu +Repository: git+https://github.com/antfu/strip-literal.git + +> MIT License +> +> Copyright (c) 2022 Anthony Fu +> +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in all +> copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +> SOFTWARE. + +--------------------------------------- + ## to-regex-range License: MIT By: Jon Schlinkert, Rouven Weßling diff --git a/packages/vite/package.json b/packages/vite/package.json index 55c86878622111..b508842619033e 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -112,6 +112,7 @@ "source-map-js": "^1.0.2", "source-map-support": "^0.5.21", "strip-ansi": "^6.0.1", + "strip-literal": "^0.2.0", "terser": "^5.13.1", "tsconfck": "^1.2.2", "tslib": "^2.4.0", diff --git a/packages/vite/src/node/__tests__/cleanString.spec.ts b/packages/vite/src/node/__tests__/cleanString.spec.ts deleted file mode 100644 index 99ecbcaad444023d10ed467f6cd9b2794fa935bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4756 zcmc&&TW{h<6z(&>;>e0LHbgjVyDwE)sqNEBttvID`Vc4bULVgdHr(Vhw5>j>q99dtRn_6|U?$ zQ-ic-GV6`~a&OBt@6aXe3caIwaIOz zZov;=`T@2Ba4bIdu-|I-W1a~^a9k5;`>&T|JS0+-{|<(so8bl=CoX->6U}mGq2=jM z9@YxqK*%adC%hK{aWF>U)_#DBuv`3Ke5HcHE~qi67}q`oNs(6;7+07c2Z8MudX2P7 z<45tN*wS@h$Yx09&G6$nGH%Ypq}hZ6KBGw4d7qsi$A8u~S@~Ya)aXwBlt zDA?wj-s|CKszh%LBr9F&#G0}fOTv8^NHvKfH4(f#?0XXdMf&|Q(sd_rSkvM>3*vR8 z!GBp&6Y7)Py2Y+&Qy%JS`!wi`c<9ESLRGac#e>d>)?_t)i(+2b26-gxhFxivh&brQ z0`v1M%t9r}gaRdiJQ)ji=UL%`zfNh$@mMhPo;fZqSk)<)8)u%zly$M* z#_hWfHQU_AsEavDC$AfGZIGU5j5^C0M|~}0qWCOpYVu2&vv)sevdGLhE0%IH;D8T< z>u4QH6dcqF7>CViGefwD{wk&@IL{QJzltfi(dXIX7)~^%Ep&@CpGz$RNqbmidI@O` zrT&D?+YekgtBs~f z75jD>H84WYV*Ea&kO)vCQ(RRyA&d^5Z;-(6Sg&a+hTF|HK?8lt=k4rUnCt=^&UgO| zphU<~_6wnl`2d_8HJB%u-NpU{a>_Z5OQ(x0Z}30W(^uPeDjVs(KQ$Jo_0m*f zR_HlCzw36qOc!|m%L{$HHdc?H%PbhLO0(ES9_Y+YmHI#hQrw6eJh!}8*8~} z({BlwK;4@@p0%9{!u#8nGKRFhWc>MD;7<#Dsh|hWNf!!!3Zc$0ie|V2QB;lm-;44O zQ@-5etJ2J65a7ZvihOE(M~9o$omCG{>T#rAyoV?6apb*3@xxOTKaQf9nQw_!_AH8c z*Ra8T6A?iWE^)v9{nh1To~60D&-JES71sS;B6lQ8dnwzEvtRwUA9*7J-!<{-h&%Q- DgfAcj diff --git a/packages/vite/src/node/cleanString.ts b/packages/vite/src/node/cleanString.ts deleted file mode 100644 index d990ab75f15d7c..00000000000000 --- a/packages/vite/src/node/cleanString.ts +++ /dev/null @@ -1,145 +0,0 @@ -import type { RollupError } from 'rollup' -import { multilineCommentsRE, singlelineCommentsRE } from './utils' - -// bank on the non-overlapping nature of regex matches and combine all filters into one giant regex -// /`([^`\$\{\}]|\$\{(`|\g<1>)*\})*`/g can match nested string template -// but js not support match expression(\g<0>). so clean string template(`...`) in other ways. -const stringsRE = /"([^"\r\n]|(?<=\\)")*"|'([^'\r\n]|(?<=\\)')*'/g -const regexRE = /\/.*?(? ' '.repeat(s.length) -const stringBlankReplacer = (s: string) => - `${s[0]}${'\0'.repeat(s.length - 2)}${s[0]}` - -export function emptyString(raw: string): string { - let res = raw - .replace(cleanerRE, (s: string) => - s[0] === '/' ? blankReplacer(s) : stringBlankReplacer(s) - ) - .replace(regexRE, (s) => stringBlankReplacer(s)) - - let lastEnd = 0 - let start = 0 - while ((start = res.indexOf('`', lastEnd)) >= 0) { - let clean - ;[clean, lastEnd] = lexStringTemplateExpression(res, start) - res = replaceAt(res, start, lastEnd, clean) - } - - return res -} - -export function emptyCssComments(raw: string) { - return raw.replace(multilineCommentsRE, blankReplacer) -} - -const enum LexerState { - // template string - inTemplateString, - inInterpolationExpression, - inObjectExpression, - // strings - inSingleQuoteString, - inDoubleQuoteString, - // comments - inMultilineCommentsRE, - inSinglelineCommentsRE -} - -function replaceAt( - string: string, - start: number, - end: number, - replacement: string -): string { - return string.slice(0, start) + replacement + string.slice(end) -} - -/** - * lex string template and clean it. - */ -function lexStringTemplateExpression( - code: string, - start: number -): [string, number] { - let state = LexerState.inTemplateString as LexerState - let clean = '`' - const opStack: LexerState[] = [state] - - function pushStack(newState: LexerState) { - state = newState - opStack.push(state) - } - - function popStack() { - opStack.pop() - state = opStack[opStack.length - 1] - } - - let i = start + 1 - outer: for (; i < code.length; i++) { - const char = code.charAt(i) - switch (state) { - case LexerState.inTemplateString: - if (char === '$' && code.charAt(i + 1) === '{') { - pushStack(LexerState.inInterpolationExpression) - clean += '${' - i++ // jump next - } else if (char === '`') { - popStack() - clean += char - if (opStack.length === 0) { - break outer - } - } else { - clean += '\0' - } - break - case LexerState.inInterpolationExpression: - if (char === '{') { - pushStack(LexerState.inObjectExpression) - clean += char - } else if (char === '}') { - popStack() - clean += char - } else if (char === '`') { - pushStack(LexerState.inTemplateString) - clean += char - } else { - clean += char - } - break - case LexerState.inObjectExpression: - if (char === '}') { - popStack() - clean += char - } else if (char === '`') { - pushStack(LexerState.inTemplateString) - clean += char - } else { - clean += char - } - break - default: - throw new Error('unknown string template lexer state') - } - } - - if (opStack.length !== 0) { - error(start) - } - - return [clean, i + 1] -} - -function error(pos: number) { - const err = new Error( - `can not match string template expression.` - ) as RollupError - err.pos = pos - throw err -} diff --git a/packages/vite/src/node/plugins/assetImportMetaUrl.ts b/packages/vite/src/node/plugins/assetImportMetaUrl.ts index b8c16f76d2b93f..217b0d3fee1564 100644 --- a/packages/vite/src/node/plugins/assetImportMetaUrl.ts +++ b/packages/vite/src/node/plugins/assetImportMetaUrl.ts @@ -3,7 +3,7 @@ import MagicString from 'magic-string' import path from 'path' import { fileToUrl } from './asset' import type { ResolvedConfig } from '../config' -import { emptyString } from '../cleanString' +import { stripLiteral } from 'strip-literal' /** * Convert `new URL('./foo.png', import.meta.url)` to its resolved built URL @@ -27,7 +27,7 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin { let s: MagicString | undefined const assetImportMetaUrlRE = /\bnew\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*,?\s*\)/g - const cleanString = emptyString(code) + const cleanString = stripLiteral(code) let match: RegExpExecArray | null while ((match = assetImportMetaUrlRE.exec(cleanString))) { diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index c61e059867080b..22dfc33f67a509 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -49,7 +49,7 @@ import { transform, formatMessages } from 'esbuild' import { addToHTMLProxyTransformResult } from './html' import { injectSourcesContent, getCodeWithSourcemap } from '../server/sourcemap' import type { RawSourceMap } from '@ampproject/remapping' -import { emptyCssComments } from '../cleanString' +import { emptyCssComments } from '../utils' // const debug = createDebugger('vite:css') diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index 0223c351af6071..6d793c416ce60a 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -36,7 +36,7 @@ import type { TextNode } from '@vue/compiler-dom' import { NodeTypes } from '@vue/compiler-dom' -import { emptyString } from '../cleanString' +import { stripLiteral } from 'strip-literal' interface ScriptAssetsUrl { start: number @@ -308,7 +308,7 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin { } } else if (node.children.length) { const scriptNode = node.children.pop()! as TextNode - const cleanCode = emptyString(scriptNode.content) + const cleanCode = stripLiteral(scriptNode.content) let match: RegExpExecArray | null while ((match = inlineImportRE.exec(cleanCode))) { diff --git a/packages/vite/src/node/plugins/workerImportMetaUrl.ts b/packages/vite/src/node/plugins/workerImportMetaUrl.ts index 3d8970b746349c..bfd8c22dcad372 100644 --- a/packages/vite/src/node/plugins/workerImportMetaUrl.ts +++ b/packages/vite/src/node/plugins/workerImportMetaUrl.ts @@ -10,7 +10,7 @@ import { ENV_ENTRY, ENV_PUBLIC_PATH } from '../constants' import MagicString from 'magic-string' import type { ViteDevServer } from '..' import type { RollupError } from 'rollup' -import { emptyString } from '../cleanString' +import { stripLiteral } from 'strip-literal' type WorkerType = 'classic' | 'module' | 'ignore' const ignoreFlagRE = /\/\*\s*@vite-ignore\s*\*\// @@ -110,7 +110,7 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin { code.includes('new URL') && code.includes(`import.meta.url`) ) { - const cleanString = emptyString(code) + const cleanString = stripLiteral(code) const workerImportMetaUrlRE = /\bnew\s+(Worker|SharedWorker)\s*\(\s*(new\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*\))/g diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index 29741989ea2326..ddcaced9832bc1 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -785,3 +785,7 @@ function gracefulRename( if (cb) cb(er) }) } + +export function emptyCssComments(raw: string) { + return raw.replace(multilineCommentsRE, (s) => ' '.repeat(s.length)) +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3f15dbb27aae88..a20eb4e3bb7d1f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -893,6 +893,7 @@ importers: source-map-js: ^1.0.2 source-map-support: ^0.5.21 strip-ansi: ^6.0.1 + strip-literal: ^0.2.0 terser: ^5.13.1 tsconfck: ^1.2.2 tslib: ^2.4.0 @@ -966,6 +967,7 @@ importers: source-map-js: 1.0.2 source-map-support: 0.5.21 strip-ansi: 6.0.1 + strip-literal: 0.2.0 terser: 5.13.1 tsconfck: 1.2.2_typescript@4.5.4 tslib: 2.4.0 @@ -9016,6 +9018,12 @@ packages: engines: {node: '>=8'} dev: true + /strip-literal/0.2.0: + resolution: {integrity: sha512-pqhiiFRDifA2CRVH0Gmv6MDbd2b27MS0oIqqy7JCqfL5m2sh68223lmEK2eoBXp4vNaq8G1Wzwd9dfQcWszUlg==} + dependencies: + acorn: 8.7.1 + dev: true + /stylis/4.0.13: resolution: {integrity: sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==}