webpack源码分析(八)

先看上一节的_create函数

	_create(type, resolveOptionsWithDepType) {
		const originalResolveOptions = { ...resolveOptionsWithDepType };
		const resolveOptions = convertToResolveOptions(
			this.hooks.resolveOptions.for(type).call(resolveOptionsWithDepType)
		);
		const resolver = Factory.createResolver(resolveOptions)
		const childCache = new WeakMap();
		resolver.withOptions = options => {
			const cacheEntry = childCache.get(options);
			if (cacheEntry !== undefined) return cacheEntry;
			const mergedOptions = cachedCleverMerge(originalResolveOptions, options);
			const resolver = this.get(type, mergedOptions);
			childCache.set(options, resolver);
			return resolver;
		};
		this.hooks.resolver.for(type).call(resolver, resolveOptions,originalResolveOptions);
		return resolver;
	}

先来一行一行过,第一行直接跳过,{...object}

看第二行

this.hooks.resolveOptions.for(type).call(resolveOptionsWithDepType)

其实这就是调用了方法

在之前我们说的WebpackOptionsApply.process()这个方法赋值了几个钩子函数

先说一下,一共赋值了3个钩子,normal,context,loader,先不说这三种都是干什么的,因为说了大概率现在也不懂,后续会用到,自然就懂了。

这里说一下normal的吧,三个其实都差不多,说一个就阔以了。

compiler.resolverFactory.hooks.resolveOptions

.for("normal")

.tap("WebpackOptionsApply", resolveOptions => {

resolveOptions = cleverMerge(options.resolve, resolveOptions);

resolveOptions.fileSystem = compiler.inputFileSystem;

return resolveOptions;

});

其实就是,获取resolveOption的值而已

const resolver = Factory.createResolver(resolveOptions)

const Factory = require("enhanced-resolve").ResolverFactory;

const resolver = Factory.createResolver(resolveOptions);

先跳过这个,先把最简单的代码讲了

const childCache = new WeakMap();

resolver.withOptions = options => {

const cacheEntry = childCache.get(options);

if (cacheEntry !== undefined) return cacheEntry;

const mergedOptions = cachedCleverMerge(originalResolveOptions, options);

const resolver = this.get(type, mergedOptions);

childCache.set(options, resolver);

return resolver;

};

一看就知道了,其实就是在resolver对象上面增加_create方法,这样就可以通过resolver,定义不同配置的新的resolver对象。

this.hooks.resolver.for(type).call(resolver, resolveOptions, originalResolveOptions);

这个插件会被调用,webpack有个插件叫做,ResolverCachePlugin看名字就知道是干什么的,肯定是增加缓存的。

这个插件我就说一下是干啥用的吧,不多介绍了,他在resolver阶段,注册了resolver.hooks.resolve.tapAsync,注册了别的生命周期的插件,并且优先级是最低的,保证是最后执行的。(这里用不到,如果后续用到,就会讲,现在就是在他的钩子里注册别人的钩子没必要讲)

回归正题

所以我上一节说的核心就是const resolver = Factory.createResolver(resolveOptions),现在看没一点问题。

const Factory = require("enhanced-resolve").ResolverFactory;

const resolver = Factory.createResolver(resolveOptions);

enhanced-resolve 一个非常熟悉的东西,我们之前的CachedInputFileSystem就是内部的。

那我们来说一下这个ResolverFactory

我们先来举例一个demo吧。

const { ResolverFactory, CachedInputFileSystem } = require("enhanced-resolve");

const fs = require("fs");

const path = require("path");

const myResolver = ResolverFactory.createResolver({

fileSystem: new CachedInputFileSystem(fs, 4000),

extensions: [".json", ".js", ".ts"]

});

const context = {};

const resolveContext = {};

const lookupStartPath = path.resolve(__dirname);

const request = "./a";

myResolver.resolve( context, lookupStartPath, request, resolveContext,

(err, path, result) => { console.log("createResolve path: ", path); }

);

我们只需要在同级创建一个a.js即可,不需要输入内容。

➜ node xx.js

最后会输出createResolve path: xxxx/a.js

通过这个demo,我们就知道了,原来 ResolverFactory,和名字一样,就是实现一个resolve功能。

这节就讲到这里,本章知道了ResolverFactory是什么,并给了一个demo,可以拿到绝对路径

前端技术专栏分享 文章被收录于专栏

1. 包含常规前端面试题解析,和源码分析 2. 从0-1深入浅出理解前端相关技术栈

全部评论

相关推荐

2024-12-07 21:21
东北大学 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务