Skip to content

Commit dbb4652

Browse files
committed
perf(qwik): remove vendor scan at build start
1 parent 97c0d08 commit dbb4652

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',
@@ -715,90 +700,6 @@ export async function render(document, rootNode, opts) {
715700
}`;
716701
}
717702

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

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)