From 9892ab846266b11dbd32393fe3e6357cea688ac9 Mon Sep 17 00:00:00 2001 From: patak-js Date: Mon, 11 Oct 2021 21:22:12 +0200 Subject: [PATCH 1/6] refactor!: plugin hooks ssr param to object --- docs/guide/ssr.md | 12 +++++++++--- packages/plugin-react/src/index.ts | 3 ++- packages/plugin-vue-jsx/index.js | 5 +++-- packages/plugin-vue/src/index.ts | 15 +++++++++++---- packages/vite/src/node/plugin.ts | 7 +++---- .../vite/src/node/plugins/assetImportMetaUrl.ts | 4 ++-- packages/vite/src/node/plugins/css.ts | 4 ++-- packages/vite/src/node/plugins/define.ts | 3 ++- packages/vite/src/node/plugins/importAnalysis.ts | 3 ++- packages/vite/src/node/plugins/preAlias.ts | 4 ++-- packages/vite/src/node/plugins/resolve.ts | 3 ++- packages/vite/src/node/server/pluginContainer.ts | 7 +++---- 12 files changed, 43 insertions(+), 27 deletions(-) diff --git a/docs/guide/ssr.md b/docs/guide/ssr.md index 97a7140c98490e..47faf97682a1ad 100644 --- a/docs/guide/ssr.md +++ b/docs/guide/ssr.md @@ -227,7 +227,7 @@ If you have configured aliases that redirects one package to another, you may wa ## SSR-specific Plugin Logic -Some frameworks such as Vue or Svelte compiles components into different formats based on client vs. SSR. To support conditional transforms, Vite passes an additional `ssr` argument to the following plugin hooks: +Some frameworks such as Vue or Svelte compiles components into different formats based on client vs. SSR. To support conditional transforms, Vite passes an additional `ssr` property in the `options` object of the following plugin hooks: - `resolveId` - `load` @@ -239,8 +239,8 @@ Some frameworks such as Vue or Svelte compiles components into different formats export function mySSRPlugin() { return { name: 'my-ssr', - transform(code, id, ssr) { - if (ssr) { + transform(code, id, options) { + if (options?.ssr) { // perform ssr-specific transform... } } @@ -248,6 +248,12 @@ export function mySSRPlugin() { } ``` +The options object in `load` and `transform` is optional, rollup is not currently using this object but may extend these hooks with additional metadata in the future. + +::: note +Before Vite 2.7, this was informed to plugin hooks with a positional `ssr` param instead of using the `options` object. All major frameworks and plugins are updated but you may find outdated posts using the previous API. +::: + ## SSR Target The default target for the SSR build is a node environment, but you can also run the server in a Web Worker. Packages entry resolution is different for each platform. You can configure the target to be Web Worker using the `ssr.target` set to `'webworker'`. diff --git a/packages/plugin-react/src/index.ts b/packages/plugin-react/src/index.ts index 6d5f05aef8a32f..97341815511ecc 100644 --- a/packages/plugin-react/src/index.ts +++ b/packages/plugin-react/src/index.ts @@ -91,7 +91,8 @@ export default function viteReact(opts: Options = {}): PluginOption[] { ) ) }, - async transform(code, id, ssr) { + async transform(code, id, options) { + const ssr = typeof options === 'boolean' ? options : options?.ssr === true if (/\.[tj]sx?$/.test(id)) { const plugins = [...userPlugins] diff --git a/packages/plugin-vue-jsx/index.js b/packages/plugin-vue-jsx/index.js index 6866899c8cb82c..bb4b2d2ab629ab 100644 --- a/packages/plugin-vue-jsx/index.js +++ b/packages/plugin-vue-jsx/index.js @@ -22,7 +22,7 @@ function ssrRegisterHelper(comp, filename) { comp.setup = (props, ctx) => { // @ts-ignore const ssrContext = useSSRContext() - ;(ssrContext.modules || (ssrContext.modules = new Set())).add(filename) + ; (ssrContext.modules || (ssrContext.modules = new Set())).add(filename) if (setup) { return setup(props, ctx) } @@ -80,7 +80,8 @@ function vueJsxPlugin(options = {}) { } }, - transform(code, id, ssr) { + transform(code, id, opt) { + const ssr = typeof opt === 'boolean' ? opt : opt?.ssr === true const { include, exclude, diff --git a/packages/plugin-vue/src/index.ts b/packages/plugin-vue/src/index.ts index e954e058949491..646f9134a43562 100644 --- a/packages/plugin-vue/src/index.ts +++ b/packages/plugin-vue/src/index.ts @@ -87,8 +87,8 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin { refTransform === false ? () => false : refTransform === true - ? createFilter(/\.(j|t)sx?$/, /node_modules/) - : createFilter(refTransform) + ? createFilter(/\.(j|t)sx?$/, /node_modules/) + : createFilter(refTransform) // compat for older verisons const canUseRefTransform = typeof compiler.shouldTransformRef === 'function' @@ -104,6 +104,11 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin { sourceMap: true } + // Temporal handling for 2.7 breaking change + const isSSR = (opt: { ssr?: boolean } | boolean | undefined) => + opt === undefined ? !!options.ssr : + (typeof opt === 'boolean' ? opt : opt?.ssr === true) + return { name: 'vite:vue', @@ -150,7 +155,8 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin { } }, - load(id, ssr = !!options.ssr) { + load(id, opt) { + const ssr = isSSR(opt) if (id === EXPORT_HELPER_ID) { return helperCode } @@ -182,7 +188,8 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin { } }, - transform(code, id, ssr = !!options.ssr) { + transform(code, id, opt) { + const ssr = isSSR(opt) const { filename, query } = parseVueRequest(id) if (query.raw) { return diff --git a/packages/vite/src/node/plugin.ts b/packages/vite/src/node/plugin.ts index 3af59bbd09b62c..09c4aa31d7fcb1 100644 --- a/packages/vite/src/node/plugin.ts +++ b/packages/vite/src/node/plugin.ts @@ -121,18 +121,17 @@ export interface Plugin extends RollupPlugin { this: PluginContext, source: string, importer: string | undefined, - options: { custom?: CustomPluginOptions }, - ssr?: boolean + options: { custom?: CustomPluginOptions, ssr?: boolean } ): Promise | ResolveIdResult load?( this: PluginContext, id: string, - ssr?: boolean + options?: { ssr?: boolean } ): Promise | LoadResult transform?( this: TransformPluginContext, code: string, id: string, - ssr?: boolean + options?: { ssr?: boolean } ): Promise | TransformResult } diff --git a/packages/vite/src/node/plugins/assetImportMetaUrl.ts b/packages/vite/src/node/plugins/assetImportMetaUrl.ts index a0da45f4aaf155..2eb4a175f5a7d1 100644 --- a/packages/vite/src/node/plugins/assetImportMetaUrl.ts +++ b/packages/vite/src/node/plugins/assetImportMetaUrl.ts @@ -18,7 +18,7 @@ import { multilineCommentsRE, singlelineCommentsRE } from '../utils' export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin { return { name: 'vite:asset-import-meta-url', - async transform(code, id, ssr) { + async transform(code, id, options) { if (code.includes('new URL') && code.includes(`import.meta.url`)) { const importMetaUrlRE = /\bnew\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*\)/g @@ -30,7 +30,7 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin { while ((match = importMetaUrlRE.exec(noCommentsCode))) { const { 0: exp, 1: rawUrl, index } = match - if (ssr) { + if (options?.ssr) { this.error( `\`new URL(url, import.meta.url)\` is not supported in SSR.`, index diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 1a62bf7f028d13..5fec8522c5e5c4 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -271,7 +271,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { hasEmitted = false }, - async transform(css, id, ssr) { + async transform(css, id, options) { if (!isCSSRequest(id) || commonjsProxyRE.test(id)) { return } @@ -286,7 +286,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { return css } else { // server only - if (ssr) { + if (options?.ssr) { return modulesCode || `export default ${JSON.stringify(css)}` } if (inlined) { diff --git a/packages/vite/src/node/plugins/define.ts b/packages/vite/src/node/plugins/define.ts index bc466cc3daae0a..574c46eab70fb0 100644 --- a/packages/vite/src/node/plugins/define.ts +++ b/packages/vite/src/node/plugins/define.ts @@ -59,7 +59,8 @@ export function definePlugin(config: ResolvedConfig): Plugin { return { name: 'vite:define', - transform(code, id, ssr) { + transform(code, id, options) { + const ssr = options?.ssr === true if (!ssr && !isBuild) { // for dev we inject actual global defines in the vite client to // avoid the transform cost. diff --git a/packages/vite/src/node/plugins/importAnalysis.ts b/packages/vite/src/node/plugins/importAnalysis.ts index fa2d261f577004..dc66f20b217853 100644 --- a/packages/vite/src/node/plugins/importAnalysis.ts +++ b/packages/vite/src/node/plugins/importAnalysis.ts @@ -105,7 +105,8 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { server = _server }, - async transform(source, importer, ssr) { + async transform(source, importer, options) { + const ssr = options?.ssr === true const prettyImporter = prettifyUrl(importer, root) if (canSkip(importer)) { diff --git a/packages/vite/src/node/plugins/preAlias.ts b/packages/vite/src/node/plugins/preAlias.ts index 03337ecf19b60b..f194a8c29c78d7 100644 --- a/packages/vite/src/node/plugins/preAlias.ts +++ b/packages/vite/src/node/plugins/preAlias.ts @@ -13,8 +13,8 @@ export function preAliasPlugin(): Plugin { configureServer(_server) { server = _server }, - resolveId(id, importer, _, ssr) { - if (!ssr && bareImportRE.test(id)) { + resolveId(id, importer, options) { + if (!options?.ssr && bareImportRE.test(id)) { return tryOptimizedResolve(id, server, importer) } } diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index 9b8519a43119c0..b58fec288793d0 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -89,7 +89,8 @@ export function resolvePlugin(baseOptions: InternalResolveOptions): Plugin { server = _server }, - resolveId(id, importer, resolveOpts, ssr) { + resolveId(id, importer, resolveOpts) { + const ssr = resolveOpts?.ssr === true if (id.startsWith(browserExternalId)) { return id } diff --git a/packages/vite/src/node/server/pluginContainer.ts b/packages/vite/src/node/server/pluginContainer.ts index 6287bfbd1b79ab..20c8f7c0ba07ff 100644 --- a/packages/vite/src/node/server/pluginContainer.ts +++ b/packages/vite/src/node/server/pluginContainer.ts @@ -439,8 +439,7 @@ export async function createPluginContainer( ctx as any, rawId, importer, - {}, - ssr + { ssr } ) if (!result) continue @@ -487,7 +486,7 @@ export async function createPluginContainer( for (const plugin of plugins) { if (!plugin.load) continue ctx._activePlugin = plugin - const result = await plugin.load.call(ctx as any, id, ssr) + const result = await plugin.load.call(ctx as any, id, { ssr }) if (result != null) { return result } @@ -506,7 +505,7 @@ export async function createPluginContainer( const start = isDebug ? performance.now() : 0 let result: TransformResult | string | undefined try { - result = await plugin.transform.call(ctx as any, code, id, ssr) + result = await plugin.transform.call(ctx as any, code, id, { ssr }) } catch (e) { ctx.error(e) } From a22ca8aabb994ae708d99e8210a215a4c3105fa9 Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 11 Oct 2021 21:51:21 +0200 Subject: [PATCH 2/6] chore: spacing --- packages/plugin-vue-jsx/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-vue-jsx/index.js b/packages/plugin-vue-jsx/index.js index bb4b2d2ab629ab..76ccb85a1f225e 100644 --- a/packages/plugin-vue-jsx/index.js +++ b/packages/plugin-vue-jsx/index.js @@ -22,7 +22,7 @@ function ssrRegisterHelper(comp, filename) { comp.setup = (props, ctx) => { // @ts-ignore const ssrContext = useSSRContext() - ; (ssrContext.modules || (ssrContext.modules = new Set())).add(filename) + ;(ssrContext.modules || (ssrContext.modules = new Set())).add(filename) if (setup) { return setup(props, ctx) } From 549a62d1ae01e24bb7fd1437e4d27c1deaaa7820 Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 11 Oct 2021 21:51:48 +0200 Subject: [PATCH 3/6] chore: spacing --- packages/plugin-vue/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugin-vue/src/index.ts b/packages/plugin-vue/src/index.ts index 646f9134a43562..55a34ba0dc70a1 100644 --- a/packages/plugin-vue/src/index.ts +++ b/packages/plugin-vue/src/index.ts @@ -87,8 +87,8 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin { refTransform === false ? () => false : refTransform === true - ? createFilter(/\.(j|t)sx?$/, /node_modules/) - : createFilter(refTransform) + ? createFilter(/\.(j|t)sx?$/, /node_modules/) + : createFilter(refTransform) // compat for older verisons const canUseRefTransform = typeof compiler.shouldTransformRef === 'function' From 333e6dc4ee80b9d1145d7e1e0418129351ae69d1 Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 11 Oct 2021 22:02:18 +0200 Subject: [PATCH 4/6] fix: node 12 support in plugin-vue-jsx --- packages/plugin-vue-jsx/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-vue-jsx/index.js b/packages/plugin-vue-jsx/index.js index 76ccb85a1f225e..a520ae176dd770 100644 --- a/packages/plugin-vue-jsx/index.js +++ b/packages/plugin-vue-jsx/index.js @@ -81,7 +81,7 @@ function vueJsxPlugin(options = {}) { }, transform(code, id, opt) { - const ssr = typeof opt === 'boolean' ? opt : opt?.ssr === true + const ssr = typeof opt === 'boolean' ? opt : (opt && opt.ssr) === true const { include, exclude, From f57c50c61eda3303e0551cea8b538393a084a532 Mon Sep 17 00:00:00 2001 From: patak-js Date: Tue, 12 Oct 2021 22:30:43 +0200 Subject: [PATCH 5/6] fix: inject ssr flag in rollup build --- packages/vite/src/node/build.ts | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/packages/vite/src/node/build.ts b/packages/vite/src/node/build.ts index 148833eabe9b30..6672be7224fdf3 100644 --- a/packages/vite/src/node/build.ts +++ b/packages/vite/src/node/build.ts @@ -785,15 +785,35 @@ function injectSsrFlagToHooks(p: Plugin): Plugin { const { resolveId, load, transform } = p return { ...p, - resolveId: wrapSsrHook(resolveId), - load: wrapSsrHook(load), - transform: wrapSsrHook(transform) + resolveId: wrapSsrResolveId(resolveId), + load: wrapSsrLoad(load), + transform: wrapSsrTransform(transform) } } -function wrapSsrHook(fn: Function | undefined) { +function wrapSsrResolveId(fn: Function | undefined) { if (!fn) return - return function (this: any, ...args: any[]) { - return fn.call(this, ...args, true) + return function (this: any, id: any, importer: any, options: any) { + return fn.call(this, id, importer, injectSsrFlag(options)) } } + +function wrapSsrLoad(fn: Function | undefined) { + if (!fn) return + // Receiving options param to be future-proof if Rollup adds it + return function (this: any, id: any, ...args: any[]) { + return fn.call(this, id, injectSsrFlag(args[0])) + } +} + +function wrapSsrTransform(fn: Function | undefined) { + if (!fn) return + // Receiving options param to be future-proof if Rollup adds it + return function (this: any, code: any, importer: any, ...args: any[]) { + return fn.call(this, code, importer, injectSsrFlag(args[0])) + } +} + +function injectSsrFlag(options: any = {}) { + return { ...options, ssr: true } +} From 318d727b6972eaeca74575b77eba842654644355 Mon Sep 17 00:00:00 2001 From: patak-js Date: Wed, 27 Oct 2021 14:50:20 +0200 Subject: [PATCH 6/6] fix: merge issue --- packages/plugin-react/src/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/plugin-react/src/index.ts b/packages/plugin-react/src/index.ts index ad0e24366d61d4..2cc9eaab5a5f75 100644 --- a/packages/plugin-react/src/index.ts +++ b/packages/plugin-react/src/index.ts @@ -98,7 +98,8 @@ export default function viteReact(opts: Options = {}): PluginOption[] { ) ) }, - async transform(code, id, ssr) { + async transform(code, id, options) { + const ssr = typeof options === 'boolean' ? options : options?.ssr === true // File extension could be mocked/overriden in querystring. const [filepath, querystring = ''] = id.split('?') const [extension = ''] =