vite 是如何找到包入口的

2024-04-20

简单来说就是 找包的 package.json 判断有没有 exports 字段,用 key 去匹配,如果成功使用exports定义的文件,如没有就回退,找 main 字段


function resolvePackageEntry(id, { dir, data, setResolvedCache, getResolvedCache }, targetWeb, options) {
    const { file: idWithoutPostfix, postfix } = splitFileAndPostfix(id);
    // 分离文件名和后缀
    const cached = getResolvedCache('.', targetWeb);
    if (cached) {
        return cached + postfix;
    }
    try {
        let entryPoint;
        // 预定入口
        // resolve exports field with highest priority
        // using https://github.com/lukeed/resolve.exports
        if (data.exports) {
            // 找 exports 是高优先级
            entryPoint = resolveExportsOrImports(data, '.', options, targetWeb, 'exports');
        }
        // fallback to mainFields if still not resolved
        if (!entryPoint) {
            for (const field of options.mainFields) {
                if (field === 'browser') {
                    if (targetWeb) {
                        entryPoint = tryResolveBrowserEntry(dir, data, options);
                        if (entryPoint) {
                            break;
                        }
                    }
                }
                else if (typeof data[field] === 'string') {
                    entryPoint = data[field];
                    break;
                }
            }
        }
        entryPoint ||= data.main;
        // try default entry when entry is not define
        // https://nodejs.org/api/modules.html#all-together
        const entryPoints = entryPoint
            ? [entryPoint]
            : ['index.js', 'index.json', 'index.node'];
        for (let entry of entryPoints) {
            // make sure we don't get scripts when looking for sass
            let skipPackageJson = false;
            if (options.mainFields[0] === 'sass' &&
                !options.extensions.includes(path$o.extname(entry))) {
                entry = '';
                skipPackageJson = true;
            }
            else {
                // resolve object browser field in package.json
                const { browser: browserField } = data;
                if (targetWeb &&
                    options.mainFields.includes('browser') &&
                    isObject$1(browserField)) {
                    entry = mapWithBrowserField(entry, browserField) || entry;
                }
            }
            const entryPointPath = path$o.join(dir, entry);
            const resolvedEntryPoint = tryFsResolve(entryPointPath, options, true, true, skipPackageJson);
            if (resolvedEntryPoint) {
                debug$f?.(`[package entry] ${colors$1.cyan(idWithoutPostfix)} -> ${colors$1.dim(resolvedEntryPoint)}${postfix !== '' ? ` (postfix: ${postfix})` : ''}`);
                setResolvedCache('.', resolvedEntryPoint, targetWeb);
                return resolvedEntryPoint + postfix;
            }
        }
    }
    catch (e) {
        packageEntryFailure(id, e.message);
    }
    packageEntryFailure(id);
}


function resolveExportsOrImports(pkg, key, options, targetWeb, type) {
    const additionalConditions = new Set(options.overrideConditions || [
        'production',
        'development',
        'module',
        ...options.conditions,
    ]);
    const conditions = [...additionalConditions].filter((condition) => {
        switch (condition) {
            case 'production':
                return options.isProduction;
            case 'development':
                return !options.isProduction;
        }
        return true;
    });
    const fn = type === 'imports' ? f : o;
    const result = fn(pkg, key, {
        browser: targetWeb && !additionalConditions.has('node'),
        require: options.isRequire && !additionalConditions.has('import'),
        conditions,
    });
    return result ? result[0] : undefined;
}
copyright ©2019-2024 shenzhen
粤ICP备20041170号-1