From 04c06e678f3c5dcfd5e705f744f367c73ee969d9 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Fri, 25 Jun 2021 15:14:23 -0400 Subject: [PATCH] feat(ssr): respect `resolve.dedupe` in production --- packages/vite/src/node/plugins/index.ts | 4 ++ .../vite/src/node/plugins/ssrRequireHook.ts | 42 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 packages/vite/src/node/plugins/ssrRequireHook.ts diff --git a/packages/vite/src/node/plugins/index.ts b/packages/vite/src/node/plugins/index.ts index cf982fcd0b4482..a2f24f65b6a104 100644 --- a/packages/vite/src/node/plugins/index.ts +++ b/packages/vite/src/node/plugins/index.ts @@ -14,6 +14,7 @@ import { dynamicImportPolyfillPlugin } from './dynamicImportPolyfill' import { webWorkerPlugin } from './worker' import { preAliasPlugin } from './preAlias' import { definePlugin } from './define' +import { ssrRequireHookPlugin } from './ssrRequireHook' export async function resolvePlugins( config: ResolvedConfig, @@ -40,6 +41,9 @@ export async function resolvePlugins( ssrTarget: config.ssr?.target, asSrc: true }), + config.ssr && config.command === 'build' + ? ssrRequireHookPlugin(config) + : null, htmlInlineScriptProxyPlugin(), cssPlugin(config), config.esbuild !== false ? esbuildPlugin(config.esbuild) : null, diff --git a/packages/vite/src/node/plugins/ssrRequireHook.ts b/packages/vite/src/node/plugins/ssrRequireHook.ts new file mode 100644 index 00000000000000..e3d2023828bfc5 --- /dev/null +++ b/packages/vite/src/node/plugins/ssrRequireHook.ts @@ -0,0 +1,42 @@ +import MagicString from 'magic-string' +import { ResolvedConfig } from '..' +import { Plugin } from '../plugin' + +const impl = `;(function() { + const Module = require("module") + const resolveFilename = Module._resolveFilename + const dedupe = DEDUPE_IDS + Module._resolveFilename = function (request, parent, isMain, options) { + if (request[0] !== "." && request[0] !== "/") { + const parts = request.split("/") + const pkgName = parts[0][0] === "@" ? parts[0] + "/" + parts[1] : parts[0] + if (dedupe.includes(pkgName)) { + // Use this module as the parent. + parent = module + } + } + return resolveFilename(request, parent, isMain, options) + } +})(); +` + +export function ssrRequireHookPlugin(config: ResolvedConfig): Plugin { + return { + name: 'vite:ssr-require-hook', + transform(code, id) { + const moduleInfo = this.getModuleInfo(id) + if (moduleInfo?.isEntry) { + const s = new MagicString(code) + s.prepend( + impl.replace('DEDUPE_IDS', JSON.stringify(config.resolve.dedupe)) + ) + return { + code: s.toString(), + map: s.generateMap({ + source: id + }) + } + } + } + } +}