webpack 核心编译器 十一 节

addChunkInGroup(groupOptions, module, loc, request)

  • 作用 :添加或获取一个代码块组(ChunkGroup)。

  • 逻辑

    • 如果提供了 groupOptions.name,则检查是否已经存在相同名称的代码块组,若存在则直接返回。
    • 如果不存在,则创建新的 ChunkGroup,并关联一个 Chunk,然后存储该 ChunkGroup
    • 如果 module 传入,则将 module 作为 ChunkGroup 的来源信息。
js 复制代码
/**
 * 如果传递了 `module`,则 `loc` 和 `request` 也必须传递。
 * @param {string | ChunkGroupOptions} groupOptions 代码块组的选项
 * @param {Module=} module 引用该代码块组的模块
 * @param {DependencyLocation=} loc 代码块组在模块内部的引用位置
 * @param {string=} request 引用该代码块组的请求
 * @returns {ChunkGroup} 新的或已存在的代码块组
 */
addChunkInGroup(groupOptions, module, loc, request) {
    if (typeof groupOptions === "string") {
        groupOptions = { name: groupOptions };
    }
    const name = groupOptions.name;

    if (name) {
        const chunkGroup = this.namedChunkGroups.get(name);
        if (chunkGroup !== undefined) {
            if (module) {
                chunkGroup.addOrigin(
                    module,
                    /** @type {DependencyLocation} */
                    (loc),
                    request
                );
            }
            return chunkGroup;
        }
    }
    const chunkGroup = new ChunkGroup(groupOptions);
    if (module)
        chunkGroup.addOrigin(
            module,
            /** @type {DependencyLocation} */
            (loc),
            request
        );
    const chunk = this.addChunk(name);

    connectChunkGroupAndChunk(chunkGroup, chunk);

    this.chunkGroups.push(chunkGroup);
    if (name) {
        this.namedChunkGroups.set(name, chunkGroup);
    }
    return chunkGroup;
}

addAsyncEntrypoint(options, module, loc, request)

  • 作用 :添加或获取一个异步入口点(Entrypoint)。

  • 逻辑

    • 如果 options.name 存在,则检查是否已有同名的 Entrypoint,若存在则直接返回,否则抛出错误(若存在的是其他类型的 ChunkGroup)。
    • 创建一个新的 Chunk,并设置 filenameTemplate(如果有提供)。
    • 创建新的 Entrypoint,并将其 runtimeChunkentrypointChunk 设为 chunk
    • 关联 EntrypointChunk,存入相关数据结构中。
    • 如果 module 传入,则添加来源信息。
  • 返回值 :返回新的或已存在的 Entrypoint

js 复制代码
/**
 * @param {EntryOptions} options 入口点的选项
 * @param {Module} module 引用该代码块组的模块
 * @param {DependencyLocation} loc 代码块组在模块内部的引用位置
 * @param {string} request 引用该代码块组的请求
 * @returns {Entrypoint} 新的或已存在的入口点
 */
addAsyncEntrypoint(options, module, loc, request) {
    const name = options.name;
    if (name) {
        const entrypoint = this.namedChunkGroups.get(name);
        if (entrypoint instanceof Entrypoint) {
            if (entrypoint !== undefined) {
                if (module) {
                    entrypoint.addOrigin(module, loc, request);
                }
                return entrypoint;
            }
        } else if (entrypoint) {
            throw new Error(
                `无法添加名称为 '${name}' 的异步入口点,因为已经存在一个具有相同名称的代码块组`
            );
        }
    }
    const chunk = this.addChunk(name);
    if (options.filename) {
        chunk.filenameTemplate = options.filename;
    }
    const entrypoint = new Entrypoint(options, false);
    entrypoint.setRuntimeChunk(chunk);
    entrypoint.setEntrypointChunk(chunk);
    if (name) {
        this.namedChunkGroups.set(name, entrypoint);
    }
    this.chunkGroups.push(entrypoint);
    this.asyncEntrypoints.push(entrypoint);
    connectChunkGroupAndChunk(entrypoint, chunk);
    if (module) {
        entrypoint.addOrigin(module, loc, request);
    }
    return entrypoint;
}

addChunk(name)

  • 作用 :创建或获取一个 Chunk(代码块)。

  • 逻辑

    • 如果 name 存在,则检查是否已有同名的 Chunk,若存在则直接返回。
    • 否则创建新的 Chunk,并存储到 chunksnamedChunks 结构中(如果开启了 backCompat,则关联 ChunkGraph)。
  • 返回值 :返回新的或已存在的 Chunk

js 复制代码
/**
 * 该方法首先检查是否提供了新的代码块名称,
 * 如果提供了名称,则会先检查是否已经存在同名的代码块,并复用该代码块。
 * @param {string=} name 可选的代码块名称
 * @returns {Chunk} 创建一个代码块(在 seal 事件期间调用)
 */
addChunk(name) {
    if (name) {
        const chunk = this.namedChunks.get(name);
        if (chunk !== undefined) {
            return chunk;
        }
    }
    const chunk = new Chunk(name, this._backCompat);
    this.chunks.add(chunk);
    if (this._backCompat)
        ChunkGraph.setChunkGraphForChunk(chunk, this.chunkGraph);
    if (name) {
        this.namedChunks.set(name, chunk);
    }
    return chunk;
}

assignDepth(module) (已废弃)

  • 作用:为模块分配深度(深度表示模块在依赖图中的层级)。

  • 逻辑

    • 使用 BFS 遍历模块依赖关系,并根据深度信息更新模块图(moduleGraph)。
    • 如果某个模块的深度值可以更新,则加入队列,继续遍历其依赖项。
  • 返回值 :无返回值(void),仅修改 moduleGraph 的深度信息。

js 复制代码
/**
 * @deprecated
 * @param {Module} module 要分配深度的模块
 * @returns {void}
 */
assignDepth(module) {
    const moduleGraph = this.moduleGraph;

    const queue = new Set([module]);
    /** @type {number} */
    let depth;

    moduleGraph.setDepth(module, 0);

    /**
     * @param {Module} module 要处理的模块
     * @returns {void}
     */
    const processModule = module => {
        if (!moduleGraph.setDepthIfLower(module, depth)) return;
        queue.add(module);
    };

    for (module of queue) {
        queue.delete(module);
        depth = /** @type {number} */ (moduleGraph.getDepth(module)) + 1;

        for (const connection of moduleGraph.getOutgoingConnections(module)) {
            const refModule = connection.module;
            if (refModule) {
                processModule(refModule);
            }
        }
    }
}
相关推荐
范文杰3 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪3 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪3 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy4 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom4 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom4 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom4 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom5 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom5 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试
LaoZhangAI6 小时前
2025最全GPT-4o图像生成API指南:官方接口配置+15个实用提示词【保姆级教程】
前端