Skip to content

Commit 47a0b13

Browse files
committed
perf(qwik): remove vendor scan at build start
1 parent a764cf4 commit 47a0b13

File tree

3 files changed

+8
-115
lines changed

3 files changed

+8
-115
lines changed

.changeset/lemon-dingos-dance.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@builder.io/qwik': minor
3+
---
4+
5+
BREAKING: (slightly) Qwik will no longer scan all modules at build start to detect Qwik modules. Instead, a runtime check is done to prevent duplicate core imports. If you get a runtime error, you need to fix your build settings so they don't externalize qwik-related libraries.

packages/qwik/src/optimizer/src/plugins/vite.ts

Lines changed: 2 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import type {
55
GlobalInjections,
66
Optimizer,
77
OptimizerOptions,
8-
OptimizerSystem,
98
QwikManifest,
109
TransformModule,
1110
} from '../types';
@@ -25,7 +24,6 @@ import {
2524
type NormalizedQwikPluginOptions,
2625
type QwikBuildMode,
2726
type QwikBuildTarget,
28-
type QwikPackages,
2927
type QwikPluginOptions,
3028
} from './plugin';
3129
import { createRollupError, normalizeRollupOutputOptions } from './rollup';
@@ -96,7 +94,6 @@ export function qwikVite(qwikViteOpts: QwikVitePluginOptions = {}): any {
9694
async config(viteConfig, viteEnv) {
9795
await qwikPlugin.init();
9896

99-
const sys = qwikPlugin.getSys();
10097
const path = qwikPlugin.getPath();
10198

10299
let target: QwikBuildTarget;
@@ -149,8 +146,6 @@ export function qwikVite(qwikViteOpts: QwikVitePluginOptions = {}): any {
149146
if (input && typeof input === 'string') {
150147
input = [input];
151148
}
152-
const shouldFindVendors =
153-
!qwikViteOpts.disableVendorScan && (target !== 'lib' || viteCommand === 'serve');
154149
viteAssetsDir = viteConfig.build?.assetsDir;
155150
const useAssetsDir = target === 'client' && !!viteAssetsDir && viteAssetsDir !== '_astro';
156151
const pluginOpts: QwikPluginOptions = {
@@ -208,8 +203,6 @@ export function qwikVite(qwikViteOpts: QwikVitePluginOptions = {}): any {
208203
clientDevInput = qwikPlugin.normalizePath(clientDevInput);
209204
}
210205

211-
const vendorRoots = shouldFindVendors ? await findQwikRoots(sys, sys.cwd()) : [];
212-
const vendorIds = vendorRoots.map((v) => v.id);
213206
const isDevelopment = buildMode === 'development';
214207
const qDevKey = 'globalThis.qDev';
215208
const qTestKey = 'globalThis.qTest';
@@ -221,17 +214,11 @@ export function qwikVite(qwikViteOpts: QwikVitePluginOptions = {}): any {
221214

222215
const updatedViteConfig: UserConfig = {
223216
ssr: {
224-
noExternal: [
225-
QWIK_CORE_ID,
226-
QWIK_CORE_INTERNAL_ID,
227-
QWIK_CORE_SERVER,
228-
QWIK_BUILD_ID,
229-
...vendorIds,
230-
],
217+
noExternal: [QWIK_CORE_ID, QWIK_CORE_INTERNAL_ID, QWIK_CORE_SERVER, QWIK_BUILD_ID],
231218
},
232219
envPrefix: ['VITE_', 'PUBLIC_'],
233220
resolve: {
234-
dedupe: [...DEDUPE, ...vendorIds],
221+
dedupe: [...DEDUPE],
235222
conditions: buildMode === 'production' && target === 'client' ? ['min'] : [],
236223
alias: {
237224
'@builder.io/qwik': '@qwik.dev/core',
@@ -264,8 +251,6 @@ export function qwikVite(qwikViteOpts: QwikVitePluginOptions = {}): any {
264251
QWIK_JSX_DEV_RUNTIME_ID,
265252
QWIK_BUILD_ID,
266253
QWIK_CLIENT_MANIFEST_ID,
267-
// Sadly we can't specify **/*.qwik.*, so we need to specify each one
268-
...vendorIds,
269254
// v1 imports, they are removed during transform but vite doesn't know that
270255
'@builder.io/qwik',
271256
'@builder.io/qwik-city',
@@ -714,90 +699,6 @@ export async function render(document, rootNode, opts) {
714699
}`;
715700
}
716701

717-
async function findDepPkgJsonPath(sys: OptimizerSystem, dep: string, parent: string) {
718-
const fs: typeof import('fs') = await sys.dynamicImport('node:fs');
719-
let root = parent;
720-
while (root) {
721-
const pkg = sys.path.join(root, 'node_modules', dep, 'package.json');
722-
try {
723-
await fs.promises.access(pkg);
724-
// use 'node:fs' version to match 'vite:resolve' and avoid realpath.native quirk
725-
// https://github.com/sveltejs/vite-plugin-svelte/issues/525#issuecomment-1355551264
726-
return fs.promises.realpath(pkg);
727-
} catch {
728-
//empty
729-
}
730-
const nextRoot = sys.path.dirname(root);
731-
if (nextRoot === root) {
732-
break;
733-
}
734-
root = nextRoot;
735-
}
736-
return undefined;
737-
}
738-
739-
const findQwikRoots = async (
740-
sys: OptimizerSystem,
741-
packageJsonDir: string
742-
): Promise<QwikPackages[]> => {
743-
const paths = new Map<string, string>();
744-
if (sys.env === 'node' || sys.env === 'bun') {
745-
const fs: typeof import('fs') = await sys.dynamicImport('node:fs');
746-
let prevPackageJsonDir: string | undefined;
747-
do {
748-
try {
749-
const data = await fs.promises.readFile(sys.path.join(packageJsonDir, 'package.json'), {
750-
encoding: 'utf-8',
751-
});
752-
753-
try {
754-
const packageJson = JSON.parse(data);
755-
const dependencies = packageJson['dependencies'];
756-
const devDependencies = packageJson['devDependencies'];
757-
758-
const packages: string[] = [];
759-
if (typeof dependencies === 'object') {
760-
packages.push(...Object.keys(dependencies));
761-
}
762-
if (typeof devDependencies === 'object') {
763-
packages.push(...Object.keys(devDependencies));
764-
}
765-
766-
const basedir = sys.cwd();
767-
await Promise.all(
768-
packages.map(async (id) => {
769-
const pkgJsonPath = await findDepPkgJsonPath(sys, id, basedir);
770-
if (pkgJsonPath) {
771-
const pkgJsonContent = await fs.promises.readFile(pkgJsonPath, 'utf-8');
772-
const pkgJson = JSON.parse(pkgJsonContent);
773-
const qwikPath = pkgJson['qwik'];
774-
if (!qwikPath) {
775-
return;
776-
}
777-
// Support multiple paths
778-
const allPaths = Array.isArray(qwikPath) ? qwikPath : [qwikPath];
779-
for (const p of allPaths) {
780-
paths.set(
781-
await fs.promises.realpath(sys.path.resolve(sys.path.dirname(pkgJsonPath), p)),
782-
id
783-
);
784-
}
785-
}
786-
})
787-
);
788-
} catch (e) {
789-
console.error(e);
790-
}
791-
} catch {
792-
// ignore errors if package.json not found
793-
}
794-
prevPackageJsonDir = packageJsonDir;
795-
packageJsonDir = sys.path.dirname(packageJsonDir);
796-
} while (packageJsonDir !== prevPackageJsonDir);
797-
}
798-
return Array.from(paths).map(([path, id]) => ({ path, id }));
799-
};
800-
801702
export const isNotNullable = <T>(v: T): v is NonNullable<T> => {
802703
return v != null;
803704
};

starters/dev-server.ts

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,6 @@ const appNames = readdirSync(startersAppsDir).filter(
4343
(p) => statSync(join(startersAppsDir, p)).isDirectory() && p !== "base",
4444
);
4545

46-
const rootDir = resolve(__dirname, "..");
47-
const packagesDir = resolve(rootDir, "packages");
48-
const qwikRouterMjs = join(packagesDir, "qwik-router", "lib", "index.qwik.mjs");
49-
5046
/** Used when qwik-router server is enabled */
5147
const qwikRouterVirtualEntry = "@router-ssr-entry";
5248
const entrySsrFileName = "entry.ssr.tsx";
@@ -198,16 +194,7 @@ export {
198194
plugins: [
199195
...plugins,
200196
optimizer.qwikVite({
201-
/**
202-
* normally qwik finds qwik-router via package.json but we don't want that
203-
* because it causes it to try to lookup the special qwik router imports
204-
* even when we're not actually importing qwik-router
205-
*/
206-
disableVendorScan: true,
207-
vendorRoots: enableRouterServer ? [qwikRouterMjs] : [],
208-
entryStrategy: {
209-
type: "segment",
210-
},
197+
entryStrategy: { type: "segment" },
211198
client: {
212199
manifestOutput(manifest) {
213200
clientManifest = manifest;

0 commit comments

Comments
 (0)