From 51a02ff902c3afa4dff76b43f75b9221768cd7f8 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 9 Jan 2021 15:54:14 -0500 Subject: [PATCH 001/106] fix: inject css link when cssCodeSplit is disabled fix #1141 --- packages/vite/src/node/plugins/html.ts | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index 50859d783c1267..7c3a525b425211 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -2,7 +2,7 @@ import fs from 'fs' import path from 'path' import { Plugin } from '../plugin' import { ViteDevServer } from '../server' -import { OutputBundle, OutputChunk } from 'rollup' +import { OutputAsset, OutputBundle, OutputChunk } from 'rollup' import { cleanUrl, isExternalUrl, isDataUrl, generateCodeFrame } from '../utils' import { ResolvedConfig } from '../config' import slash from 'slash' @@ -293,6 +293,24 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin { result = injectToHead(result, assetTags) } + // inject css link when cssCodeSplit is false + if (!config.build.cssCodeSplit) { + const cssChunk = Object.values(bundle).find( + (chunk) => chunk.type === 'asset' && chunk.name === 'style.css' + ) as OutputAsset | undefined + if (cssChunk) { + result = injectToHead(result, [ + { + tag: 'link', + attrs: { + rel: 'stylesheet', + href: toPublicPath(cssChunk.fileName, config) + } + } + ]) + } + } + const shortEmitName = path.posix.relative(config.root, id) result = await applyHtmlTransforms( result, From 432487e24cb8688c86502e3b4e284e25c81b7dd8 Mon Sep 17 00:00:00 2001 From: Sacha STAFYNIAK Date: Sat, 9 Jan 2021 21:56:58 +0100 Subject: [PATCH 002/106] feat: allow tag injection after body open (body-prepend) (#1435) --- docs/guide/api-plugin.md | 2 +- .../playground/html/__tests__/html.spec.ts | 6 ++++ packages/playground/html/vite.config.js | 17 +++++++++ packages/vite/src/node/plugins/html.ts | 36 +++++++++++++++---- 4 files changed, 53 insertions(+), 8 deletions(-) diff --git a/docs/guide/api-plugin.md b/docs/guide/api-plugin.md index 582522a35e92ce..357e209418a51a 100644 --- a/docs/guide/api-plugin.md +++ b/docs/guide/api-plugin.md @@ -269,7 +269,7 @@ Vite plugins can also provide hooks that serve Vite-specific purposes. These hoo /** * default: 'head-prepend' */ - injectTo?: 'head' | 'body' | 'head-prepend' + injectTo?: 'head' | 'body' | 'head-prepend' | 'body-prepend' } ``` diff --git a/packages/playground/html/__tests__/html.spec.ts b/packages/playground/html/__tests__/html.spec.ts index 232e7b7b8fe68d..97f64fc010789b 100644 --- a/packages/playground/html/__tests__/html.spec.ts +++ b/packages/playground/html/__tests__/html.spec.ts @@ -55,6 +55,12 @@ function testPage(isNested: boolean) { } }) + test('body prepend/append transform', async () => { + expect(await page.innerHTML('body')).toMatch( + /prepended to body(.*)appended to body/s + ) + }) + test('css', async () => { expect(await getColor('h1')).toBe(isNested ? 'red' : 'blue') expect(await getColor('p')).toBe('grey') diff --git a/packages/playground/html/vite.config.js b/packages/playground/html/vite.config.js index 83b4deea9cf228..ba56b2f2555bd9 100644 --- a/packages/playground/html/vite.config.js +++ b/packages/playground/html/vite.config.js @@ -121,6 +121,23 @@ module.exports = { ] } } + }, + { + name: 'body-prepend-transform', + transformIndexHtml() { + return [ + { + tag: 'noscript', + children: '', + injectTo: 'body' + }, + { + tag: 'noscript', + children: '', + injectTo: 'body-prepend' + } + ] + } } ] } diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index 7c3a525b425211..2ca940b5b09387 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -339,7 +339,7 @@ export interface HtmlTagDescriptor { /** * default: 'head-prepend' */ - injectTo?: 'head' | 'body' | 'head-prepend' + injectTo?: 'head' | 'body' | 'head-prepend' | 'body-prepend' } export type IndexHtmlTransformResult = @@ -408,6 +408,7 @@ export async function applyHtmlTransforms( const headTags: HtmlTagDescriptor[] = [] const headPrependTags: HtmlTagDescriptor[] = [] const bodyTags: HtmlTagDescriptor[] = [] + const bodyPrependTags: HtmlTagDescriptor[] = [] const ctx: IndexHtmlTransformContext = { path, @@ -435,6 +436,8 @@ export async function applyHtmlTransforms( for (const tag of tags) { if (tag.injectTo === 'body') { bodyTags.push(tag) + } else if (tag.injectTo === 'body-prepend') { + bodyPrependTags.push(tag) } else if (tag.injectTo === 'head') { headTags.push(tag) } else { @@ -451,6 +454,9 @@ export async function applyHtmlTransforms( if (headTags.length) { html = injectToHead(html, headTags) } + if (bodyPrependTags.length) { + html = injectToBody(html, bodyPrependTags, true) + } if (bodyTags.length) { html = injectToBody(html, bodyTags) } @@ -488,13 +494,29 @@ function injectToHead( } const bodyInjectRE = /<\/body>/ -function injectToBody(html: string, tags: HtmlTagDescriptor[]) { - const tagsHtml = `\n` + serializeTags(tags) - if (bodyInjectRE.test(html)) { - return html.replace(bodyInjectRE, `${tagsHtml}\n$&`) +const bodyPrependInjectRE = // +function injectToBody( + html: string, + tags: HtmlTagDescriptor[], + prepend = false +) { + if (prepend) { + // inject after body open + const tagsHtml = `\n` + serializeTags(tags) + if (bodyPrependInjectRE.test(html)) { + return html.replace(bodyPrependInjectRE, `$&\n${tagsHtml}`) + } + // if no body, prepend + return tagsHtml + `\n` + html + } else { + // inject before body close + const tagsHtml = `\n` + serializeTags(tags) + if (bodyInjectRE.test(html)) { + return html.replace(bodyInjectRE, `${tagsHtml}\n$&`) + } + // if no body, append + return html + `\n` + tagsHtml } - // if no body, append - return html + `\n` + tagsHtml } const unaryTags = new Set(['link', 'meta', 'base']) From 4647e072cb89d6eac648a66314f26cb6b65c68b4 Mon Sep 17 00:00:00 2001 From: Florian Dreier Date: Sat, 9 Jan 2021 21:58:19 +0100 Subject: [PATCH 003/106] docs: Typo in plugin-legacy README (#1455) [skip ci] --- packages/plugin-legacy/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-legacy/README.md b/packages/plugin-legacy/README.md index 835af84fe3cdee..4adf8a4de8e509 100644 --- a/packages/plugin-legacy/README.md +++ b/packages/plugin-legacy/README.md @@ -43,7 +43,7 @@ export default { - **Type:** `boolean | string[]` - **Default:** `true` - By default, a polyfills chunks are generated based on the target browser ranges and actual usage in the final bundle (detected via `@babel/preset-env`'s `useBuiltIns: 'usage'`). + By default, a polyfills chunk is generated based on the target browser ranges and actual usage in the final bundle (detected via `@babel/preset-env`'s `useBuiltIns: 'usage'`). Set to a list of strings to explicitly control which polyfills to include. See [Polyfill Specifiers](#polyfill-specifiers) for details. From bc0f72f44159832d9f7d2ca0e8c862202ae0e38f Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 9 Jan 2021 15:59:14 -0500 Subject: [PATCH 004/106] release: plugin-legacy@1.1.1 --- packages/plugin-legacy/CHANGELOG.md | 9 +++++++++ packages/plugin-legacy/package.json | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/plugin-legacy/CHANGELOG.md b/packages/plugin-legacy/CHANGELOG.md index a96186ae31e94a..0feacab27a8ba0 100644 --- a/packages/plugin-legacy/CHANGELOG.md +++ b/packages/plugin-legacy/CHANGELOG.md @@ -1,3 +1,12 @@ +## [1.1.1](https://github.com/vitejs/vite/compare/plugin-legacy@1.1.0...plugin-legacy@1.1.1) (2021-01-09) + + +### Bug Fixes + +* **plugin-legacy:** add `index.d.ts` at publish ([#1457](https://github.com/vitejs/vite/issues/1457)) ([dce2456](https://github.com/vitejs/vite/commit/dce245629651edab9719127deaf07ecfbcf20c5f)) + + + # [1.1.0](https://github.com/vitejs/vite/compare/plugin-legacy@1.0.1...plugin-legacy@1.1.0) (2021-01-07) diff --git a/packages/plugin-legacy/package.json b/packages/plugin-legacy/package.json index ecf69b67adb574..d7f824d96684a0 100644 --- a/packages/plugin-legacy/package.json +++ b/packages/plugin-legacy/package.json @@ -1,6 +1,6 @@ { "name": "@vitejs/plugin-legacy", - "version": "1.1.0", + "version": "1.1.1", "license": "MIT", "author": "Evan You", "files": [ From 80071b2b83f1d7d2e54eca7266b2b844d4a6757c Mon Sep 17 00:00:00 2001 From: Amour1688 <31695475+Amour1688@users.noreply.github.com> Date: Sun, 10 Jan 2021 05:07:25 +0800 Subject: [PATCH 005/106] refactor(plugin-vue-jsx): use options interface of `@vue/babel-plugin-jsx` (#1454) --- packages/plugin-vue-jsx/index.d.ts | 11 ++--------- packages/plugin-vue-jsx/package.json | 2 +- yarn.lock | 8 ++++---- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/packages/plugin-vue-jsx/index.d.ts b/packages/plugin-vue-jsx/index.d.ts index faabb66bab0f86..4948b9551ef181 100644 --- a/packages/plugin-vue-jsx/index.d.ts +++ b/packages/plugin-vue-jsx/index.d.ts @@ -1,13 +1,6 @@ import { Plugin } from 'vite' +import { VueJSXPluginOptions } from '@vue/babel-plugin-jsx' -// https://github.com/vuejs/jsx-next/tree/dev/packages/babel-plugin-jsx#options -export interface Options { - transformOn?: boolean - optimize?: boolean - isCustomElement?: (tag: string) => boolean - mergeProps?: boolean -} - -declare function createPlugin(options?: Options): Plugin +declare function createPlugin(options?: VueJSXPluginOptions): Plugin export default createPlugin diff --git a/packages/plugin-vue-jsx/package.json b/packages/plugin-vue-jsx/package.json index ccc39b474a7b51..ce7d46356b5c9c 100644 --- a/packages/plugin-vue-jsx/package.json +++ b/packages/plugin-vue-jsx/package.json @@ -27,7 +27,7 @@ "@babel/core": "^7.12.10", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-transform-typescript": "^7.12.1", - "@vue/babel-plugin-jsx": "^1.0.0", + "@vue/babel-plugin-jsx": "^1.0.1", "hash-sum": "^2.0.0" } } diff --git a/yarn.lock b/yarn.lock index b4382c2934ee2f..37bfcd6b84f3e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1128,10 +1128,10 @@ resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.0.tgz#8cbec6bbcae53626ad70139061be5e73403c9a62" integrity sha512-svFuKPoXP92TJ76ztENOglOsLjcMGUXkdeQhYDxl6KBnZCpqFjqx6RodUPWFg1bj4zsUVsfoIh1RibLO86fUUQ== -"@vue/babel-plugin-jsx@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.0.0.tgz#1dabe1cf8588d088226fd5666ff1987f2f11982d" - integrity sha512-WoqRUaslY52PKJFcd7PZExAxhvm6xU5u47l2xFi+UbywzTh/vU2WwgGg3rA2N1HqYJbWFT9hDGFcFqOT6hcBHw== +"@vue/babel-plugin-jsx@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.0.1.tgz#8ece4e521888fabe2c96adca428606e5cea55f54" + integrity sha512-pE1YlINZBzqaLeSNfrvo0nNvYjtWTBU+sXUrx65sLW7DL+nDCZcAVeVkMFDcpT1jIahx4hI3EzOcGZE6oLPLoA== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/plugin-syntax-jsx" "^7.0.0" From 86a727bf59f2c3ecd1c8041bb30a342944bebcb2 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 9 Jan 2021 16:25:35 -0500 Subject: [PATCH 006/106] release: v2.0.0-beta.16 --- packages/vite/CHANGELOG.md | 15 +++++++++++++++ packages/vite/package.json | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/vite/CHANGELOG.md b/packages/vite/CHANGELOG.md index fa47a463c09cb4..b649d4b48ca2c3 100644 --- a/packages/vite/CHANGELOG.md +++ b/packages/vite/CHANGELOG.md @@ -1,3 +1,18 @@ +# [2.0.0-beta.16](https://github.com/vitejs/vite/compare/v2.0.0-beta.15...v2.0.0-beta.16) (2021-01-09) + + +### Bug Fixes + +* inject css link when cssCodeSplit is disabled ([51a02ff](https://github.com/vitejs/vite/commit/51a02ff902c3afa4dff76b43f75b9221768cd7f8)), closes [#1141](https://github.com/vitejs/vite/issues/1141) +* set NODE_ENV for build ([d7ceabe](https://github.com/vitejs/vite/commit/d7ceabe92efe1c523ee05a6941e3f5042733b2bf)), closes [#1445](https://github.com/vitejs/vite/issues/1445) [#1452](https://github.com/vitejs/vite/issues/1452) + + +### Features + +* allow tag injection after body open (body-prepend) ([#1435](https://github.com/vitejs/vite/issues/1435)) ([432487e](https://github.com/vitejs/vite/commit/432487e24cb8688c86502e3b4e284e25c81b7dd8)) + + + # [2.0.0-beta.15](https://github.com/vitejs/vite/compare/v2.0.0-beta.14...v2.0.0-beta.15) (2021-01-09) diff --git a/packages/vite/package.json b/packages/vite/package.json index b2dfacb43ac270..45fa1fa88173f8 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -1,6 +1,6 @@ { "name": "vite", - "version": "2.0.0-beta.15", + "version": "2.0.0-beta.16", "license": "MIT", "author": "Evan You", "description": "Native-ESM powered web dev build tool", From 23d0f2b85d8eb8677e30456342000cabed8e684e Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 9 Jan 2021 21:53:16 -0500 Subject: [PATCH 007/106] refactor: support glob import under `import.meta.glob` BREAKING CHANGE: Glob import syntax has changed. The feature is now exposed under `import.meta.glob` (lazy, exposes dynamic import functions) and `import.meta.globEager` (eager, exposes already imported modules). --- docs/guide/features.md | 42 ++++-- .../glob-import/__tests__/glob-import.spec.ts | 19 +-- packages/playground/glob-import/dir/index.js | 2 +- .../playground/glob-import/dir/nested/bar.js | 2 +- packages/playground/glob-import/index.html | 17 ++- packages/vite/client.d.ts | 25 +++- .../vite/src/node/plugins/importAnalysis.ts | 27 ++-- packages/vite/src/node/plugins/importGlob.ts | 132 ++++++++++++------ packages/vite/src/node/server/hmr.ts | 2 +- 9 files changed, 175 insertions(+), 93 deletions(-) diff --git a/docs/guide/features.md b/docs/guide/features.md index 5da7c39ab918eb..103e335cff26ba 100644 --- a/docs/guide/features.md +++ b/docs/guide/features.md @@ -181,23 +181,21 @@ import { field } from './example.json' ## Glob Import -> Requires ^2.0.0-beta.13 +> Requires ^2.0.0-beta.17 -Vite supports importing multiple modules from the file system using a [glob pattern](https://github.com/mrmlnc/fast-glob#pattern-syntax): +Vite supports importing multiple modules from the file system via the special `import.meta.glob` function: ```js -import modules from 'glob:./dir/**' +const modules = import.meta.glob('./dir/*.js') ``` -Will be transformed to the following: +The above will be transformed into the following: ```js // code produced by vite -import * as __glob__0_0 from './dir/foo.js' -import * as __glob__0_1 from './dir/bar.js' const modules = { - './dir/foo.js': __glob__0_0, - './dir/bar.js': __glob__0_1 + './dir/foo.js': () => import('./dir/foo.js'), + './dir/bar.js': () => import('./dir/bar.js') } ``` @@ -205,15 +203,33 @@ You can then iterate over the keys of the `modules` object to access the corresp ```js for (const path in modules) { - console.log(modules[path]) + modules[path]().then((mod) => { + console.log(path, mod) + }) } ``` -Some notes on the glob import syntax: +Matched files are by default lazy loaded via dynamic import and will be split into separate chunks during build. If you'd rather import all the modules directly (e.g. relying on side-effects in these modules to be applied first), you can use `import.meta.globEager` instead: -- Glob imports must start with the `glob:` prefix and followed by a [glob pattern](https://github.com/mrmlnc/fast-glob#pattern-syntax). -- Glob patterns must be relative and start with `.` -- Glob imports can only use the default import specifier (no named imports, no `import * as ...`). +```js +const modules = import.meta.glob('./dir/*.js') +``` + +The above will be transformed into the following: + +```js +// code produced by vite +const modules = { + './dir/foo.js': () => import('./dir/foo.js'), + './dir/bar.js': () => import('./dir/bar.js') +} +``` + +Note that: + +- This is a Vite-only feature and is not a web or ES standard. +- The glob patterns must be relative and start with `.`. +- The glob matching is done via `fast-glob` - check out its documentation for [supported glob patterns](https://github.com/mrmlnc/fast-glob#pattern-syntax). ## Web Assembly diff --git a/packages/playground/glob-import/__tests__/glob-import.spec.ts b/packages/playground/glob-import/__tests__/glob-import.spec.ts index 3c2fc03f3665c2..f4e37ec46b7d0f 100644 --- a/packages/playground/glob-import/__tests__/glob-import.spec.ts +++ b/packages/playground/glob-import/__tests__/glob-import.spec.ts @@ -31,19 +31,12 @@ const allResult = { './dir/index.js': { modules: filteredResult }, - './dir/nested/bar.js': isBuild - ? { - msg: 'bar', - modules: { - '../baz.json': json - } - } - : { - modules: { - '../baz.json': json - }, - msg: 'bar' - } + './dir/nested/bar.js': { + modules: { + '../baz.json': json + }, + msg: 'bar' + } } test('should work', async () => { diff --git a/packages/playground/glob-import/dir/index.js b/packages/playground/glob-import/dir/index.js index 1029969704eef0..7adc59a0b14f5e 100644 --- a/packages/playground/glob-import/dir/index.js +++ b/packages/playground/glob-import/dir/index.js @@ -1,3 +1,3 @@ -import modules from 'glob:./*.js' +const modules = import.meta.globEager('./*.js') export { modules } diff --git a/packages/playground/glob-import/dir/nested/bar.js b/packages/playground/glob-import/dir/nested/bar.js index 1dfb9d52105c39..a2d2921cca80ad 100644 --- a/packages/playground/glob-import/dir/nested/bar.js +++ b/packages/playground/glob-import/dir/nested/bar.js @@ -1,4 +1,4 @@ -import modules from 'glob:../*.json' +const modules = import.meta.globEager('../*.json') export const msg = 'bar' export { modules } diff --git a/packages/playground/glob-import/index.html b/packages/playground/glob-import/index.html index 134f1eff1c3c01..541898db833426 100644 --- a/packages/playground/glob-import/index.html +++ b/packages/playground/glob-import/index.html @@ -2,7 +2,20 @@ diff --git a/packages/vite/client.d.ts b/packages/vite/client.d.ts index aa01074a696ca5..d802d1eace906b 100644 --- a/packages/vite/client.d.ts +++ b/packages/vite/client.d.ts @@ -24,8 +24,25 @@ interface ImportMeta { } readonly env: ImportMetaEnv -} + glob( + pattern: string + ): Record< + string, + () => Promise<{ + [key: string]: any + }> + > + + globEager( + pattern: string + ): Record< + string, + { + [key: string]: any + } + > +} interface ImportMetaEnv { [key: string]: string | boolean | undefined BASE_URL: string @@ -187,9 +204,3 @@ declare module '*?worker&inline' { } export default workerConstructor } - -// glob import -declare module 'glob:*' { - const modules: Record> - export default modules -} diff --git a/packages/vite/src/node/plugins/importAnalysis.ts b/packages/vite/src/node/plugins/importAnalysis.ts index a478f19d26d04f..26a7e985cc377b 100644 --- a/packages/vite/src/node/plugins/importAnalysis.ts +++ b/packages/vite/src/node/plugins/importAnalysis.ts @@ -254,25 +254,22 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { } } else if (prop === '.env') { hasEnv = true + } else if (prop === '.glo' && source[end + 4] === 'b') { + // transform import.meta.glob() + // e.g. `import.meta.glob('glob:./dir/*.js')` + const { imports, exp, endIndex } = await transformImportGlob( + source, + start, + importer, + index, + normalizeUrl + ) + str().prepend(imports) + str().overwrite(expStart, endIndex, exp) } continue } - // transform import context - // e.g. `import modules from 'glob:./dir/*.js'` - if (url.startsWith('glob:')) { - const result = await transformImportGlob( - source.slice(expStart, expEnd), - url, - importer, - index, - start, - normalizeUrl - ) - str().overwrite(expStart, expEnd, result) - continue - } - // For dynamic id, check if it's a literal that we can resolve let hasViteIgnore = false let isLiteralDynamicId = false diff --git a/packages/vite/src/node/plugins/importGlob.ts b/packages/vite/src/node/plugins/importGlob.ts index cd7fe8a9335f15..1d07f56872f437 100644 --- a/packages/vite/src/node/plugins/importGlob.ts +++ b/packages/vite/src/node/plugins/importGlob.ts @@ -2,11 +2,10 @@ import path from 'path' import glob from 'fast-glob' import { ResolvedConfig } from '../config' import { Plugin } from '../plugin' -import { parse as parseJS } from 'acorn' import { cleanUrl } from '../utils' -import type { Node } from 'estree' import MagicString from 'magic-string' import { ImportSpecifier, init, parse as parseImports } from 'es-module-lexer' +import { RollupError } from 'rollup' /** * Build only. During serve this is performed as part of ./importAnalysis. @@ -20,7 +19,7 @@ export function importGlobPlugin(config: ResolvedConfig): Plugin { // skip deps importer.includes('node_modules') || // fast check for presence of glob keyword - source.indexOf('glob:.') < 0 + source.indexOf('import.meta.glob') < 0 ) { return } @@ -42,17 +41,17 @@ export function importGlobPlugin(config: ResolvedConfig): Plugin { const str = () => s || (s = new MagicString(source)) for (let index = 0; index < imports.length; index++) { - const { s: start, e: end, ss: expStart, se: expEnd } = imports[index] + const { s: start, e: end, ss: expStart } = imports[index] const url = source.slice(start, end) - if (url.startsWith('glob:')) { - const result = await transformImportGlob( - source.slice(expStart, expEnd), - url, + if (url === 'import.meta' && source.slice(end, end + 5) === '.glob') { + const { imports, exp, endIndex } = await transformImportGlob( + source, + start, importer, - index, - start + index ) - str().overwrite(expStart, expEnd, result) + str().prepend(imports) + str().overwrite(expStart, endIndex, exp) } } @@ -67,44 +66,22 @@ export function importGlobPlugin(config: ResolvedConfig): Plugin { } export async function transformImportGlob( - exp: string, - url: string, + source: string, + pos: number, importer: string, importIndex: number, - pos: number, normalizeUrl?: (url: string, pos: number) => Promise<[string, string]> -): Promise { +): Promise<{ imports: string; exp: string; endIndex: number }> { const err = (msg: string) => { const e = new Error(`Invalid glob import syntax: ${msg}`) ;(e as any).pos = pos return e } - const node = (parseJS(exp, { - ecmaVersion: 2020, - sourceType: 'module' - }) as any).body[0] as Node - - if (node.type !== 'ImportDeclaration') { - throw err(`statement must be an import declaration.`) - } - - let localName: string | undefined - for (const spec of node.specifiers) { - if (spec.type !== 'ImportDefaultSpecifier') { - throw err(`can only use the default import.`) - } - localName = spec.local.name - break - } - if (!localName) { - throw err(`missing default import.`) - } - importer = cleanUrl(importer) const importerBasename = path.basename(importer) - let pattern = url.slice(5) + let [pattern, endIndex] = lexGlobPattern(source, pos) if (!pattern.startsWith('.')) { throw err(`pattern must start with "."`) } @@ -133,9 +110,84 @@ export async function transformImportGlob( ;[importee] = await normalizeUrl(file, pos) } const identifier = `__glob_${importIndex}_${i}` - imports += `import * as ${identifier} from "${importee}";\n` - entries += `\n ${JSON.stringify(file)}: ${identifier},` + const isEager = source.slice(pos, pos + 21) === 'import.meta.globEager' + if (isEager) { + imports += `import * as ${identifier} from ${JSON.stringify(importee)};` + entries += ` ${JSON.stringify(file)}: ${identifier},` + } else { + entries += ` ${JSON.stringify(file)}: () => import(${JSON.stringify( + importee + )}),` + } + } + + return { + imports, + exp: `{${entries}}`, + endIndex + } +} + +const enum LexerState { + inCall, + inSingleQuoteString, + inDoubleQuoteString, + inTemplateString +} + +function lexGlobPattern(code: string, pos: number): [string, number] { + let state = LexerState.inCall + let pattern = '' + + let i = code.indexOf(`(`, pos) + 1 + outer: for (; i < code.length; i++) { + const char = code.charAt(i) + switch (state) { + case LexerState.inCall: + if (char === `'`) { + state = LexerState.inSingleQuoteString + } else if (char === `"`) { + state = LexerState.inDoubleQuoteString + } else if (char === '`') { + state = LexerState.inTemplateString + } else if (/\s/.test(char)) { + continue + } else { + error(i) + } + break + case LexerState.inSingleQuoteString: + if (char === `'`) { + break outer + } else { + pattern += char + } + break + case LexerState.inDoubleQuoteString: + if (char === `"`) { + break outer + } else { + pattern += char + } + break + case LexerState.inTemplateString: + if (char === '`') { + break outer + } else { + pattern += char + } + break + default: + throw new Error('unknown import.meta.glob lexer state') + } } + return [pattern, code.indexOf(`)`, i) + 1] +} - return `${imports}const ${localName} = {${entries}\n}` +function error(pos: number) { + const err = new Error( + `import.meta.glob() can only accept string literals.` + ) as RollupError + err.pos = pos + throw err } diff --git a/packages/vite/src/node/server/hmr.ts b/packages/vite/src/node/server/hmr.ts index 140ee2af18d90d..d4a588cf3b94d4 100644 --- a/packages/vite/src/node/server/hmr.ts +++ b/packages/vite/src/node/server/hmr.ts @@ -328,7 +328,7 @@ export function lexAcceptedHmrDeps( } break default: - throw new Error('unknown lexer state') + throw new Error('unknown import.meta.hot lexer state') } } return false From 1e13c0a0bcd2df9535ae2371c0dcfd9fb06dcb71 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 9 Jan 2021 21:58:35 -0500 Subject: [PATCH 008/106] release: v2.0.0-beta.17 --- packages/vite/CHANGELOG.md | 16 ++++++++++++++++ packages/vite/package.json | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/vite/CHANGELOG.md b/packages/vite/CHANGELOG.md index b649d4b48ca2c3..5c4f7cec392a1d 100644 --- a/packages/vite/CHANGELOG.md +++ b/packages/vite/CHANGELOG.md @@ -1,3 +1,19 @@ +# [2.0.0-beta.17](https://github.com/vitejs/vite/compare/v2.0.0-beta.16...v2.0.0-beta.17) (2021-01-10) + + +### Code Refactoring + +* support glob import under `import.meta.glob` ([23d0f2b](https://github.com/vitejs/vite/commit/23d0f2b85d8eb8677e30456342000cabed8e684e)) + + +### BREAKING CHANGES + +* Glob import syntax has changed. The feature is now +exposed under `import.meta.glob` (lazy, exposes dynamic import functions) +and `import.meta.globEager` (eager, exposes already imported modules). + + + # [2.0.0-beta.16](https://github.com/vitejs/vite/compare/v2.0.0-beta.15...v2.0.0-beta.16) (2021-01-09) diff --git a/packages/vite/package.json b/packages/vite/package.json index 45fa1fa88173f8..c26d9817564338 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -1,6 +1,6 @@ { "name": "vite", - "version": "2.0.0-beta.16", + "version": "2.0.0-beta.17", "license": "MIT", "author": "Evan You", "description": "Native-ESM powered web dev build tool", From 91dbb017091c175a54bcd1c93a69f8458d1bde8d Mon Sep 17 00:00:00 2001 From: zhenzhenChange <1506678296@qq.com> Date: Sun, 10 Jan 2021 11:00:05 +0800 Subject: [PATCH 009/106] chore: typos (#1463) [skip ci] --- docs/config/index.md | 4 ++-- docs/guide/api-hmr.md | 2 +- docs/guide/api-javascript.md | 6 ++--- docs/guide/api-plugin.md | 2 +- docs/guide/migration.md | 2 +- packages/plugin-vue-jsx/README.md | 2 +- packages/plugin-vue/src/handleHotUpdate.ts | 2 +- packages/vite/src/client/client.ts | 4 ++-- packages/vite/src/node/optimizer/index.ts | 2 +- packages/vite/src/node/plugins/asset.ts | 2 +- .../src/node/plugins/dynamicImportPolyfill.ts | 2 +- .../vite/src/node/plugins/importAnalysis.ts | 4 ++-- packages/vite/src/node/plugins/resolve.ts | 4 ++-- packages/vite/src/node/server/index.ts | 6 ++--- .../vite/src/node/server/middlewares/proxy.ts | 2 +- packages/vite/src/node/server/moduleGraph.ts | 22 +++++++++---------- 16 files changed, 34 insertions(+), 34 deletions(-) diff --git a/docs/config/index.md b/docs/config/index.md index af090b63b2a810..336e83984b31e8 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -103,7 +103,7 @@ export default ({ command, mode }) => { - **Type:** `string` - **Default:** `'development'` for serve, `'production'` for build - Specifying this in config will override the default mode for both serve and build. This value can also be overriden via the command line `--mode` option. + Specifying this in config will override the default mode for both serve and build. This value can also be overridden via the command line `--mode` option. See [Env Variables and Modes](/guide/env-and-mode) for more details. @@ -192,7 +192,7 @@ export default ({ command, mode }) => { - **Type:** `string[]` - If you have duplicated copies of the same depdendency in your app (likely due to hoisting or linked packages in monorepos), use this option to force Vite to always resolve listed dependencies to the same copy (from + If you have duplicated copies of the same dependency in your app (likely due to hoisting or linked packages in monorepos), use this option to force Vite to always resolve listed dependencies to the same copy (from project root). ### logLevel diff --git a/docs/guide/api-hmr.md b/docs/guide/api-hmr.md index adea2454038f9b..cc58ebce612999 100644 --- a/docs/guide/api-hmr.md +++ b/docs/guide/api-hmr.md @@ -3,7 +3,7 @@ :::tip Note This is the client HMR API. For handling HMR update in plugins, see [handleHotUpdate](./api-plugin#handlehotupdate). -The manual HMR API is primarly intended for framework and tooling authors. As an end user, HMR is likely already handled for you in the framework specific starter templates. +The manual HMR API is primarily intended for framework and tooling authors. As an end user, HMR is likely already handled for you in the framework specific starter templates. ::: Vite exposes its manual HMR API via the special `import.meta.hot` object: diff --git a/docs/guide/api-javascript.md b/docs/guide/api-javascript.md index dcb1eb0ac640e4..08efcef52b96fc 100644 --- a/docs/guide/api-javascript.md +++ b/docs/guide/api-javascript.md @@ -33,7 +33,7 @@ const { createServer } = require('vite') The `InlineConfig` interface extends `UserConfig` with additional properties: - `mode`: override default mode (`'development'` for server) -- `configFile`: specifcy config file to use. If not set, Vite will try to automatically resolve one from project root. Set to `false` to disable auto resolving. +- `configFile`: specify config file to use. If not set, Vite will try to automatically resolve one from project root. Set to `false` to disable auto resolving. ## `ViteDevServer` @@ -72,12 +72,12 @@ interface ViteDevServer { */ moduleGraph: ModuleGraph /** - * Programatically resolve, load and transform a URL and get the result + * Programmatically resolve, load and transform a URL and get the result * without going through the http request pipeline. */ transformRequest(url: string): Promise /** - * Util for transfoming a file with esbuild. + * Util for transforming a file with esbuild. * Can be useful for certain plugins. */ transformWithEsbuild( diff --git a/docs/guide/api-plugin.md b/docs/guide/api-plugin.md index 357e209418a51a..7c2c73c8f13e70 100644 --- a/docs/guide/api-plugin.md +++ b/docs/guide/api-plugin.md @@ -124,7 +124,7 @@ Vite plugins can also provide hooks that serve Vite-specific purposes. These hoo **Example:** ```js - const exmaplePlugin = () => { + const examplePlugin = () => { let config return { diff --git a/docs/guide/migration.md b/docs/guide/migration.md index 820b4e9ed16cda..57270e2c47e47d 100644 --- a/docs/guide/migration.md +++ b/docs/guide/migration.md @@ -29,7 +29,7 @@ `server`. - `hostname` is now [`server.host`](/config/#server-host). - - `httpsOptions` has been removed. [`server.https`](/config/#server-https) can diretly accept the options object. + - `httpsOptions` has been removed. [`server.https`](/config/#server-https) can directly accept the options object. - `chokidarWatchOptions` is now [`server.watch`](/config/#server-watch). - [`assetsInclude`](/config/#assetsInclude) now expects `string | RegExp | (string | RegExp)[]` instead of a function. diff --git a/packages/plugin-vue-jsx/README.md b/packages/plugin-vue-jsx/README.md index e4f0836a5f6436..098c7559a811b7 100644 --- a/packages/plugin-vue-jsx/README.md +++ b/packages/plugin-vue-jsx/README.md @@ -33,7 +33,7 @@ import { defineComponent } from 'vue' // named exports w/ variable declaration: ok export const Foo = defineComponent(...) -// named exports referencing vairable declaration: ok +// named exports referencing variable declaration: ok const Bar = defineComponent(...) export { Bar } diff --git a/packages/plugin-vue/src/handleHotUpdate.ts b/packages/plugin-vue/src/handleHotUpdate.ts index 00455a7e0804d9..be131824da3bcd 100644 --- a/packages/plugin-vue/src/handleHotUpdate.ts +++ b/packages/plugin-vue/src/handleHotUpdate.ts @@ -104,7 +104,7 @@ export async function handleHotUpdate({ // custom blocks update causes a reload // because the custom block contents is changed and it may be used in JS. if (prevCustoms.length !== nextCustoms.length) { - // block rmeoved/added, force reload + // block removed/added, force reload affectedModules.add(mainModule) } else { for (let i = 0; i < nextCustoms.length; i++) { diff --git a/packages/vite/src/client/client.ts b/packages/vite/src/client/client.ts index 1dbef0e3cce364..e2cb1a379b35d7 100644 --- a/packages/vite/src/client/client.ts +++ b/packages/vite/src/client/client.ts @@ -82,7 +82,7 @@ async function handleMessage(payload: HMRPayload) { queueUpdate(fetchUpdate(update)) } else { // css-update - // this is only sent when a css file referened with is updated + // this is only sent when a css file referenced with is updated let { path, timestamp } = update path = path.replace(/\?.*/, '') const el = document.querySelector(`link[href*='${path}']`) @@ -261,7 +261,7 @@ export function removeStyle(id: string) { async function fetchUpdate({ path, acceptedPath, timestamp }: Update) { const mod = hotModulesMap.get(path) if (!mod) { - // In a code-spliting project, + // In a code-splitting project, // it is common that the hot-updating module is not loaded yet. // https://github.com/vitejs/vite/issues/721 return diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts index d08d42a714d769..195d031605b65a 100644 --- a/packages/vite/src/node/optimizer/index.ts +++ b/packages/vite/src/node/optimizer/index.ts @@ -42,7 +42,7 @@ export interface DepOptimizationOptions { */ link?: string[] /** - * A list of depdendencies that imports Node built-ins, but do not actually + * A list of dependencies that imports Node built-ins, but do not actually * use them in browsers. */ allowNodeBuiltins?: string[] diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts index 65a54a77004593..5192137f4e32a2 100644 --- a/packages/vite/src/node/plugins/asset.ts +++ b/packages/vite/src/node/plugins/asset.ts @@ -114,7 +114,7 @@ function fileToDevUrl(id: string, { root }: ResolvedConfig) { return '/' + path.posix.relative(root, id) } // outside of project root, use absolute fs path - // (this is speical handled by the serve static middleware + // (this is special handled by the serve static middleware return FS_PREFIX + id } diff --git a/packages/vite/src/node/plugins/dynamicImportPolyfill.ts b/packages/vite/src/node/plugins/dynamicImportPolyfill.ts index 445e441b1edad6..e02563610d6451 100644 --- a/packages/vite/src/node/plugins/dynamicImportPolyfill.ts +++ b/packages/vite/src/node/plugins/dynamicImportPolyfill.ts @@ -3,7 +3,7 @@ import { ResolvedConfig } from '..' import { Plugin } from '../plugin' export const polyfillId = 'vite/dynamic-import-polyfill' -const polyfillPlaceholder = `__DYANMIC_IMPORT_POLYFILL__()` +const polyfillPlaceholder = `__DYNAMIC_IMPORT_POLYFILL__()` export function dynamicImportPolyfillPlugin(config: ResolvedConfig): Plugin { const skip = config.command === 'serve' || config.build.ssr diff --git a/packages/vite/src/node/plugins/importAnalysis.ts b/packages/vite/src/node/plugins/importAnalysis.ts index 26a7e985cc377b..b2233c0e40b5f8 100644 --- a/packages/vite/src/node/plugins/importAnalysis.ts +++ b/packages/vite/src/node/plugins/importAnalysis.ts @@ -71,7 +71,7 @@ function markExplicitImport(url: string) { * ``` * * - CSS imports are appended with `.js` since both the js module and the actual - * css (referenced via ) may go through the trasnform pipeline: + * css (referenced via ) may go through the transform pipeline: * * ```js * import './style.css' @@ -464,7 +464,7 @@ type ImportNameSpecifier = { importedName: string; localName: string } * Detect import statements to a known optimized CJS dependency and provide * ES named imports interop. We do this by rewriting named imports to a variable * assignment to the corresponding property on the `module.exports` of the cjs - * module. Note this doesn't support dynamic re-assisgnments from within the cjs + * module. Note this doesn't support dynamic re-assignments from within the cjs * module. * * Note that es-module-lexer treats `export * from '...'` as an import as well, diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index 6bbebfd9c658f1..a092b0600446ec 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -104,9 +104,9 @@ export function resolvePlugin({ // handle browser field mapping for relative imports const pkg = importer && idToPkgMap.get(importer) if (pkg && isObject(pkg.data.browser)) { - const pkgRealtivePath = './' + slash(path.relative(pkg.dir, fsPath)) + const pkgRelativePath = './' + slash(path.relative(pkg.dir, fsPath)) const browserMappedPath = mapWithBrowserField( - pkgRealtivePath, + pkgRelativePath, pkg.data.browser ) if (browserMappedPath) { diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index 183d740f6434e1..415a7c327ccb85 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -156,12 +156,12 @@ export interface ViteDevServer { */ moduleGraph: ModuleGraph /** - * Programatically resolve, load and transform a URL and get the result + * Programmatically resolve, load and transform a URL and get the result * without going through the http request pipeline. */ transformRequest(url: string): Promise /** - * Util for transfoming a file with esbuild. + * Util for transforming a file with esbuild. * Can be useful for certain plugins. */ transformWithEsbuild( @@ -179,7 +179,7 @@ export interface ViteDevServer { */ close(): Promise /** - * @intenral + * @internal */ optimizeDepsMetadata: DepOptimizationMetadata | null } diff --git a/packages/vite/src/node/server/middlewares/proxy.ts b/packages/vite/src/node/server/middlewares/proxy.ts index 17d4b89c77a33c..325e95e4eafa0f 100644 --- a/packages/vite/src/node/server/middlewares/proxy.ts +++ b/packages/vite/src/node/server/middlewares/proxy.ts @@ -45,7 +45,7 @@ export function proxyMiddleware({ if (opts.configure) { opts.configure(proxy, opts) } - // clone before saving becaues http-proxy mutates the options + // clone before saving because http-proxy mutates the options proxies[context] = [proxy, { ...opts }] }) diff --git a/packages/vite/src/node/server/moduleGraph.ts b/packages/vite/src/node/server/moduleGraph.ts index c42136b7c68a19..3f5cdd92293fda 100644 --- a/packages/vite/src/node/server/moduleGraph.ts +++ b/packages/vite/src/node/server/moduleGraph.ts @@ -122,12 +122,12 @@ export class ModuleGraph { mod.id = resolvedId this.idToModuleMap.set(resolvedId, mod) const file = (mod.file = cleanUrl(resolvedId)) - let fileMappedMdoules = this.fileToModulesMap.get(file) - if (!fileMappedMdoules) { - fileMappedMdoules = new Set() - this.fileToModulesMap.set(file, fileMappedMdoules) + let fileMappedModules = this.fileToModulesMap.get(file) + if (!fileMappedModules) { + fileMappedModules = new Set() + this.fileToModulesMap.set(file, fileMappedModules) } - fileMappedMdoules.add(mod) + fileMappedModules.add(mod) } return mod } @@ -139,19 +139,19 @@ export class ModuleGraph { createFileOnlyEntry(file: string) { file = normalizePath(file) const url = `/@fs/${file}` - let fileMappedMdoules = this.fileToModulesMap.get(file) - if (!fileMappedMdoules) { - fileMappedMdoules = new Set() - this.fileToModulesMap.set(file, fileMappedMdoules) + let fileMappedModules = this.fileToModulesMap.get(file) + if (!fileMappedModules) { + fileMappedModules = new Set() + this.fileToModulesMap.set(file, fileMappedModules) } - for (const m of fileMappedMdoules) { + for (const m of fileMappedModules) { if (m.url === url) { return m } } const mod = new ModuleNode(url) mod.file = file - fileMappedMdoules.add(mod) + fileMappedModules.add(mod) return mod } From 5d180db4bd19e26de20bb816d594226b4d492804 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 9 Jan 2021 22:26:27 -0500 Subject: [PATCH 010/106] fix(optimizer): properly externalize css/asset imports in optimized deps fix #1443 --- .../optimize-deps-linked-include/index.js | 3 +++ .../optimize-deps-linked-include/test.css | 3 +++ .../__tests__/optimize-deps.spec.ts | 6 ++++++ packages/playground/optimize-deps/index.html | 16 +++++++-------- .../vite/src/node/optimizer/depAssetPlugin.ts | 20 ++++++++++++------- packages/vite/src/node/optimizer/index.ts | 4 ++-- packages/vite/src/node/plugins/resolve.ts | 2 +- 7 files changed, 36 insertions(+), 18 deletions(-) create mode 100644 packages/playground/optimize-deps-linked-include/test.css diff --git a/packages/playground/optimize-deps-linked-include/index.js b/packages/playground/optimize-deps-linked-include/index.js index 74c1e295715f63..508a908abefa6a 100644 --- a/packages/playground/optimize-deps-linked-include/index.js +++ b/packages/playground/optimize-deps-linked-include/index.js @@ -5,3 +5,6 @@ import { useState } from 'react' export function useCount() { return useState(0) } + +// test dep with css/asset imports +import './test.css' diff --git a/packages/playground/optimize-deps-linked-include/test.css b/packages/playground/optimize-deps-linked-include/test.css new file mode 100644 index 00000000000000..b719c608467fdd --- /dev/null +++ b/packages/playground/optimize-deps-linked-include/test.css @@ -0,0 +1,3 @@ +body { + color: red; +} \ No newline at end of file diff --git a/packages/playground/optimize-deps/__tests__/optimize-deps.spec.ts b/packages/playground/optimize-deps/__tests__/optimize-deps.spec.ts index f7616fb9d6be71..9623590c007b7b 100644 --- a/packages/playground/optimize-deps/__tests__/optimize-deps.spec.ts +++ b/packages/playground/optimize-deps/__tests__/optimize-deps.spec.ts @@ -1,3 +1,5 @@ +import { getColor } from '../../testUtils' + test('default + named imports from cjs dep (react)', async () => { expect(await page.textContent('.cjs button')).toBe('count is 0') await page.click('.cjs button') @@ -27,3 +29,7 @@ test('dep from linked dep (lodash-es)', async () => { test('forced include', async () => { expect(await page.textContent('.force-include')).toMatch(`[success]`) }) + +test('dep with css import', async () => { + expect(await getColor('h1')).toBe('red') +}) diff --git a/packages/playground/optimize-deps/index.html b/packages/playground/optimize-deps/index.html index d79167fa82bf80..7e881b1daeabab 100644 --- a/packages/playground/optimize-deps/index.html +++ b/packages/playground/optimize-deps/index.html @@ -22,15 +22,15 @@

Optimizing force included dep even when it's linked

diff --git a/packages/vite/src/node/optimizer/depAssetPlugin.ts b/packages/vite/src/node/optimizer/depAssetPlugin.ts index 3922a204387f6d..e3b21d42c71b83 100644 --- a/packages/vite/src/node/optimizer/depAssetPlugin.ts +++ b/packages/vite/src/node/optimizer/depAssetPlugin.ts @@ -3,8 +3,9 @@ import { Plugin } from 'rollup' import { init, parse } from 'es-module-lexer' import { isCSSRequest } from '../plugins/css' import MagicString from 'magic-string' -import { bareImportRE, normalizePath, resolveFrom } from '../utils' +import { normalizePath } from '../utils' import { ResolvedConfig } from '../config' +import { idToPkgMap } from '../plugins/resolve' export const depAssetExternalPlugin = (config: ResolvedConfig): Plugin => ({ name: 'vite:dep-assets-external', @@ -47,12 +48,17 @@ export const depAssetRewritePlugin = (config: ResolvedConfig): Plugin => { s.remove(statementStart, statementEnd) continue } - const deepPath = `/@fs/${normalizePath( - bareImportRE.test(importee) - ? resolveFrom(config.root, importee) - : path.resolve(path.dirname(id), importee) - )}` - s.overwrite(start, end, deepPath) + if (importee.startsWith('.')) { + const pkg = idToPkgMap.get(id) + if (pkg) { + const fsPath = path.resolve(path.dirname(id), importee) + const deepPath = + pkg.data.name + + '/' + + normalizePath(path.relative(pkg.dir, fsPath)) + s.overwrite(start, end, deepPath) + } + } } } else { // ignore dynamic import diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts index 195d031605b65a..380f88bfda4310 100644 --- a/packages/vite/src/node/optimizer/index.ts +++ b/packages/vite/src/node/optimizer/index.ts @@ -326,12 +326,12 @@ async function resolveQualifiedDeps( if (i.startsWith('.')) { debug(`optimizing ${id} (contains relative imports)`) qualified[id] = filePath - continue + break } if (!deps.includes(i)) { debug(`optimizing ${id} (imports sub dependencies)`) qualified[id] = filePath - continue + break } } debug(`skipping ${id} (single esm file, doesn't need optimization)`) diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index a092b0600446ec..c9c8956bc05a67 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -221,7 +221,7 @@ function tryResolveFile( } } -const idToPkgMap = new Map() +export const idToPkgMap = new Map() export function tryNodeResolve( id: string, From 8b8d5061ea44affd3b9bed97da2e629254a6ec28 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 9 Jan 2021 22:53:51 -0500 Subject: [PATCH 011/106] refactor(optimizer): adjust node built-in handling - prefer resolved if resolvable - externalize to empty module when not resolved - better plugin warning handling --- docs/config/index.md | 14 +--- .../optimize-deps-linked-include/index.js | 9 +++ packages/vite/src/node/build.ts | 79 ++++++------------- packages/vite/src/node/optimizer/index.ts | 35 +++----- packages/vite/src/node/plugins/resolve.ts | 25 ++++-- 5 files changed, 59 insertions(+), 103 deletions(-) diff --git a/docs/config/index.md b/docs/config/index.md index 336e83984b31e8..6507755e824364 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -415,22 +415,10 @@ export default ({ command, mode }) => { ### optimizeDeps.exclude -- **Type:** `string[]` +- **Type:** `string | RegExp | (string | RegExp)[]` Dependencies to force exclude in pre-bundling. -### optimizeDeps.link - -- **Type:** `string[]` - - Dependencies to be explicitly treated as linked source in pre-bundling. Note Vite 2.0 automatically detects linked packages (deps whose resolved path is not inside `node_modules`) so this should only be needed in rare cases. - -### optimizeDeps.allowNodeBuiltins - -- **Type:** `string[]` - - A list of dependencies that imports Node built-ins, but do not actually use them in browsers. Suppresses related warnings. - ### optimizeDeps.auto - **Type:** `boolean` diff --git a/packages/playground/optimize-deps-linked-include/index.js b/packages/playground/optimize-deps-linked-include/index.js index 508a908abefa6a..a869157f53ed1b 100644 --- a/packages/playground/optimize-deps-linked-include/index.js +++ b/packages/playground/optimize-deps-linked-include/index.js @@ -8,3 +8,12 @@ export function useCount() { // test dep with css/asset imports import './test.css' + +// test importing node built-ins +import fs from 'fs' + +if (false) { + fs.readFileSync() +} else { + console.log('ok') +} diff --git a/packages/vite/src/node/build.ts b/packages/vite/src/node/build.ts index 0c953b276f7c58..d8ef6812574f4f 100644 --- a/packages/vite/src/node/build.ts +++ b/packages/vite/src/node/build.ts @@ -8,7 +8,6 @@ import Rollup, { RollupOptions, RollupWarning, WarningHandler, - WarningHandlerWithDefault, OutputOptions, RollupOutput } from 'rollup' @@ -22,7 +21,6 @@ import { copyDir, emptyDir, lookupFile } from './utils' import { manifestPlugin } from './plugins/manifest' import commonjsPlugin from '@rollup/plugin-commonjs' import dynamicImportVars from '@rollup/plugin-dynamic-import-vars' -import isBuiltin from 'isbuiltin' import { Logger } from './logger' import { TransformOptions } from 'esbuild' import { CleanCSS } from 'types/clean-css' @@ -280,12 +278,7 @@ async function doBuild( ...options.rollupOptions, plugins: config.plugins as Plugin[], onwarn(warning, warn) { - onRollupWarning( - warning, - warn, - config.optimizeDeps?.allowNodeBuiltins, - options.rollupOptions?.onwarn - ) + onRollupWarning(warning, warn, config) } }) @@ -397,59 +390,20 @@ const dynamicImportWarningIgnoreList = [ export function onRollupWarning( warning: RollupWarning, warn: WarningHandler, - allowNodeBuiltins: string[] = [], - userOnWarn?: WarningHandlerWithDefault + config: ResolvedConfig ) { - function doWarn() { - if (userOnWarn) { - userOnWarn(warning, warn) - } else { - warn(warning) - } - } - if (warning.code === 'UNRESOLVED_IMPORT') { - let message: string const id = warning.source const importer = warning.importer - - if (importer && /\?commonjs-external$/.test(importer)) { - // allow commonjs external... - warning.message = chalk.yellow(warning.message) - return doWarn() - } - - if (id && isBuiltin(id)) { - let importingDep: string | undefined - if (importer) { - const pkg = JSON.parse(lookupFile(importer, ['package.json']) || `{}`) - if (pkg.name) { - importingDep = pkg.name - } - } - if ( - importingDep && - allowNodeBuiltins.some((allowed) => importingDep!.startsWith(allowed)) - ) { - return - } - const dep = importingDep - ? `Dependency ${chalk.yellow(importingDep)}` - : `A dependency` - message = - `${dep} is attempting to import Node built-in module ${chalk.yellow( - id - )}.\n` + - `This will not work in a browser environment.\n` + - `Imported by: ${chalk.gray(importer)}` - } else { - message = - `[vite]: Rollup failed to resolve import "${warning.source}" from "${warning.importer}".\n` + - `This is most likely unintended because it can break your application at runtime.\n` + - `If you do want to externalize this module explicitly add it to\n` + - `\`build.rollupOptions.external\`` + // throw unless it's commonjs external... + if (!importer || !/\?commonjs-external$/.test(importer)) { + throw new Error( + `[vite]: Rollup failed to resolve import "${id}" from "${importer}".\n` + + `This is most likely unintended because it can break your application at runtime.\n` + + `If you do want to externalize this module explicitly add it to\n` + + `\`build.rollupOptions.external\`` + ) } - throw new Error(message) } if ( @@ -460,6 +414,17 @@ export function onRollupWarning( } if (!warningIgnoreList.includes(warning.code!)) { - doWarn() + const userOnWarn = config.build.rollupOptions?.onwarn + if (userOnWarn) { + userOnWarn(warning, warn) + } else if (warning.code === 'PLUGIN_WARNING') { + config.logger.warn( + `${chalk.bold.yellow(`[plugin:${warning.plugin}]`)} ${chalk.yellow( + warning.message + )}` + ) + } else { + warn(warning) + } } } diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts index 380f88bfda4310..befeb4cca8751e 100644 --- a/packages/vite/src/node/optimizer/index.ts +++ b/packages/vite/src/node/optimizer/index.ts @@ -25,6 +25,7 @@ import aliasPlugin from '@rollup/plugin-alias' import commonjsPlugin from '@rollup/plugin-commonjs' import jsonPlugin from '@rollup/plugin-json' import { buildDefinePlugin } from '../plugins/define' +import { createFilter } from '@rollup/pluginutils' const debug = createDebugger('vite:optimize') @@ -36,21 +37,17 @@ export interface DepOptimizationOptions { /** * Do not optimize these dependencies. */ - exclude?: string[] - /** - * A list of linked dependencies that should be treated as source code. - */ - link?: string[] - /** - * A list of dependencies that imports Node built-ins, but do not actually - * use them in browsers. - */ - allowNodeBuiltins?: string[] + exclude?: string | RegExp | (string | RegExp)[] /** * Automatically run `vite optimize` on server start? * @default true */ auto?: boolean + /** + * A list of linked dependencies that should be treated as source code. + * @deprecated + */ + link?: string[] } export interface DepOptimizationMetadata { @@ -174,7 +171,7 @@ export async function optimizeDeps( input: qualified, external, onwarn(warning, warn) { - onRollupWarning(warning, warn, options.allowNodeBuiltins) + onRollupWarning(warning, warn, config) }, plugins: [ aliasPlugin({ entries: config.alias }), @@ -219,19 +216,6 @@ export async function optimizeDeps( e.message += `\n\n${chalk.cyan( path.relative(root, e.loc.file) )}\n${chalk.dim(e.frame)}` - } else if (e.message.match('Node built-in')) { - e.message += chalk.yellow( - `\n\nTip:\nMake sure your "dependencies" only include packages that you\n` + - `intend to use in the browser. If it's a Node.js package, it\n` + - `should be in "devDependencies".\n\n` + - `If you do intend to use this dependency in the browser and the\n` + - `dependency does not actually use these Node built-ins in the\n` + - `browser, you can add the dependency (not the built-in) to the\n` + - `"optimizeDeps.allowNodeBuiltins" option in vite.config.js.\n\n` + - `If that results in a runtime error, then unfortunately the\n` + - `package is not distributed in a web-friendly format. You should\n` + - `open an issue in its repo, or look for a modern alternative.` - ) } throw e } @@ -271,13 +255,14 @@ async function resolveQualifiedDeps( const pkg = JSON.parse(pkgContent) const deps = Object.keys(pkg.dependencies || {}) const linked: string[] = [] + const excludeFilter = exclude && createFilter(exclude) for (const id of deps) { if (include && include.includes(id)) { // already force included continue } - if (exclude && exclude.includes(id)) { + if (excludeFilter && excludeFilter(id)) { debug(`skipping ${id} (excluded)`) continue } diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index c9c8956bc05a67..0906beb9a806e5 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -146,14 +146,6 @@ export function resolvePlugin({ // bare package imports, perform node resolve if (bareImportRE.test(id)) { - // externalize node built-ins only when building for ssr - if (isBuild && config && config.build.ssr && isBuiltin(id)) { - return { - id, - external: true - } - } - if (asSrc && server && (res = tryOptimizedResolve(id, server))) { return res } @@ -170,6 +162,23 @@ export function resolvePlugin({ ) { return res } + + // node built-ins. + // externalize if building for SSR, otherwise redirect to empty module + if (isBuiltin(id)) { + if (isBuild && config && config.build.ssr) { + return { + id, + external: true + } + } else { + this.warn( + `externalized node built-in "${id}" to empty module. ` + + `(imported by: ${chalk.white.dim(importer)})` + ) + return browserExternalId + } + } } isDebug && debug(`[fallthrough] ${chalk.dim(id)}`) From 60b9e10405c513c440c393925d74757d5c2fa15b Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 9 Jan 2021 23:19:34 -0500 Subject: [PATCH 012/106] refactor: fix js request check & deep import error on assets --- packages/vite/src/node/plugins/resolve.ts | 3 ++- packages/vite/src/node/utils.ts | 12 ++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index 0906beb9a806e5..800df619cdd37b 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -259,7 +259,8 @@ export function tryNodeResolve( server && server.optimizeDepsMetadata && pkg.data.name in server.optimizeDepsMetadata.map && - !isCSSRequest(id) + !isCSSRequest(id) && + !server.config.assetsInclude(id) ) { throw new Error( chalk.yellow( diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index 1518b5c8d38a88..44de579d6e64f5 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -77,8 +77,16 @@ const dataUrlRE = /^\s*data:/i export const isDataUrl = (url: string) => dataUrlRE.test(url) const knownJsSrcRE = /\.((j|t)sx?|mjs|vue)($|\?)/ -export const isJSRequest = (url: string) => - knownJsSrcRE.test(url) || (!path.extname(url) && !url.endsWith('/')) +export const isJSRequest = (url: string) => { + if (knownJsSrcRE.test(url)) { + return true + } + url = cleanUrl(url) + if (!path.extname(url) && !url.endsWith('/')) { + return true + } + return false +} const importQueryRE = /(\?|&)import(&|$)/ export const isImportRequest = (url: string) => importQueryRE.test(url) From 1ea016823975f3d0e37bf7b65614eded213e0869 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 9 Jan 2021 23:40:53 -0500 Subject: [PATCH 013/106] feat(optimizer): support specifying plugins for the optimizer --- docs/config/index.md | 8 ++++++++ .../optimize-deps-linked-include/Test.vue | 1 + .../optimize-deps-linked-include/index.js | 2 ++ .../optimize-deps/__tests__/optimize-deps.spec.ts | 4 ++++ packages/playground/optimize-deps/index.html | 6 +++++- packages/playground/optimize-deps/vite.config.js | 6 +++++- packages/vite/src/node/config.ts | 4 ++-- packages/vite/src/node/optimizer/index.ts | 14 ++++++++++++-- 8 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 packages/playground/optimize-deps-linked-include/Test.vue diff --git a/docs/config/index.md b/docs/config/index.md index 6507755e824364..1ace65ae99990c 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -419,6 +419,14 @@ export default ({ command, mode }) => { Dependencies to force exclude in pre-bundling. +### optimizeDeps.plugins + +- **Type:** `Plugin[]` + + By default, Vite assumes dependencies ship plain JavaScript and will not attempt to transform non-js file formats during pre-bundling. If you wish to support speical file types, e.g. `.vue` files, you will need to supply the relevant plugins via this option. + + Note that you will also need to include these plugins in the main `plugins` option in order to support the same file types during production build. + ### optimizeDeps.auto - **Type:** `boolean` diff --git a/packages/playground/optimize-deps-linked-include/Test.vue b/packages/playground/optimize-deps-linked-include/Test.vue new file mode 100644 index 00000000000000..ca11049b3e883b --- /dev/null +++ b/packages/playground/optimize-deps-linked-include/Test.vue @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/playground/optimize-deps-linked-include/index.js b/packages/playground/optimize-deps-linked-include/index.js index a869157f53ed1b..81c43abc0387ac 100644 --- a/packages/playground/optimize-deps-linked-include/index.js +++ b/packages/playground/optimize-deps-linked-include/index.js @@ -17,3 +17,5 @@ if (false) { } else { console.log('ok') } + +export { default as VueSFC } from './Test.vue' diff --git a/packages/playground/optimize-deps/__tests__/optimize-deps.spec.ts b/packages/playground/optimize-deps/__tests__/optimize-deps.spec.ts index 9623590c007b7b..9b65f11e8ffd4a 100644 --- a/packages/playground/optimize-deps/__tests__/optimize-deps.spec.ts +++ b/packages/playground/optimize-deps/__tests__/optimize-deps.spec.ts @@ -33,3 +33,7 @@ test('forced include', async () => { test('dep with css import', async () => { expect(await getColor('h1')).toBe('red') }) + +test('dep w/ non-js files handled via plugin', async () => { + expect(await page.textContent('.plugin')).toMatch(`[success]`) +}) diff --git a/packages/playground/optimize-deps/index.html b/packages/playground/optimize-deps/index.html index 7e881b1daeabab..19762f17a2b557 100644 --- a/packages/playground/optimize-deps/index.html +++ b/packages/playground/optimize-deps/index.html @@ -21,6 +21,9 @@

Detecting linked src package and optimizing its deps (lodash-es)

Optimizing force included dep even when it's linked

+

Dep w/ speical file format supported via plugins

+
+ diff --git a/packages/playground/optimize-deps/vite.config.js b/packages/playground/optimize-deps/vite.config.js index 267e0ff2be1995..5c3b4a2d48b5f4 100644 --- a/packages/playground/optimize-deps/vite.config.js +++ b/packages/playground/optimize-deps/vite.config.js @@ -1,3 +1,5 @@ +const vue = require('@vitejs/plugin-vue') + /** * @type {import('vite').UserConfig} */ @@ -5,7 +7,8 @@ module.exports = { dedupe: ['react'], optimizeDeps: { - include: ['optimize-deps-linked-include'] + include: ['optimize-deps-linked-include'], + plugins: [vue()] }, build: { @@ -14,6 +17,7 @@ module.exports = { }, plugins: [ + vue(), // for axios request test { name: 'mock', diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts index 9c751f2df54b87..4e27d7009554ff 100644 --- a/packages/vite/src/node/config.ts +++ b/packages/vite/src/node/config.ts @@ -161,7 +161,7 @@ export async function resolveConfig( const rawUserPlugins = (config.plugins || []).flat().filter((p) => { return !p.apply || p.apply === command }) - const [prePlugins, postPlugins, normalPlugins] = sortUserPlugins( + const [prePlugins, normalPlugins, postPlugins] = sortUserPlugins( rawUserPlugins ) @@ -345,7 +345,7 @@ export function sortUserPlugins( }) } - return [prePlugins, postPlugins, normalPlugins] + return [prePlugins, normalPlugins, postPlugins] } export async function loadConfigFromFile( diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts index befeb4cca8751e..71076118825585 100644 --- a/packages/vite/src/node/optimizer/index.ts +++ b/packages/vite/src/node/optimizer/index.ts @@ -3,7 +3,7 @@ import path from 'path' import chalk from 'chalk' import Rollup from 'rollup' import { createHash } from 'crypto' -import { ResolvedConfig } from '../config' +import { ResolvedConfig, sortUserPlugins } from '../config' import { SUPPORTED_EXTS } from '../constants' import { init, parse } from 'es-module-lexer' import { onRollupWarning } from '../build' @@ -26,6 +26,7 @@ import commonjsPlugin from '@rollup/plugin-commonjs' import jsonPlugin from '@rollup/plugin-json' import { buildDefinePlugin } from '../plugins/define' import { createFilter } from '@rollup/pluginutils' +import { Plugin } from '../plugin' const debug = createDebugger('vite:optimize') @@ -38,6 +39,10 @@ export interface DepOptimizationOptions { * Do not optimize these dependencies. */ exclude?: string | RegExp | (string | RegExp)[] + /** + * Plugins to use for dep optimizations. + */ + plugins?: Plugin[] /** * Automatically run `vite optimize` on server start? * @default true @@ -164,6 +169,8 @@ export async function optimizeDeps( logger.info(chalk.greenBright(`Optimizing dependencies:\n${depsString}`)) } + const [pre, normal, post] = sortUserPlugins(options.plugins) + try { const rollup = require('rollup') as typeof Rollup @@ -175,6 +182,7 @@ export async function optimizeDeps( }, plugins: [ aliasPlugin({ entries: config.alias }), + ...pre, depAssetExternalPlugin(config), resolvePlugin({ root: config.root, @@ -186,13 +194,15 @@ export async function optimizeDeps( preferConst: true, namedExports: true }), + ...normal, commonjsPlugin({ include: [/node_modules/], extensions: ['.js', '.cjs'] }), buildDefinePlugin(config), depAssetRewritePlugin(config), - recordCjsEntryPlugin(data) + recordCjsEntryPlugin(data), + ...post ] }) From bbfe06ce1af8f89490032e609377c6516f7da773 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 9 Jan 2021 23:54:30 -0500 Subject: [PATCH 014/106] fix: fix dynamic import with parent relative paths fix #1461 --- packages/playground/dynamic-import/index.html | 21 +------------------ .../playground/dynamic-import/nested/index.js | 18 ++++++++++++++++ packages/vite/src/client/client.ts | 4 +++- 3 files changed, 22 insertions(+), 21 deletions(-) create mode 100644 packages/playground/dynamic-import/nested/index.js diff --git a/packages/playground/dynamic-import/index.html b/packages/playground/dynamic-import/index.html index 6bf5eee0d017a6..a71c770741d80d 100644 --- a/packages/playground/dynamic-import/index.html +++ b/packages/playground/dynamic-import/index.html @@ -4,23 +4,4 @@
- + diff --git a/packages/playground/dynamic-import/nested/index.js b/packages/playground/dynamic-import/nested/index.js new file mode 100644 index 00000000000000..9c22d25a17682b --- /dev/null +++ b/packages/playground/dynamic-import/nested/index.js @@ -0,0 +1,18 @@ +async function setView(view) { + const { msg } = await import(`../views/${view}.js`) + text('.view', msg) +} + +;['foo', 'bar'].forEach((id) => { + document.querySelector(`.${id}`).addEventListener('click', () => setView(id)) +}) + +document.querySelector('.baz').addEventListener('click', async () => { + // literal dynamic + const { msg } = await import('../views/baz.js') + text('.view', msg) +}) + +function text(el, text) { + document.querySelector(el).textContent = text +} diff --git a/packages/vite/src/client/client.ts b/packages/vite/src/client/client.ts index e2cb1a379b35d7..949145a2103d0b 100644 --- a/packages/vite/src/client/client.ts +++ b/packages/vite/src/client/client.ts @@ -438,7 +438,9 @@ export const createHotContext = (ownerPath: string) => { } export function injectQuery(url: string, queryToInject: string) { - const { pathname, search, hash } = new URL(url, 'http://vitejs.dev') + // can't use pathname from URL since it may be relative like ../ + const pathname = url.replace(/#.*$/, '').replace(/\?.*$/, '') + const { search, hash } = new URL(url, 'http://vitejs.dev') return `${pathname}?${queryToInject}${search ? `&` + search.slice(1) : ''}${ hash || '' }` From 8497f52953646d610db6579b0e77807011a2dba1 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 9 Jan 2021 23:55:56 -0500 Subject: [PATCH 015/106] chore: deprecation message --- packages/vite/src/node/optimizer/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts index 71076118825585..40d3f4e76e5ce6 100644 --- a/packages/vite/src/node/optimizer/index.ts +++ b/packages/vite/src/node/optimizer/index.ts @@ -50,7 +50,7 @@ export interface DepOptimizationOptions { auto?: boolean /** * A list of linked dependencies that should be treated as source code. - * @deprecated + * @deprecated local linked deps are auto detected in Vite 2. */ link?: string[] } From cf8342bef45bebb05d020d4f220b12d2bf526256 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Han=EF=BC=88=E3=83=8F=E3=83=B3=EF=BC=89?= Date: Sun, 10 Jan 2021 14:02:52 +0900 Subject: [PATCH 016/106] fix: transform json in deep import (#1459) fix #1458 --- .../playground/json/__tests__/json.spec.ts | 10 +++ packages/playground/json/index.html | 9 +++ packages/vite/src/node/plugins/index.ts | 2 +- packages/vite/src/node/plugins/json.ts | 81 +++++++++++++++++++ 4 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 packages/vite/src/node/plugins/json.ts diff --git a/packages/playground/json/__tests__/json.spec.ts b/packages/playground/json/__tests__/json.spec.ts index cd15c1d50dc4de..2a9451d1c41ca7 100644 --- a/packages/playground/json/__tests__/json.spec.ts +++ b/packages/playground/json/__tests__/json.spec.ts @@ -1,5 +1,7 @@ const json = require('../test.json') +const deepJson = require('@vue/runtime-core/package.json') const stringified = JSON.stringify(json) +const deepStringified = JSON.stringify(deepJson) test('default import', async () => { expect(await page.textContent('.full')).toBe(stringified) @@ -9,6 +11,14 @@ test('named import', async () => { expect(await page.textContent('.named')).toBe(json.hello) }) +test('deep import', async () => { + expect(await page.textContent('.deep-full')).toBe(deepStringified) +}) + +test('named deep import', async () => { + expect(await page.textContent('.deep-named')).toBe(deepJson.name) +}) + test('dynamic import', async () => { expect(await page.textContent('.dynamic')).toBe(stringified) }) diff --git a/packages/playground/json/index.html b/packages/playground/json/index.html index 3c5eaca233d268..0efaea3147a164 100644 --- a/packages/playground/json/index.html +++ b/packages/playground/json/index.html @@ -2,6 +2,10 @@

Normal Import


 

 
+

Deep Import

+

+

+
 

Dynamic Import


 

@@ -11,9 +15,14 @@ 

Raw fetch

diff --git a/docs/public/tailwind-labs.svg b/docs/public/tailwind-labs.svg new file mode 100644 index 00000000000000..300411468cbb5f --- /dev/null +++ b/docs/public/tailwind-labs.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/package.json b/package.json index 352757e0938452..398171d808acd4 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "slash": "^3.0.0", "ts-jest": "^26.4.4", "typescript": "^4.1.2", - "vitepress": "^0.10.7", + "vitepress": "^0.11.0", "yorkie": "^2.0.0" }, "gitHooks": { diff --git a/yarn.lock b/yarn.lock index 47da774e0fccc1..e6bded2c796f2e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7592,10 +7592,10 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" -vitepress@^0.10.7: - version "0.10.7" - resolved "https://registry.yarnpkg.com/vitepress/-/vitepress-0.10.7.tgz#53ce1f735cf765fc50ed07cb0a7d5ae4fb92ef29" - integrity sha512-6ZnH3WIYL58E5ddKCDzihI2UKUOD24e15jfi2YEbiMI3Eb6cZwfFehiZUoSVFQ38sJ6/Vh9p8SzH92w+OlXXFQ== +vitepress@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/vitepress/-/vitepress-0.11.0.tgz#7f7634c8bbb33be265d026a7ac7356d82fec2a45" + integrity sha512-8nwN1EmEk0k+syg6Njt+4dhCuYp2mYat5X3WuweStS2G9BQDNN8e4jTRbgscyNEmoG0vWvdxZ+mnJr0lA7mnGA== dependencies: "@docsearch/css" "^1.0.0-alpha.28" "@docsearch/js" "^1.0.0-alpha.28" @@ -7622,7 +7622,7 @@ vitepress@^0.10.7: prismjs "^1.20.0" sirv "^1.0.10" slash "^3.0.0" - vite "^2.0.0-beta.8" + vite "^2.0.0-beta.21" vue "^3.0.5" void-elements@^3.1.0: From 43682b41ca1dffb9f81403ab9ee8054882930e44 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 12 Jan 2021 00:22:41 -0500 Subject: [PATCH 053/106] chore: bump vitepress --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 398171d808acd4..14cf29e9f6d717 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "slash": "^3.0.0", "ts-jest": "^26.4.4", "typescript": "^4.1.2", - "vitepress": "^0.11.0", + "vitepress": "^0.11.1", "yorkie": "^2.0.0" }, "gitHooks": { diff --git a/yarn.lock b/yarn.lock index e6bded2c796f2e..b191321db6304e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7592,10 +7592,10 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" -vitepress@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/vitepress/-/vitepress-0.11.0.tgz#7f7634c8bbb33be265d026a7ac7356d82fec2a45" - integrity sha512-8nwN1EmEk0k+syg6Njt+4dhCuYp2mYat5X3WuweStS2G9BQDNN8e4jTRbgscyNEmoG0vWvdxZ+mnJr0lA7mnGA== +vitepress@^0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/vitepress/-/vitepress-0.11.1.tgz#1eee2dac8d3aad8d488558ddbc2367e33b2a2a3f" + integrity sha512-ThjTFNQjlVcVz0UNv1zV6fs1cYs8h/xNWmzrbF08gqKtE6vTSRVEb9SVlIXq1LVt13/0+t5XyddEURi5wo1Big== dependencies: "@docsearch/css" "^1.0.0-alpha.28" "@docsearch/js" "^1.0.0-alpha.28" From b5e591dffb8105b86af272908665b7c64e783398 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 12 Jan 2021 00:26:28 -0500 Subject: [PATCH 054/106] docs: sponsor css fix --- docs/.vitepress/theme/sponsors.css | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/.vitepress/theme/sponsors.css b/docs/.vitepress/theme/sponsors.css index 1aa3b5a82b1fa2..2f30c1a888c540 100644 --- a/docs/.vitepress/theme/sponsors.css +++ b/docs/.vitepress/theme/sponsors.css @@ -9,7 +9,7 @@ .sponsors img { width: 200px; - display: inline-block; + display: block; margin: 1.25rem 0; } @@ -17,6 +17,10 @@ text-align: center; } +.sponsors.frontpage img { + display: inline-block; +} + .sponsors.frontpage h2 { color: #999; font-size: 1.2rem; From ae2e14baf1771c2ccdeece8bbc2b9bd11b279490 Mon Sep 17 00:00:00 2001 From: Alex Kozack Date: Tue, 12 Jan 2021 10:51:28 +0200 Subject: [PATCH 055/106] fix: show target build mode in logs (#1498) --- packages/vite/src/node/build.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/build.ts b/packages/vite/src/node/build.ts index 6417c4eb0dc0bb..f9e04991558b44 100644 --- a/packages/vite/src/node/build.ts +++ b/packages/vite/src/node/build.ts @@ -264,7 +264,7 @@ async function doBuild( inlineConfig: InlineConfig = {} ): Promise { const config = await resolveConfig(inlineConfig, 'build', 'production') - config.logger.info(chalk.cyan(`building for production...`)) + config.logger.info(chalk.cyan(`building for ${config.mode}...`)) const options = config.build const libOptions = options.lib From 6bdc3eb2d004a28d2934946e33602f832b1ad8f2 Mon Sep 17 00:00:00 2001 From: JokcyLou Date: Tue, 12 Jan 2021 19:39:29 +0800 Subject: [PATCH 056/106] fix(plugin-vue-jsx): fix vue jsx hmr (#1495) --- .../vue-jsx/__tests__/vue-jsx.spec.ts | 12 ++++---- packages/plugin-vue-jsx/index.js | 29 ++++++------------- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/packages/playground/vue-jsx/__tests__/vue-jsx.spec.ts b/packages/playground/vue-jsx/__tests__/vue-jsx.spec.ts index 3a54cfdbf011e4..104d3bd52642b9 100644 --- a/packages/playground/vue-jsx/__tests__/vue-jsx.spec.ts +++ b/packages/playground/vue-jsx/__tests__/vue-jsx.spec.ts @@ -1,4 +1,4 @@ -import { editFile, isBuild, untilUpdated } from '../../testUtils' +import { editFile, isBuild, untilUpdated } from 'testUtils' test('should render', async () => { expect(await page.textContent('.named')).toMatch('0') @@ -25,9 +25,10 @@ if (!isBuild) { ) await untilUpdated(() => page.textContent('.named'), 'named updated 0') - // should not affect other components on the page - expect(await page.textContent('.named-specifier')).toMatch('2') - expect(await page.textContent('.default')).toMatch('3') + // affect all components in same file + expect(await page.textContent('.named-specifier')).toMatch('1') + expect(await page.textContent('.default')).toMatch('2') + // should not affect other components from different file expect(await page.textContent('.default-tsx')).toMatch('4') }) @@ -40,8 +41,9 @@ if (!isBuild) { 'named specifier updated 1' ) + // affect all components in same file + expect(await page.textContent('.default')).toMatch('2') // should not affect other components on the page - expect(await page.textContent('.default')).toMatch('3') expect(await page.textContent('.default-tsx')).toMatch('4') }) diff --git a/packages/plugin-vue-jsx/index.js b/packages/plugin-vue-jsx/index.js index 6e9546be103646..86d27be65008b2 100644 --- a/packages/plugin-vue-jsx/index.js +++ b/packages/plugin-vue-jsx/index.js @@ -62,7 +62,7 @@ function vueJsxPlugin(options = {}) { // check for hmr injection /** - * @type {{ name: string, hash: string }[]} + * @type {{ name: string }[]} */ const declaredComponents = [] /** @@ -70,7 +70,6 @@ function vueJsxPlugin(options = {}) { * local: string, * exported: string, * id: string, - * hash: string * }[]} */ const hotComponents = [] @@ -91,11 +90,10 @@ function vueJsxPlugin(options = {}) { ) { hotComponents.push( ...parseComponentDecls(node.declaration, code).map( - ({ name, hash: _hash }) => ({ + ({ name }) => ({ local: name, exported: name, - id: hash(id + name), - hash: _hash + id: hash(id + name) }) ) ) @@ -112,8 +110,7 @@ function vueJsxPlugin(options = {}) { hotComponents.push({ local: spec.local.name, exported: spec.exported.name, - id: hash(id + spec.exported.name), - hash: matched.hash + id: hash(id + spec.exported.name) }) } } @@ -131,8 +128,7 @@ function vueJsxPlugin(options = {}) { hotComponents.push({ local: node.declaration.name, exported: 'default', - id: hash(id + 'default'), - hash: matched.hash + id: hash(id + 'default') }) } } else if (isDefineComponentCall(node.declaration)) { @@ -140,10 +136,7 @@ function vueJsxPlugin(options = {}) { hotComponents.push({ local: '__default__', exported: 'default', - id: hash(id + 'default'), - hash: hash( - code.slice(node.declaration.start, node.declaration.end) - ) + id: hash(id + 'default') }) } } @@ -160,14 +153,11 @@ function vueJsxPlugin(options = {}) { } let callbackCode = `` - for (const { local, exported, id, hash } of hotComponents) { + for (const { local, exported, id } of hotComponents) { code += `\n${local}.__hmrId = "${id}"` + - `\n${local}.__hmrHash = "${hash}"` + `\n__VUE_HMR_RUNTIME__.createRecord("${id}", ${local})` - callbackCode += - `\n if (__${exported}.__hmrHash !== ${local}.__hmrHash) ` + - `__VUE_HMR_RUNTIME__.reload("${id}", __${exported})` + callbackCode += `\n__VUE_HMR_RUNTIME__.reload("${id}", __${exported})` } code += `\nimport.meta.hot.accept(({${hotComponents @@ -195,8 +185,7 @@ function parseComponentDecls(node, source) { for (const decl of node.declarations) { if (decl.id.type === 'Identifier' && isDefineComponentCall(decl.init)) { names.push({ - name: decl.id.name, - hash: hash(source.slice(decl.init.start, decl.init.end)) + name: decl.id.name }) } } From cf5f3ab2c33aca6ab6bff8d600854f93586adcf0 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 12 Jan 2021 11:50:53 -0500 Subject: [PATCH 057/106] fix: support import.meta.url in ts esm config file close #1499 --- packages/vite/src/node/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts index 7878014cbe2e60..8f0862f30e2e86 100644 --- a/packages/vite/src/node/config.ts +++ b/packages/vite/src/node/config.ts @@ -481,7 +481,7 @@ async function bundleConfigFile( treeshake: false, plugins: [ // use esbuild + node-resolve to support .ts files - esbuildPlugin({ target: 'es2019' }), + esbuildPlugin({ target: 'esnext' }), resolvePlugin({ root: path.dirname(fileName), isBuild: true, From 50bff797c536b08661791a833cfbb9179ff54422 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 12 Jan 2021 12:10:01 -0500 Subject: [PATCH 058/106] fix: more consistent outDir formatting close #1497 --- packages/vite/src/node/plugins/reporter.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/node/plugins/reporter.ts b/packages/vite/src/node/plugins/reporter.ts index 5c5469c8ae2024..f9e72130c08ad4 100644 --- a/packages/vite/src/node/plugins/reporter.ts +++ b/packages/vite/src/node/plugins/reporter.ts @@ -3,6 +3,7 @@ import chalk from 'chalk' import { Plugin } from 'rollup' import { ResolvedConfig } from '../config' import { sync as brotliSizeSync } from 'brotli-size' +import { normalizePath } from '../utils' const enum WriteType { JS, @@ -38,8 +39,13 @@ export function buildReporterPlugin(config: ResolvedConfig): Plugin { ).toFixed(2)}kb` : `` - let outDir = path.posix.relative(process.cwd(), config.build.outDir) - if (!outDir.endsWith('/')) outDir += '/' + const outDir = + normalizePath( + path.relative( + config.root, + path.resolve(config.root, config.build.outDir) + ) + ) + '/' config.logger.info( `${chalk.gray(chalk.white.dim(outDir))}${writeColors[type]( filePath.padEnd(maxLength + 2) From a09a03045029a9d7fedf3f8d943269a4346c3882 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 12 Jan 2021 12:13:35 -0500 Subject: [PATCH 059/106] refactor: use consistent cli options style --- packages/vite/src/node/cli.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/cli.ts b/packages/vite/src/node/cli.ts index 194617992eb844..3a5d84d768d58a 100644 --- a/packages/vite/src/node/cli.ts +++ b/packages/vite/src/node/cli.ts @@ -61,7 +61,7 @@ cli .option('--https', `[boolean] use TLS + HTTP/2`) .option('--open [browser]', `[boolean | string] open browser on startup`) .option('--cors', `[boolean] enable CORS`) - .option('--strict-port', `[boolean] exit if specified port is already in use`) + .option('--strictPort', `[boolean] exit if specified port is already in use`) .option('-m, --mode ', `[string] set env mode`) .option( '--force', From 730d2f0d8081e11c88b1151086d99b23e0c58823 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 12 Jan 2021 12:33:47 -0500 Subject: [PATCH 060/106] feat: require explicit option to empty outDir when it is out of root close #1501 --- docs/config/index.md | 7 +++++++ packages/vite/package.json | 1 + packages/vite/src/node/build.ts | 28 ++++++++++++++++++++++++++-- packages/vite/src/node/cli.ts | 4 ++++ 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/docs/config/index.md b/docs/config/index.md index 3c5f72e4075aa8..f07dc6bc4bf6ed 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -415,6 +415,13 @@ export default ({ command, mode }) => { Set to `false` to disable writing the bundle to disk. This is mostly used in [programmatic `build()` calls](/guide/api-javascript#build) where further post processing of the bundle is needed before writing to disk. +### build.emptyOutDir + +- **Type:** `boolean` +- **Default:** `true` if `outDir` is inside `root` + + By default, Vite will empty the `outDir` on build if it is inside project root. It will emit a warning if `outDir` is outside of root to avoid accidentially removing important files. You can explicitly set this option to suppress the warning. This is also available via command line as `--emptyOutDir`. + ## Dep Optimization Options - **Related:** [Dependency Pre-Bundling](/guide/dep-pre-bundling) diff --git a/packages/vite/package.json b/packages/vite/package.json index 4e954297385b67..b586c793cfeb06 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -85,6 +85,7 @@ "debug": "^4.3.1", "dotenv": "^8.2.0", "dotenv-expand": "^5.1.0", + "enquirer": "^2.3.6", "es-module-lexer": "^0.3.26", "etag": "^1.8.1", "execa": "^5.0.0", diff --git a/packages/vite/src/node/build.ts b/packages/vite/src/node/build.ts index f9e04991558b44..2f0b1c285a8ebf 100644 --- a/packages/vite/src/node/build.ts +++ b/packages/vite/src/node/build.ts @@ -17,7 +17,7 @@ import { buildHtmlPlugin } from './plugins/html' import { buildEsbuildPlugin } from './plugins/esbuild' import { terserPlugin } from './plugins/terser' import { Terser } from 'types/terser' -import { copyDir, emptyDir, lookupFile } from './utils' +import { copyDir, emptyDir, lookupFile, normalizePath } from './utils' import { manifestPlugin } from './plugins/manifest' import commonjsPlugin from '@rollup/plugin-commonjs' import { RollupCommonJSOptions } from 'types/commonjs' @@ -118,6 +118,11 @@ export interface BuildOptions { * @default true */ write?: boolean + /** + * Empty outDir on write. + * @default true when outDir is a sub directory of project root + */ + emptyOutDir?: boolean | null /** * Whether to emit a manifest.json under assets dir to map hash-less filenames * to their hashed versions. Useful when you want to generate your own HTML @@ -176,6 +181,7 @@ export function resolveBuildOptions( terserOptions: {}, cleanCssOptions: {}, write: true, + emptyOutDir: null, manifest: false, lib: false, ssr: false, @@ -319,7 +325,25 @@ async function doBuild( } if (options.write) { - emptyDir(outDir) + // warn if outDir is outside of root + if (fs.existsSync(outDir)) { + const inferEmpty = options.emptyOutDir === null + if ( + options.emptyOutDir || + (inferEmpty && normalizePath(outDir).startsWith(config.root + '/')) + ) { + emptyDir(outDir) + } else if (inferEmpty) { + config.logger.warn( + chalk.yellow( + `\n${chalk.bold(`(!)`)} outDir ${chalk.white.dim( + outDir + )} is not inside project root and will not be emptied.\n` + + `Use --emptyOutDir to override.\n` + ) + ) + } + } if (fs.existsSync(publicDir)) { copyDir(publicDir, outDir) } diff --git a/packages/vite/src/node/cli.ts b/packages/vite/src/node/cli.ts index 3a5d84d768d58a..23bb9f6c21f84e 100644 --- a/packages/vite/src/node/cli.ts +++ b/packages/vite/src/node/cli.ts @@ -112,6 +112,10 @@ cli `or specify minifier to use (default: terser)` ) .option('--manifest', `[boolean] emit build manifest json`) + .option( + '--emptyOutDir', + `[boolean] force empty outDir when it's outside of root` + ) .option('-m, --mode ', `[string] set env mode`) .action(async (root: string, options: BuildOptions & GlobalCLIOptions) => { const { build } = await import('./build') From cc5fa6efb3448e2f83b5d6d428e79803c8993657 Mon Sep 17 00:00:00 2001 From: Alexandre Bonaventure Geissmann Date: Tue, 12 Jan 2021 12:39:45 -0500 Subject: [PATCH 061/106] fix(hmr): watch file changes even when HMR is disabled (#1504) --- packages/vite/src/node/server/index.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index b6454e406f7a00..5d834ce1876736 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -243,11 +243,11 @@ export async function createServer( } } - if (serverConfig.hmr !== false) { - watcher.on('change', async (file) => { - file = normalizePath(file) - // invalidate module graph cache on file change - moduleGraph.onFileChange(file) + watcher.on('change', async (file) => { + file = normalizePath(file) + // invalidate module graph cache on file change + moduleGraph.onFileChange(file) + if (serverConfig.hmr !== false) { try { await handleHMRUpdate(file, server) } catch (err) { @@ -256,8 +256,8 @@ export async function createServer( err: prepareError(err) }) } - }) - } + } + }) // apply server configuration hooks from plugins const postHooks: ((() => void) | void)[] = [] From 1629c546158253f155afecb55846771013f90ec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Wed, 13 Jan 2021 01:48:05 +0800 Subject: [PATCH 062/106] feat: allow browser new window view source (#1496) --- packages/vite/src/node/server/middlewares/transform.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/vite/src/node/server/middlewares/transform.ts b/packages/vite/src/node/server/middlewares/transform.ts index 6b9a57684de06c..65708262d9c0f1 100644 --- a/packages/vite/src/node/server/middlewares/transform.ts +++ b/packages/vite/src/node/server/middlewares/transform.ts @@ -39,7 +39,6 @@ export function transformMiddleware( return async (req, res, next) => { if ( req.method !== 'GET' || - req.headers.accept?.includes('text/html') || knownIgnoreList.has(req.url!) ) { return next() From 1ff9fe3effe9df80207d82fdae5d8ab367982c61 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 12 Jan 2021 12:48:54 -0500 Subject: [PATCH 063/106] release: v2.0.0-beta.24 --- packages/vite/CHANGELOG.md | 19 +++++++++++++++++++ packages/vite/package.json | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/vite/CHANGELOG.md b/packages/vite/CHANGELOG.md index 8084ae6f01a1e1..a8905c5378cf05 100644 --- a/packages/vite/CHANGELOG.md +++ b/packages/vite/CHANGELOG.md @@ -1,3 +1,22 @@ +# [2.0.0-beta.24](https://github.com/vitejs/vite/compare/v2.0.0-beta.23...v2.0.0-beta.24) (2021-01-12) + + +### Bug Fixes + +* **hmr:** watch file changes even when HMR is disabled ([#1504](https://github.com/vitejs/vite/issues/1504)) ([cc5fa6e](https://github.com/vitejs/vite/commit/cc5fa6efb3448e2f83b5d6d428e79803c8993657)) +* always replace preload marker with value ([2d6f524](https://github.com/vitejs/vite/commit/2d6f5243e16f7debd7ba0de4bf22706df35ccf73)) +* more consistent outDir formatting ([50bff79](https://github.com/vitejs/vite/commit/50bff797c536b08661791a833cfbb9179ff54422)), closes [#1497](https://github.com/vitejs/vite/issues/1497) +* show target build mode in logs ([#1498](https://github.com/vitejs/vite/issues/1498)) ([ae2e14b](https://github.com/vitejs/vite/commit/ae2e14baf1771c2ccdeece8bbc2b9bd11b279490)) +* support import.meta.url in ts esm config file ([cf5f3ab](https://github.com/vitejs/vite/commit/cf5f3ab2c33aca6ab6bff8d600854f93586adcf0)), closes [#1499](https://github.com/vitejs/vite/issues/1499) + + +### Features + +* allow browser new window view source ([#1496](https://github.com/vitejs/vite/issues/1496)) ([1629c54](https://github.com/vitejs/vite/commit/1629c546158253f155afecb55846771013f90ec0)) +* require explicit option to empty outDir when it is out of root ([730d2f0](https://github.com/vitejs/vite/commit/730d2f0d8081e11c88b1151086d99b23e0c58823)), closes [#1501](https://github.com/vitejs/vite/issues/1501) + + + # [2.0.0-beta.23](https://github.com/vitejs/vite/compare/v2.0.0-beta.22...v2.0.0-beta.23) (2021-01-12) diff --git a/packages/vite/package.json b/packages/vite/package.json index b586c793cfeb06..681dcab2964ef4 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -1,6 +1,6 @@ { "name": "vite", - "version": "2.0.0-beta.23", + "version": "2.0.0-beta.24", "license": "MIT", "author": "Evan You", "description": "Native-ESM powered web dev build tool", From 14617ec3c57562d1744823dda190ceade8cad6bd Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 12 Jan 2021 15:40:32 -0500 Subject: [PATCH 064/106] release: plugin-vue-jsx@1.0.2 --- packages/plugin-vue-jsx/CHANGELOG.md | 16 ++++++++++++++++ packages/plugin-vue-jsx/package.json | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/plugin-vue-jsx/CHANGELOG.md b/packages/plugin-vue-jsx/CHANGELOG.md index 70d26f58d1cc1e..f8824dd2e240a9 100644 --- a/packages/plugin-vue-jsx/CHANGELOG.md +++ b/packages/plugin-vue-jsx/CHANGELOG.md @@ -1,3 +1,19 @@ +## [1.0.2](https://github.com/vitejs/vite/compare/plugin-vue-jsx@1.0.1...plugin-vue-jsx@1.0.2) (2021-01-12) + + +### Bug Fixes + +* **plugin-vue-jsx:** files should include `index.d.ts` ([#1473](https://github.com/vitejs/vite/issues/1473)) [skip ci] ([f3ab497](https://github.com/vitejs/vite/commit/f3ab497b762e267721ace628bc6c7c5695b0d431)) +* **plugin-vue-jsx:** fix define call check ([#1480](https://github.com/vitejs/vite/issues/1480)) ([4ea065f](https://github.com/vitejs/vite/commit/4ea065f6278f30c022ed291bfb0412a674b18dd4)) +* **plugin-vue-jsx:** fix vue jsx hmr ([#1495](https://github.com/vitejs/vite/issues/1495)) ([6bdc3eb](https://github.com/vitejs/vite/commit/6bdc3eb2d004a28d2934946e33602f832b1ad8f2)) + + +### Performance Improvements + +* **plugin-vue-jsx:** only gen source map when necessary ([bfa8530](https://github.com/vitejs/vite/commit/bfa8530fc60deada634c38cfd6a23ab8ca05d47c)) + + + ## [1.0.1](https://github.com/vitejs/vite/compare/plugin-vue-jsx@1.0.0...plugin-vue-jsx@1.0.1) (2021-01-04) diff --git a/packages/plugin-vue-jsx/package.json b/packages/plugin-vue-jsx/package.json index 9f586ca1b303f6..a7a90fef1009a7 100644 --- a/packages/plugin-vue-jsx/package.json +++ b/packages/plugin-vue-jsx/package.json @@ -1,6 +1,6 @@ { "name": "@vitejs/plugin-vue-jsx", - "version": "1.0.1", + "version": "1.0.2", "license": "MIT", "author": "Evan You", "files": [ From 5fc1ea7242db16f1ad7b98286f8dee055481626d Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 12 Jan 2021 16:53:05 -0500 Subject: [PATCH 065/106] docs: a11y and seo --- docs/.vitepress/theme/index.js | 19 ++++++++++++++++--- docs/.vitepress/theme/sponsors.json | 1 + docs/index.md | 6 +++--- package.json | 1 + 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/docs/.vitepress/theme/index.js b/docs/.vitepress/theme/index.js index e99bee1facdfd9..fe497ebfa4bb30 100644 --- a/docs/.vitepress/theme/index.js +++ b/docs/.vitepress/theme/index.js @@ -11,11 +11,24 @@ export default { h('div', { class: 'sponsors' }, [ h( 'a', - { href: 'https://github.com/sponsors/yyx990803', target: '_blank' }, + { + href: 'https://github.com/sponsors/yyx990803', + target: '_blank', + rel: 'noopener' + }, [h('span', 'Sponsors')] ), - ...sponsors.map(({ href, src }) => - h('a', { href, target: '_blank' }, [h('img', { src })]) + ...sponsors.map(({ href, src, name }) => + h( + 'a', + { + href, + target: '_blank', + rel: 'noopener', + 'aria-label': 'sponsor-img' + }, + [h('img', { src, alt: name })] + ) ) ]) }) diff --git a/docs/.vitepress/theme/sponsors.json b/docs/.vitepress/theme/sponsors.json index 1789ca3bcb3699..622638f3d64c72 100644 --- a/docs/.vitepress/theme/sponsors.json +++ b/docs/.vitepress/theme/sponsors.json @@ -1,5 +1,6 @@ [ { + "name": "Tailwind Labs", "href": "https://tailwindcss.com", "src": "/tailwind-labs.svg" } diff --git a/docs/index.md b/docs/index.md index 64dbfbfbe6729f..38e12e939b3ff2 100644 --- a/docs/index.md +++ b/docs/index.md @@ -24,11 +24,11 @@ footer: MIT Licensed | Copyright © 2019-present Evan You & Vite Contributors - \ No newline at end of file + diff --git a/packages/playground/alias/package.json b/packages/playground/alias/package.json index 799762077e811d..de2c9f2756b52a 100644 --- a/packages/playground/alias/package.json +++ b/packages/playground/alias/package.json @@ -6,5 +6,8 @@ "dev": "vite", "build": "vite build", "debug": "node --inspect-brk ../../vite/bin/vite" + }, + "dependencies": { + "vue": "^3.0.5" } } diff --git a/packages/playground/alias/vite.config.js b/packages/playground/alias/vite.config.js index df8a6bf1ac4ba2..fa290d6166457f 100644 --- a/packages/playground/alias/vite.config.js +++ b/packages/playground/alias/vite.config.js @@ -12,6 +12,11 @@ module.exports = { find: /^regex\/(.*)/, replacement: `${path.resolve(__dirname, 'dir')}/$1` }, - { find: '/@', replacement: path.resolve(__dirname, 'dir') } - ] + { find: '/@', replacement: path.resolve(__dirname, 'dir') }, + // aliasing an optimized dep + { find: 'vue', replacement: 'vue/dist/vue.esm-bundler.js' } + ], + build: { + minify: false + } } diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts index 03df9e84b91901..31a1e1db53d367 100644 --- a/packages/vite/src/node/optimizer/index.ts +++ b/packages/vite/src/node/optimizer/index.ts @@ -159,12 +159,13 @@ export async function optimizeDeps( // Force included deps - these can also be deep paths if (options.include) { - options.include.forEach((id) => { - const filePath = tryNodeResolve(id, root, config.isProduction) + for (let id of options.include) { + const aliased = (await aliasResolver.resolveId(id))?.id || id + const filePath = tryNodeResolve(aliased, root, config.isProduction) if (filePath) { qualified[id] = filePath.id } - }) + } } let qualifiedIds = Object.keys(qualified) @@ -345,7 +346,8 @@ async function resolveQualifiedDeps( } let filePath try { - const resolved = tryNodeResolve(id, root, config.isProduction) + const aliased = (await aliasResolver.resolveId(id))?.id || id + const resolved = tryNodeResolve(aliased, root, config.isProduction) filePath = resolved && resolved.id } catch (e) {} if (!filePath) { diff --git a/packages/vite/src/node/plugins/index.ts b/packages/vite/src/node/plugins/index.ts index db514023bf099a..ebbf2f01f22e12 100644 --- a/packages/vite/src/node/plugins/index.ts +++ b/packages/vite/src/node/plugins/index.ts @@ -12,6 +12,7 @@ import { htmlPlugin } from './html' import { wasmPlugin } from './wasm' import { webWorkerPlugin } from './worker' import { dynamicImportPolyfillPlugin } from './dynamicImportPolyfill' +import { preAliasPlugin } from './preAlias' export async function resolvePlugins( config: ResolvedConfig, @@ -26,6 +27,7 @@ export async function resolvePlugins( : { pre: [], post: [] } return [ + isBuild ? null : preAliasPlugin(), aliasPlugin({ entries: config.alias }), ...prePlugins, config.build.polyfillDynamicImport diff --git a/packages/vite/src/node/plugins/preAlias.ts b/packages/vite/src/node/plugins/preAlias.ts new file mode 100644 index 00000000000000..7a7415002effde --- /dev/null +++ b/packages/vite/src/node/plugins/preAlias.ts @@ -0,0 +1,22 @@ +import { ViteDevServer } from '..' +import { Plugin } from '../plugin' +import { bareImportRE } from '../utils' +import { tryOptimizedResolve } from './resolve' + +/** + * A plugin to avoid an aliased AND optimized dep from being aliased in src + */ +export function preAliasPlugin(): Plugin { + let server: ViteDevServer + return { + name: 'vite:pre-alias', + configureServer(_server) { + server = _server + }, + resolveId(id) { + if (bareImportRE.test(id)) { + return tryOptimizedResolve(id, server) + } + } + } +} diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index e2ad5b1cf7bac5..10319b912f5680 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -328,7 +328,7 @@ export function tryNodeResolve( } } -function tryOptimizedResolve( +export function tryOptimizedResolve( rawId: string, server: ViteDevServer ): string | undefined { From 506bf2d542a27ee19a1b1b2d05aad845f4387cf6 Mon Sep 17 00:00:00 2001 From: Alex Kozack Date: Thu, 14 Jan 2021 20:43:28 +0200 Subject: [PATCH 090/106] fix: serve out of root static file on windows (#1537) --- packages/vite/src/node/server/middlewares/static.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/server/middlewares/static.ts b/packages/vite/src/node/server/middlewares/static.ts index 5efba8c1e7827d..6811f36aaee560 100644 --- a/packages/vite/src/node/server/middlewares/static.ts +++ b/packages/vite/src/node/server/middlewares/static.ts @@ -60,7 +60,7 @@ export function serveStaticMiddleware( export function rawFsStaticMiddleware(): Connect.NextHandleFunction { const fsRoot = - os.platform() == 'win32' ? process.cwd().split(path.sep)[0] : '/' + os.platform() == 'win32' ? process.cwd().split(path.sep)[0] + '/' : '/' const serveFromRoot = sirv(fsRoot, sirvOptions) return (req, res, next) => { From 25e9c44992c8b868cec97dbdeddd3a4837d5bb07 Mon Sep 17 00:00:00 2001 From: plq <562714485@qq.com> Date: Fri, 15 Jan 2021 02:48:44 +0800 Subject: [PATCH 091/106] feat: support specifying URL path via server.open option (#1514) --- docs/config/index.md | 13 +++++++++++-- packages/vite/src/node/server/index.ts | 7 ++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/config/index.md b/docs/config/index.md index 2ae7362aa705fb..a26eca74b61ac7 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -231,9 +231,18 @@ export default ({ command, mode }) => { ### server.open -- **Type:** `boolean` +- **Type:** `boolean | string` - Automatically open the app in the browser on server start. + Automatically open the app in the browser on server start. When the value is a string, it will be used as the URL's pathname. + + **Example:** + ```js + export default { + server: { + open: '/docs/index.html' + } + } + ``` ### server.proxy diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index f57e19ad0a18d8..cc0477b2ea0cea 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -53,7 +53,7 @@ export interface ServerOptions { /** * Open browser window on startup */ - open?: boolean + open?: boolean | string /** * Force dep pre-optimization regardless of whether deps have changed. */ @@ -486,9 +486,10 @@ async function startServer( } if (options.open) { + const path = typeof options.open === 'string' ? options.open : '' openBrowser( - `${protocol}://${hostname}:${port}`, - options.open, + `${protocol}://${hostname}:${port}${path}`, + true, server.config.logger ) } From 4338d7d6f32c8e0e67ff58f0cb8c1a9120294756 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 14 Jan 2021 14:02:55 -0500 Subject: [PATCH 092/106] feat: close server on sigint/sigterm close #1525 --- packages/vite/src/node/server/index.ts | 3 +++ packages/vite/src/node/server/pluginContainer.ts | 3 +++ 2 files changed, 6 insertions(+) diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index cc0477b2ea0cea..21b10378695913 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -248,6 +248,9 @@ export async function createServer( } } + process.once('SIGINT', server.close) + process.once('SIGTERM', server.close) + watcher.on('change', async (file) => { file = normalizePath(file) // invalidate module graph cache on file change diff --git a/packages/vite/src/node/server/pluginContainer.ts b/packages/vite/src/node/server/pluginContainer.ts index 84b6199e2507b0..72f60bc3085356 100644 --- a/packages/vite/src/node/server/pluginContainer.ts +++ b/packages/vite/src/node/server/pluginContainer.ts @@ -359,6 +359,7 @@ export async function createPluginContainer( } let nestedResolveCall = 0 + let closed = false const container: PluginContainer = { options: await (async () => { @@ -573,6 +574,7 @@ export async function createPluginContainer( }, async close() { + if (closed) return const ctx = new Context() await Promise.all( plugins.map((p) => p.buildEnd && p.buildEnd.call(ctx as any)) @@ -580,6 +582,7 @@ export async function createPluginContainer( await Promise.all( plugins.map((p) => p.closeBundle && p.closeBundle.call(ctx as any)) ) + closed = true } } From c5c32982f207055229b6bce61ce205d8d20db023 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 14 Jan 2021 15:09:50 -0500 Subject: [PATCH 093/106] feat: add clearScreen option --- docs/config/index.md | 10 +++++++++- packages/vite/src/node/cli.ts | 20 ++++++++++++++------ packages/vite/src/node/config.ts | 6 +++++- packages/vite/src/node/logger.ts | 16 +++++++++------- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/docs/config/index.md b/docs/config/index.md index a26eca74b61ac7..1c62c7f84a9a96 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -201,6 +201,13 @@ export default ({ command, mode }) => { Adjust console output verbosity. Default is `'info'`. +### clearScreen + +- **Type:** `boolean` +- **Default:** `true` + + Set to `false` to prevent Vite from clearing the terminal screen when logging certain messages. Via command line, use `--clearScreen false`. + ## Server Options ### server.host @@ -234,8 +241,9 @@ export default ({ command, mode }) => { - **Type:** `boolean | string` Automatically open the app in the browser on server start. When the value is a string, it will be used as the URL's pathname. - + **Example:** + ```js export default { server: { diff --git a/packages/vite/src/node/cli.ts b/packages/vite/src/node/cli.ts index 23bb9f6c21f84e..c3fdf6862f08b6 100644 --- a/packages/vite/src/node/cli.ts +++ b/packages/vite/src/node/cli.ts @@ -22,6 +22,7 @@ interface GlobalCLIOptions { m?: string logLevel?: LogLevel l?: LogLevel + clearScreen?: boolean } /** @@ -42,6 +43,7 @@ function cleanOptions(options: GlobalCLIOptions) { delete ret.m delete ret.logLevel delete ret.l + delete ret.clearScreen return ret } @@ -49,6 +51,7 @@ cli .option('-c, --config ', `[string] use specified config file`) .option('-r, --root ', `[string] use specified root directory`) .option('-l, --logLevel ', `[string] silent | error | warn | all`) + .option('--clearScreen', `[boolean] allow/disable clear screen when logging`) .option('-d, --debug [feat]', `[string | boolean] show debug logs`) .option('-f, --filter ', `[string] filter debug logs`) @@ -77,12 +80,14 @@ cli mode: options.mode, configFile: options.config, logLevel: options.logLevel, + clearScreen: options.clearScreen, server: cleanOptions(options) as ServerOptions }) await server.listen() } catch (e) { - const logError = createLogger(options.logLevel).error - logError(chalk.red(`error when starting dev server:\n${e.stack}`)) + createLogger(options.logLevel).error( + chalk.red(`error when starting dev server:\n${e.stack}`) + ) process.exit(1) } }) @@ -125,11 +130,13 @@ cli mode: options.mode, configFile: options.config, logLevel: options.logLevel, + clearScreen: options.clearScreen, build: cleanOptions(options) as BuildOptions }) } catch (e) { - const logError = createLogger(options.logLevel).error - logError(chalk.red(`error during build:\n${e.stack}`)) + createLogger(options.logLevel).error( + chalk.red(`error during build:\n${e.stack}`) + ) process.exit(1) } }) @@ -156,8 +163,9 @@ cli ) await optimizeDeps(config, options.force, true) } catch (e) { - const logError = createLogger(options.logLevel).error - logError(chalk.red(`error when optimizing deps:\n${e.stack}`)) + createLogger(options.logLevel).error( + chalk.red(`error when optimizing deps:\n${e.stack}`) + ) process.exit(1) } } diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts index d1708d487a8492..c9945c5364e889 100644 --- a/packages/vite/src/node/config.ts +++ b/packages/vite/src/node/config.ts @@ -98,6 +98,10 @@ export interface UserConfig { * Default: 'info' */ logLevel?: LogLevel + /** + * Default: true + */ + clearScreen?: boolean } export interface InlineConfig extends UserConfig { @@ -237,7 +241,7 @@ export async function resolveConfig( assetsInclude(file: string) { return DEFAULT_ASSETS_RE.test(file) || assetsFilter(file) }, - logger: createLogger(config.logLevel) + logger: createLogger(config.logLevel, config.clearScreen) } resolved.plugins = await resolvePlugins( diff --git a/packages/vite/src/node/logger.ts b/packages/vite/src/node/logger.ts index 262a491b3b8791..5d8988dc8958d8 100644 --- a/packages/vite/src/node/logger.ts +++ b/packages/vite/src/node/logger.ts @@ -35,8 +35,12 @@ function clearScreen() { readline.clearScreenDown(process.stdout) } -export function createLogger(level: LogLevel = 'info'): Logger { +export function createLogger( + level: LogLevel = 'info', + allowClearScreen = true +): Logger { const thresh = LogLevels[level] + const clear = allowClearScreen ? clearScreen : () => {} function output(type: LogType, msg: string, options: LogOptions = {}) { if (thresh >= LogLevels[type]) { @@ -49,23 +53,21 @@ export function createLogger(level: LogLevel = 'info'): Logger { : type === 'warn' ? chalk.yellow.bold(`[vite]`) : chalk.red.bold(`[vite]`) - return `${chalk.dim( - new Date().toLocaleTimeString() - )} ${tag} ${msg}` + return `${chalk.dim(new Date().toLocaleTimeString())} ${tag} ${msg}` } else { return msg } } if (type === lastType && msg === lastMsg) { sameCount++ - clearScreen() + clear() console[method](format(), chalk.yellow(`(x${sameCount + 1})`)) } else { sameCount = 0 lastMsg = msg lastType = type if (options.clear) { - clearScreen() + clear() } console[method](format()) } @@ -84,7 +86,7 @@ export function createLogger(level: LogLevel = 'info'): Logger { }, clearScreen(type) { if (thresh >= LogLevels[type]) { - clearScreen() + clear() } } } From 8401c8912151ca2c38a3a9e64779d86347eeb96b Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 14 Jan 2021 15:10:27 -0500 Subject: [PATCH 094/106] release: v2.0.0-beta.28 --- packages/vite/CHANGELOG.md | 20 ++++++++++++++++++++ packages/vite/package.json | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/vite/CHANGELOG.md b/packages/vite/CHANGELOG.md index 7ff0d820506bca..0a1ee8babbf763 100644 --- a/packages/vite/CHANGELOG.md +++ b/packages/vite/CHANGELOG.md @@ -1,3 +1,23 @@ +# [2.0.0-beta.28](https://github.com/vitejs/vite/compare/v2.0.0-beta.27...v2.0.0-beta.28) (2021-01-14) + + +### Bug Fixes + +* alias should work for optimized deps ([54dab71](https://github.com/vitejs/vite/commit/54dab71e41cdd9f516460d153b024d0c0cc05097)) +* serve out of root static file on windows ([#1537](https://github.com/vitejs/vite/issues/1537)) ([506bf2d](https://github.com/vitejs/vite/commit/506bf2d542a27ee19a1b1b2d05aad845f4387cf6)) +* **dev:** correct responce for html qurey ([#1526](https://github.com/vitejs/vite/issues/1526)) ([49d294d](https://github.com/vitejs/vite/commit/49d294d36d0f32d00a025a03017c9049d3f48ebd)), closes [#1524](https://github.com/vitejs/vite/issues/1524) +* **optimizer:** should respect rollup external during pre-bundling ([db97317](https://github.com/vitejs/vite/commit/db9731753abf36563172b02961ded54be23dd215)), closes [#1528](https://github.com/vitejs/vite/issues/1528) + + +### Features + +* add clearScreen option ([c5c3298](https://github.com/vitejs/vite/commit/c5c32982f207055229b6bce61ce205d8d20db023)) +* close server on sigint/sigterm ([4338d7d](https://github.com/vitejs/vite/commit/4338d7d6f32c8e0e67ff58f0cb8c1a9120294756)), closes [#1525](https://github.com/vitejs/vite/issues/1525) +* support specifying URL path via server.open option ([#1514](https://github.com/vitejs/vite/issues/1514)) ([25e9c44](https://github.com/vitejs/vite/commit/25e9c44992c8b868cec97dbdeddd3a4837d5bb07)) +* support using vite as a middleware ([960b420](https://github.com/vitejs/vite/commit/960b42068579dddc2c216720a7f16d8d189e8225)) + + + # [2.0.0-beta.27](https://github.com/vitejs/vite/compare/v2.0.0-beta.26...v2.0.0-beta.27) (2021-01-13) diff --git a/packages/vite/package.json b/packages/vite/package.json index 43fce90e032e03..60a6320a0fb884 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -1,6 +1,6 @@ { "name": "vite", - "version": "2.0.0-beta.27", + "version": "2.0.0-beta.28", "license": "MIT", "author": "Evan You", "description": "Native-ESM powered web dev build tool", From fe7238c530533d7ea7bff20ce97485669c7dfb46 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 14 Jan 2021 15:19:59 -0500 Subject: [PATCH 095/106] fix: fix graceful shutdown on sigint --- packages/vite/src/node/server/index.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index 21b10378695913..ab6580a181eb73 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -248,8 +248,15 @@ export async function createServer( } } - process.once('SIGINT', server.close) - process.once('SIGTERM', server.close) + const onExit = async () => { + try { + await server.close() + } finally { + process.exit(0) + } + } + process.once('SIGINT', onExit) + process.once('SIGTERM', onExit) watcher.on('change', async (file) => { file = normalizePath(file) From 7a1261b51695cbe7d41da6835c360b9bb26d189e Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 14 Jan 2021 15:20:30 -0500 Subject: [PATCH 096/106] fix: warn failed source map load instead of erroring --- .../vite/src/node/server/transformRequest.ts | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/packages/vite/src/node/server/transformRequest.ts b/packages/vite/src/node/server/transformRequest.ts index 1518545b5a2b0e..cb5e7808a179c9 100644 --- a/packages/vite/src/node/server/transformRequest.ts +++ b/packages/vite/src/node/server/transformRequest.ts @@ -27,7 +27,12 @@ export interface TransformResult { export async function transformRequest( url: string, - { config: { root }, pluginContainer, moduleGraph, watcher }: ViteDevServer + { + config: { root, logger }, + pluginContainer, + moduleGraph, + watcher + }: ViteDevServer ): Promise { url = removeTimestampQuery(url) const prettyUrl = isDebug ? prettifyUrl(url, root) : '' @@ -62,10 +67,16 @@ export async function transformRequest( } } if (code) { - map = ( - convertSourceMap.fromSource(code) || - convertSourceMap.fromMapFileSource(code, path.dirname(file)) - )?.toObject() + try { + map = ( + convertSourceMap.fromSource(code) || + convertSourceMap.fromMapFileSource(code, path.dirname(file)) + )?.toObject() + } catch (e) { + logger.warn(`Failed to load source map for ${url}.`, { + timestamp: true + }) + } } } else { isDebug && debugLoad(`${timeFrom(loadStart)} [plugin] ${prettyUrl}`) From a04db16f0329cfa7ef97d0f58f36189b391494a0 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 14 Jan 2021 15:25:06 -0500 Subject: [PATCH 097/106] refactor: do not intercept sigint --- packages/vite/src/node/server/index.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index ab6580a181eb73..0bfa736e8f8267 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -248,15 +248,13 @@ export async function createServer( } } - const onExit = async () => { + process.once('SIGTERM', async () => { try { await server.close() } finally { process.exit(0) } - } - process.once('SIGINT', onExit) - process.once('SIGTERM', onExit) + }) watcher.on('change', async (file) => { file = normalizePath(file) From 4579c382d4a1b0385510bb708f74305c87c4a68a Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 14 Jan 2021 15:26:40 -0500 Subject: [PATCH 098/106] fix(optimizer): fix empty exclude filter --- packages/vite/src/node/optimizer/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts index 31a1e1db53d367..eb7f9fea868ab7 100644 --- a/packages/vite/src/node/optimizer/index.ts +++ b/packages/vite/src/node/optimizer/index.ts @@ -320,14 +320,14 @@ async function resolveQualifiedDeps( const deps = Object.keys(pkg.dependencies || {}) const linked: string[] = [] const excludeFilter = - exclude && createFilter(exclude, null, { resolve: false }) + exclude && createFilter(null, exclude, { resolve: false }) for (const id of deps) { if (include && include.includes(id)) { // already force included continue } - if (excludeFilter && excludeFilter(id)) { + if (excludeFilter && !excludeFilter(id)) { debug(`skipping ${id} (excluded)`) continue } From bdec0f87e826fbfafc3f76ace6abcce2336eefef Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 14 Jan 2021 15:33:04 -0500 Subject: [PATCH 099/106] release: v2.0.0-beta.29 --- packages/vite/CHANGELOG.md | 11 +++++++++++ packages/vite/package.json | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/vite/CHANGELOG.md b/packages/vite/CHANGELOG.md index 0a1ee8babbf763..6c0b6ee9269eac 100644 --- a/packages/vite/CHANGELOG.md +++ b/packages/vite/CHANGELOG.md @@ -1,3 +1,14 @@ +# [2.0.0-beta.29](https://github.com/vitejs/vite/compare/v2.0.0-beta.28...v2.0.0-beta.29) (2021-01-14) + + +### Bug Fixes + +* **optimizer:** fix empty exclude filter ([4579c38](https://github.com/vitejs/vite/commit/4579c382d4a1b0385510bb708f74305c87c4a68a)) +* fix graceful shutdown on sigint ([fe7238c](https://github.com/vitejs/vite/commit/fe7238c530533d7ea7bff20ce97485669c7dfb46)) +* warn failed source map load instead of erroring ([7a1261b](https://github.com/vitejs/vite/commit/7a1261b51695cbe7d41da6835c360b9bb26d189e)) + + + # [2.0.0-beta.28](https://github.com/vitejs/vite/compare/v2.0.0-beta.27...v2.0.0-beta.28) (2021-01-14) diff --git a/packages/vite/package.json b/packages/vite/package.json index 60a6320a0fb884..e6402a359d26a6 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -1,6 +1,6 @@ { "name": "vite", - "version": "2.0.0-beta.28", + "version": "2.0.0-beta.29", "license": "MIT", "author": "Evan You", "description": "Native-ESM powered web dev build tool", From 9f54510b30e624e10f13bb7d52722a00fc185242 Mon Sep 17 00:00:00 2001 From: Alex Kozack Date: Fri, 15 Jan 2021 16:28:45 +0200 Subject: [PATCH 100/106] docs: Add Packages table (#1550) [skip ci] --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index bb26db71c709de..395af493b2e07a 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,17 @@ In addition, Vite is highly extensible via its [Plugin API](https://vitejs.dev/g Vite is now in 2.0 beta. Check out the [Migration Guide](https://vitejs.dev/guide/migration.html) if you are upgrading from 1.x. +## Packages + +| Package | Version | +|---------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------| +| [vite](packages/vite) | [![vite version](https://img.shields.io/npm/v/vite.svg?label=%20)](packages/vite/CHANGELOG.md) | +| [@vitejs/plugin-vue](packages/plugin-vue) | [![plugin-vue version](https://img.shields.io/npm/v/@vitejs/plugin-vue.svg?label=%20)](packages/plugin-vue/CHANGELOG.md) | +| [@vitejs/plugin-vue-jsx](packages/plugin-vue-jsx) | [![plugin-vue-jsx version](https://img.shields.io/npm/v/@vitejs/plugin-vue-jsx.svg?label=%20)](packages/plugin-vue-jsx/CHANGELOG.md) | +| [@vitejs/plugin-react-refresh](packages/plugin-react-refresh) | [![plugin-react-refresh version](https://img.shields.io/npm/v/@vitejs/plugin-react-refresh.svg?label=%20)](packages/plugin-react-refresh/CHANGELOG.md) | +| [@vitejs/plugin-legacy](packages/plugin-legacy) | [![plugin-legacy version](https://img.shields.io/npm/v/@vitejs/plugin-legacy.svg?label=%20)](packages/plugin-legacy/CHANGELOG.md) | +| [@vitejs/create-app](packages/create-app) | [![create-app version](https://img.shields.io/npm/v/@vitejs/create-app.svg?label=%20)](packages/create-app/CHANGELOG.md) + ## Contribution See [Contributing Guide](https://github.com/vitejs/vite/tree/main/.github/contributing.md). From bd3b1bfd83488b05a188a9d1c7093e3003721d91 Mon Sep 17 00:00:00 2001 From: CHOYSEN <582511362@qq.com> Date: Fri, 15 Jan 2021 22:36:41 +0800 Subject: [PATCH 101/106] fix(config): delete cache correctly when restarting server (#1541) --- packages/vite/src/node/config.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts index c9945c5364e889..bd2543819912fd 100644 --- a/packages/vite/src/node/config.ts +++ b/packages/vite/src/node/config.ts @@ -433,7 +433,7 @@ export async function loadConfigFromFile( // 1. try to directly require the module (assuming commonjs) try { // clear cache in case of server restart - delete require.cache[resolvedPath] + delete require.cache[require.resolve(resolvedPath)] userConfig = require(resolvedPath) debug(`cjs config loaded in ${Date.now() - start}ms`) } catch (e) { @@ -530,7 +530,8 @@ async function loadConfigFromBundledFile( defaultLoader(module, filename) } } - delete require.cache[fileName] + // clear cache in case of server restart + delete require.cache[require.resolve(fileName)] const raw = require(fileName) const config = raw.__esModule ? raw.default : raw require.extensions[extension] = defaultLoader From 2ce1efa0871b9d7111ae8265c3f362fb45037664 Mon Sep 17 00:00:00 2001 From: qicoo <757271842@qq.com> Date: Fri, 15 Jan 2021 22:37:32 +0800 Subject: [PATCH 102/106] docs: typo (#1540) --- docs/guide/dep-pre-bundling.md | 2 +- packages/vite/types/chokidar.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guide/dep-pre-bundling.md b/docs/guide/dep-pre-bundling.md index ec66ba2a8eef9a..a574e3772ead8e 100644 --- a/docs/guide/dep-pre-bundling.md +++ b/docs/guide/dep-pre-bundling.md @@ -54,7 +54,7 @@ Some dependencies may be designed to be used via deep imports, e.g. `firebase` e ## Dependency Compatibility -While Vite tries its best to accomodate non-ESM dependencies, there are going to be some dependencies that won't work out of the box. The most common types are those that import Node.js built-in modules (e.g. `os` or `path`) and expect the bundler to automatically shim them. These packages are typically written assuming all users will be consuming it with `webpack`, but such usage does not make sense when targeting browser environments. +While Vite tries its best to accommodate non-ESM dependencies, there are going to be some dependencies that won't work out of the box. The most common types are those that import Node.js built-in modules (e.g. `os` or `path`) and expect the bundler to automatically shim them. These packages are typically written assuming all users will be consuming it with `webpack`, but such usage does not make sense when targeting browser environments. When using Vite, it is strongly recommended to always prefer dependencies that provide ESM formats. This will make your build faster, and results in smaller production bundles due to more efficient tree-shaking. diff --git a/packages/vite/types/chokidar.d.ts b/packages/vite/types/chokidar.d.ts index a1ca6af2a05c15..743c2cb3e19d5b 100644 --- a/packages/vite/types/chokidar.d.ts +++ b/packages/vite/types/chokidar.d.ts @@ -154,7 +154,7 @@ export interface WatchOptions { /** * Whether to use the `fsevents` watching interface if available. When set to `true` explicitly - * and `fsevents` is available this supercedes the `usePolling` setting. When set to `false` on + * and `fsevents` is available this supersedes the `usePolling` setting. When set to `false` on * OS X, `usePolling: true` becomes the default. */ useFsEvents?: boolean From d8754deeb16ef0d86b17dfa2a3394d0919bcd72e Mon Sep 17 00:00:00 2001 From: underfin Date: Fri, 15 Jan 2021 22:39:18 +0800 Subject: [PATCH 103/106] fix(plugin-vue): sfc src import respect alias (#1544) fix #1542 --- .../playground/vue/src-import/SrcImport.vue | 2 +- packages/playground/vue/vite.config.ts | 4 ++ packages/plugin-vue/src/main.ts | 57 ++++++++++++------- 3 files changed, 41 insertions(+), 22 deletions(-) diff --git a/packages/playground/vue/src-import/SrcImport.vue b/packages/playground/vue/src-import/SrcImport.vue index 9ff8831029f10c..ac7ec78c869e65 100644 --- a/packages/playground/vue/src-import/SrcImport.vue +++ b/packages/playground/vue/src-import/SrcImport.vue @@ -1,3 +1,3 @@ - + diff --git a/packages/playground/vue/vite.config.ts b/packages/playground/vue/vite.config.ts index 707f3fbe5a89ce..b528b36535c3c9 100644 --- a/packages/playground/vue/vite.config.ts +++ b/packages/playground/vue/vite.config.ts @@ -1,8 +1,12 @@ +import path from 'path' import { defineConfig } from 'vite' import vuePlugin from '@vitejs/plugin-vue' import { vueI18nPlugin } from './CustomBlockPlugin' export default defineConfig({ + alias: { + '/@': __dirname + }, plugins: [vuePlugin(), vueI18nPlugin], build: { // to make tests faster diff --git a/packages/plugin-vue/src/main.ts b/packages/plugin-vue/src/main.ts index 2f3ace6f081304..1c8fcafa3d0df4 100644 --- a/packages/plugin-vue/src/main.ts +++ b/packages/plugin-vue/src/main.ts @@ -42,7 +42,11 @@ export async function transformMain( const hasScoped = descriptor.styles.some((s) => s.scoped) // script - const { code: scriptCode, map } = await genScriptCode(descriptor, options) + const { code: scriptCode, map } = await genScriptCode( + descriptor, + options, + pluginContext + ) // template // Check if we can use compile template as inlined render function @@ -57,7 +61,7 @@ export async function transformMain( let templateCode = '' let templateMap if (hasTemplateImport) { - ;({ code: templateCode, map: templateMap } = genTemplateCode( + ;({ code: templateCode, map: templateMap } = await genTemplateCode( descriptor, options, pluginContext @@ -71,10 +75,10 @@ export async function transformMain( : '' // styles - const stylesCode = genStyleCode(descriptor) + const stylesCode = await genStyleCode(descriptor, pluginContext) // custom blocks - const customBlocksCode = genCustomBlockCode(descriptor) + const customBlocksCode = await genCustomBlockCode(descriptor, pluginContext) const output: string[] = [ scriptCode, @@ -148,7 +152,7 @@ export async function transformMain( } } -function genTemplateCode( +async function genTemplateCode( descriptor: SFCDescriptor, options: ResolvedOptions, pluginContext: PluginContext @@ -167,7 +171,7 @@ function genTemplateCode( ) } else { if (template.src) { - linkSrcToDescriptor(template.src, descriptor) + await linkSrcToDescriptor(template.src, descriptor, pluginContext) } const src = template.src || descriptor.filename const srcQuery = template.src ? `&src` : `` @@ -184,7 +188,8 @@ function genTemplateCode( async function genScriptCode( descriptor: SFCDescriptor, - options: ResolvedOptions + options: ResolvedOptions, + pluginContext: PluginContext ): Promise<{ code: string map: RawSourceMap @@ -213,7 +218,7 @@ async function genScriptCode( } } else { if (script.src) { - linkSrcToDescriptor(script.src, descriptor) + await linkSrcToDescriptor(script.src, descriptor, pluginContext) } const src = script.src || descriptor.filename const langFallback = (script.src && path.extname(src).slice(1)) || 'js' @@ -231,13 +236,17 @@ async function genScriptCode( } } -function genStyleCode(descriptor: SFCDescriptor) { +async function genStyleCode( + descriptor: SFCDescriptor, + pluginContext: PluginContext +) { let stylesCode = `` let hasCSSModules = false if (descriptor.styles.length) { - descriptor.styles.forEach((style, i) => { + for (let i = 0; i < descriptor.styles.length; i++) { + const style = descriptor.styles[i] if (style.src) { - linkSrcToDescriptor(style.src, descriptor) + await linkSrcToDescriptor(style.src, descriptor, pluginContext) } const src = style.src || descriptor.filename // do not include module in default query, since we use it to indicate @@ -256,16 +265,20 @@ function genStyleCode(descriptor: SFCDescriptor) { stylesCode += `\nimport ${JSON.stringify(styleRequest)}` } // TODO SSR critical CSS collection - }) + } } return stylesCode } -function genCustomBlockCode(descriptor: SFCDescriptor) { +async function genCustomBlockCode( + descriptor: SFCDescriptor, + pluginContext: PluginContext +) { let code = '' - descriptor.customBlocks.forEach((block, index) => { + for (let index = 0; index < descriptor.customBlocks.length; index++) { + const block = descriptor.customBlocks[index] if (block.src) { - linkSrcToDescriptor(block.src, descriptor) + await linkSrcToDescriptor(block.src, descriptor, pluginContext) } const src = block.src || descriptor.filename const attrsQuery = attrsToQuery(block.attrs, block.type) @@ -274,7 +287,7 @@ function genCustomBlockCode(descriptor: SFCDescriptor) { const request = JSON.stringify(src + query) code += `import block${index} from ${request}\n` code += `if (typeof block${index} === 'function') block${index}(_sfc_main)\n` - }) + } return code } @@ -298,11 +311,13 @@ function genCSSModulesCode( * with its owner SFC descriptor so that we can get the information about * the owner SFC when compiling that file in the transform phase. */ -function linkSrcToDescriptor(src: string, descriptor: SFCDescriptor) { - const srcFile = path.posix.resolve( - path.posix.dirname(descriptor.filename), - src - ) +async function linkSrcToDescriptor( + src: string, + descriptor: SFCDescriptor, + pluginContext: PluginContext +) { + const srcFile = + (await pluginContext.resolve(src, descriptor.filename))?.id || src setDescriptor(srcFile, descriptor) } From 55b05dba3d157da72eaf9c445b0bb5084b9858d0 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 15 Jan 2021 09:50:34 -0500 Subject: [PATCH 104/106] fix(config): load native esm ts config string with base64 encoding fix #1548 --- packages/vite/src/node/config.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts index bd2543819912fd..066c38fe4cd4dd 100644 --- a/packages/vite/src/node/config.ts +++ b/packages/vite/src/node/config.ts @@ -415,7 +415,11 @@ export async function loadConfigFromFile( const code = await bundleConfigFile(resolvedPath, 'es') userConfig = ( await eval( - `import(${JSON.stringify(`data:text/javascript,${code}`)})` + `import(${JSON.stringify( + `data:text/javascript;base64,${Buffer.from(code).toString( + 'base64' + )}` + )})` ) ).default debug(`TS + native esm config loaded in ${Date.now() - start}ms`) From 74b6e3a7e158d84aed36b8cf062a2f726b0f0c4a Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 15 Jan 2021 10:03:32 -0500 Subject: [PATCH 105/106] release: v2.0.0-beta.30 --- packages/vite/CHANGELOG.md | 10 ++++++++++ packages/vite/package.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/vite/CHANGELOG.md b/packages/vite/CHANGELOG.md index 6c0b6ee9269eac..03eea084830577 100644 --- a/packages/vite/CHANGELOG.md +++ b/packages/vite/CHANGELOG.md @@ -1,3 +1,13 @@ +# [2.0.0-beta.30](https://github.com/vitejs/vite/compare/v2.0.0-beta.29...v2.0.0-beta.30) (2021-01-15) + + +### Bug Fixes + +* **config:** delete cache correctly when restarting server ([#1541](https://github.com/vitejs/vite/issues/1541)) ([bd3b1bf](https://github.com/vitejs/vite/commit/bd3b1bfd83488b05a188a9d1c7093e3003721d91)) +* **config:** load native esm ts config string with base64 encoding ([55b05db](https://github.com/vitejs/vite/commit/55b05dba3d157da72eaf9c445b0bb5084b9858d0)), closes [#1548](https://github.com/vitejs/vite/issues/1548) + + + # [2.0.0-beta.29](https://github.com/vitejs/vite/compare/v2.0.0-beta.28...v2.0.0-beta.29) (2021-01-14) diff --git a/packages/vite/package.json b/packages/vite/package.json index e6402a359d26a6..4220562bc45fd2 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -1,6 +1,6 @@ { "name": "vite", - "version": "2.0.0-beta.29", + "version": "2.0.0-beta.30", "license": "MIT", "author": "Evan You", "description": "Native-ESM powered web dev build tool", From 6a9a4aaf8ef78dc37629fd6962fc6d057f126c53 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 15 Jan 2021 10:04:06 -0500 Subject: [PATCH 106/106] release: plugin-vue@1.0.6 --- packages/plugin-vue/CHANGELOG.md | 9 +++++++++ packages/plugin-vue/package.json | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/plugin-vue/CHANGELOG.md b/packages/plugin-vue/CHANGELOG.md index e18bf1c3b16d67..deaa35c4b1db99 100644 --- a/packages/plugin-vue/CHANGELOG.md +++ b/packages/plugin-vue/CHANGELOG.md @@ -1,3 +1,12 @@ +## [1.0.6](https://github.com/vitejs/vite/compare/plugin-vue@1.0.5...plugin-vue@1.0.6) (2021-01-15) + + +### Bug Fixes + +* **plugin-vue:** sfc src import respect alias ([#1544](https://github.com/vitejs/vite/issues/1544)) ([d8754de](https://github.com/vitejs/vite/commit/d8754deeb16ef0d86b17dfa2a3394d0919bcd72e)), closes [#1542](https://github.com/vitejs/vite/issues/1542) + + + ## [1.0.5](https://github.com/vitejs/vite/compare/plugin-vue@1.0.4...plugin-vue@1.0.5) (2021-01-09) diff --git a/packages/plugin-vue/package.json b/packages/plugin-vue/package.json index e9f7cdef60f536..b7463a1f20bf7d 100644 --- a/packages/plugin-vue/package.json +++ b/packages/plugin-vue/package.json @@ -1,6 +1,6 @@ { "name": "@vitejs/plugin-vue", - "version": "1.0.5", + "version": "1.0.6", "license": "MIT", "author": "Evan You", "files": [