Preface
After webpack initialization is complete, it will pass through the options.watch
to determine whether to open the watch, if open watch
will be executed watch
process, if it is run
, will perform run
process, focus only on the main line of this series, we directly from run
start, watch
interested students can study on their own research
compiler.run()
Look directly at the core code
const run = () => {
this.hooks.beforeRun.callAsync(this, err => {
if (err) return finalCallback(err);
this.hooks.run.callAsync(this, err => {
if (err) return finalCallback(err);
this.readRecords(err => {
if (err) return finalCallback(err);
this.compile(onCompiled);
});
});
});
};
To put it simply, it did just a few things.
- Trigger the callback of
beforeRun
- Trigger the callback of
run
- Then adjust
this.readRecords
- In
readRecords
call a callback inthis.compile(onCompiled)
start the compilation
Let's see step by stepbeforeRun
before triggers in NodeEnvironmentPlugin
registered in beforeRun hook, this plugin will determine inputFileSystem
whether configured, if no configuration is performed purge
clean-up methods.
readRecords
reads some statistical information, because there is no configuration recordsInputPath
, will here this.records
initially {}
.
Create a compilation instance
Then execute to the compiler.compiler()
method.compiler.compiler
method runs through the entire compilation process. First, compiler
instantiates a compilation
.
compile(callback) {
const params = this.newCompilationParams();
this.hooks.beforeCompile.callAsync(params, err => {
if (err) return callback(err);
this.hooks.compile.call(params);
const compilation = this.newCompilation(params);
// do something
}
}
Get parameters
newCompilationParams() {
const params = {
normalModuleFactory: this.createNormalModuleFactory(),
contextModuleFactory: this.createContextModuleFactory()
};
return params;
}
There are two parameters, one is NormalModuleFactory
example, one ContextModuleFactory
instance. ContextModuleFactory
in the compilation. I will skip it for the time being. Then I will make a break to see if I can walk in. Here we mainly look at NormalModuleFactory
.
NormalModuleFactory
NormalModuleFactory
look at the parameters of instantiating 0616982641093b
const normalModuleFactory = new NormalModuleFactory({
context: this.options.context,
fs: this.inputFileSystem,
resolverFactory: this.resolverFactory,
options: this.options.module,
associatedObjectForCache: this.root,
layers: this.options.experiments.layers
});
Pay attention to resolverFactory
here, it will be used in the future.
Next, new NormalModuleFactory
’s look at what happened at 06169826410960
constructor({
context,
fs,
resolverFactory,
options,
associatedObjectForCache,
layers = false
}) {
super();
this.hooks = 定义了很多hooks
this.resolverFactory = resolverFactory;
this.ruleSet = ruleSetCompiler.compile([
{
rules: options.defaultRules
},
{
rules: options.rules
}
]);
this.context = context || "";
this.fs = fs;
this._globalParserOptions = options.parser;
this._globalGeneratorOptions = options.generator;
/** @type {Map<string, WeakMap<Object, TODO>>} */
this.parserCache = new Map();
/** @type {Map<string, WeakMap<Object, Generator>>} */
this.generatorCache = new Map();
/** @type {Set<Module>} */
this._restoredUnsafeCacheEntries = new Set();
const cacheParseResource = parseResource.bindCache(
associatedObjectForCache
);
this.hooks.factorize.tapAsync(
// do something
);
this.hooks.resolve.tapAsync(
// dosomething
);
}
Maybe I think it’s too long to read, I’ll just translate it for everyone.
- A lot of internal hooks are defined, such as the two reslover and factorize registered at the end
- A lot of variables needed to build a module are defined, so I won't go into details here.
- Two internal hooks of
NormalModuleFactory
are registered at the same time. Will be called by the compilation object at the right time
new NormalModuleFactory()
after, triggering the Compiler normalModuleFactory
hook
this.hooks.normalModuleFactory.call(normalModuleFactory);
Continue to trigger the hook callback
Then trigger the beforeCompile
and compile
hooks.
Start instantiating
newCompilation(params) {
const compilation = this.createCompilation(params); //这里简单理解为new 了一下,
compilation.name = this.name;
compilation.records = this.records;
this.hooks.thisCompilation.call(compilation, params);
this.hooks.compilation.call(compilation, params);
return compilation;
}
To classify it, this function does two things.
- new Compilation, assign a little more value
Register two hooks
new Compilation internal details
The Compilation object represents the current module resources, compiled resources, changed files, and status information of the tracked dependencies, and represents the construction of a resource. There are too many constructor codes so I won't post it here, you can go and see by yourself.
To summarize briefly, it is
- A lot of internal hooks are registered in compilation.
- Initialized some of its own properties
- Instantiate
MainTemplate
,ChunkTemplate
,HotUpdateChunkTemplate
,RuntimeTemplate
,ModuleTemplate
. Used to provide compiled templates
Hook call after instantiation
this.hooks.thisCompilation.call(compilation, params);
this.hooks.compilation.call(compilation, params);
compilation
hook will call the method registered in entryplugin before.
Dependency modules will be added to dependencyFactories.
compilation.dependencyFactories.set(
EntryDependency,
normalModuleFactory
);
Maybe you are curious, why are there two hooks here? The reason is related to the sub-compiler. Create a child compiler in the createChildCompiler method of Compiler, where thisCompilation hook will not be copied, but compilation will be copied.
The sub-compiler has a complete module and chunk generation. Through the sub-compiler, a core build process can be executed independently of the parent compiler, and some required modules and chunks can be additionally generated.
Finish
So far, the description of the process of building objects compiler
objects and describes the compilation process compilation
object has been created. In the next article we enter the build process.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。