引言
webpack
@5.69.0
之前使用[email protected]
创建一个taro-react项目之后build了一个weapp项目
最后一步就是启用webpack
把react
代码编译成weapp
webpack入口
在package.json
中可以找到入口文件
这个文件的作用就是引入webpack核心函数
(lib/webpack.js)以及工具文件,抛出整理好之后的webpack核心函数
"main": "lib/index.js",
最终输出:
// lib/index.js // mergeExports是处理fn的,最后输出的就是结果处理的fn module.exports = mergeExports(fn, { // 很多文件的引入 get webpack() { return require("./webpack"); // 核心文件 }, ...... })
mergeExports
// lib/index.js // 第一个参数是对象(函数继承于Fuction,Fuction继承于Object) const mergeExports = (obj, exports) => { // 克隆exports对象,传入这个对象里有很多的文件的引入 const descriptors = Object.getOwnPropertyDescriptors(exports); // 遍历这个对象 for (const name of Object.keys(descriptors)) { const descriptor = descriptors[name]; if (descriptor.get) { const fn = descriptor.get; // 遍历出的属性一个个添加getter到传入的webpack函数 Object.defineProperty(obj, name, { configurable: false, enumerable: true, /** * memoize就是执行了传入的fn返回一个返回执行之后的结果的一个函数 * memoize(fn)等于 * function(){ * return fn(); * } */ get: memoize(fn) }); } else if (typeof descriptor.value === "object") { Object.defineProperty(obj, name, { configurable: false, enumerable: true, writable: false, value: mergeExports({}, descriptor.value) // 递归 }); } else { throw new Error( "Exposed values must be either a getter or an nested object" ); } } // 返回了一个冻结之后的对象,这个对象是个函数,函数里面有很多添加进去的属性方法 return /** @type {A & B} */ (Object.freeze(obj)); };
打印
descriptor
可以得到如下{ get: [Function: get webpack], set: undefined, enumerable: true, configurable: true } ... { value: { ModuleDependency: [Getter], ConstDependency: [Getter], NullDependency: [Getter] }, writable: true, enumerable: true, configurable: true } ...
打印最终返回的
[Function: f] { webpack: [Getter], validate: [Getter], validateSchema: [Getter], version: [Getter], cli: [Getter], AutomaticPrefetchPlugin: [Getter], AsyncDependenciesBlock: [Getter], BannerPlugin: [Getter], Cache: [Getter], Chunk: [Getter], ChunkGraph: [Getter], CleanPlugin: [Getter], Compilation: [Getter], Compiler: [Getter], ConcatenationScope: [Getter], ContextExclusionPlugin: [Getter], ContextReplacementPlugin: [Getter], DefinePlugin: [Getter], DelegatedPlugin: [Getter], Dependency: [Getter], DllPlugin: [Getter], DllReferencePlugin: [Getter], DynamicEntryPlugin: [Getter], EntryOptionPlugin: [Getter], EntryPlugin: [Getter], EnvironmentPlugin: [Getter], EvalDevToolModulePlugin: [Getter], EvalSourceMapDevToolPlugin: [Getter], ExternalModule: [Getter], ExternalsPlugin: [Getter], Generator: [Getter], HotUpdateChunk: [Getter], HotModuleReplacementPlugin: [Getter], IgnorePlugin: [Getter], JavascriptModulesPlugin: [Getter], LibManifestPlugin: [Getter], LibraryTemplatePlugin: [Getter], LoaderOptionsPlugin: [Getter], LoaderTargetPlugin: [Getter], Module: [Getter], ModuleFilenameHelpers: [Getter], ModuleGraph: [Getter], ModuleGraphConnection: [Getter], NoEmitOnErrorsPlugin: [Getter], NormalModule: [Getter], NormalModuleReplacementPlugin: [Getter], MultiCompiler: [Getter], Parser: [Getter], PrefetchPlugin: [Getter], ProgressPlugin: [Getter], ProvidePlugin: [Getter], RuntimeGlobals: [Getter], RuntimeModule: [Getter], SingleEntryPlugin: [Getter], SourceMapDevToolPlugin: [Getter], Stats: [Getter], Template: [Getter], UsageState: [Getter], WatchIgnorePlugin: [Getter], WebpackError: [Getter], WebpackOptionsApply: [Getter], WebpackOptionsDefaulter: [Getter], WebpackOptionsValidationError: [Getter], ValidationError: [Getter], cache: { MemoryCachePlugin: [Getter] }, config: { getNormalizedWebpackOptions: [Getter], applyWebpackOptionsDefaults: [Getter] }, dependencies: { ModuleDependency: [Getter], ConstDependency: [Getter], NullDependency: [Getter] }, ids: { ChunkModuleIdRangePlugin: [Getter], NaturalModuleIdsPlugin: [Getter], OccurrenceModuleIdsPlugin: [Getter], NamedModuleIdsPlugin: [Getter], DeterministicChunkIdsPlugin: [Getter], DeterministicModuleIdsPlugin: [Getter], NamedChunkIdsPlugin: [Getter], OccurrenceChunkIdsPlugin: [Getter], HashedModuleIdsPlugin: [Getter] }, javascript: { EnableChunkLoadingPlugin: [Getter], JavascriptModulesPlugin: [Getter], JavascriptParser: [Getter] }, optimize: { AggressiveMergingPlugin: [Getter], AggressiveSplittingPlugin: [Getter], InnerGraph: [Getter], LimitChunkCountPlugin: [Getter], MinChunkSizePlugin: [Getter], ModuleConcatenationPlugin: [Getter], RealContentHashPlugin: [Getter], RuntimeChunkPlugin: [Getter], SideEffectsFlagPlugin: [Getter], SplitChunksPlugin: [Getter] }, runtime: { GetChunkFilenameRuntimeModule: [Getter], LoadScriptRuntimeModule: [Getter] }, prefetch: { ChunkPrefetchPreloadPlugin: [Getter] }, web: { FetchCompileAsyncWasmPlugin: [Getter], FetchCompileWasmPlugin: [Getter], JsonpChunkLoadingRuntimeModule: [Getter], JsonpTemplatePlugin: [Getter] }, webworker: { WebWorkerTemplatePlugin: [Getter] }, node: { NodeEnvironmentPlugin: [Getter], NodeSourcePlugin: [Getter], NodeTargetPlugin: [Getter], NodeTemplatePlugin: [Getter], ReadFileCompileWasmPlugin: [Getter] }, electron: { ElectronTargetPlugin: [Getter] }, wasm: { AsyncWebAssemblyModulesPlugin: [Getter] }, library: { AbstractLibraryPlugin: [Getter], EnableLibraryPlugin: [Getter] }, container: { ContainerPlugin: [Getter], ContainerReferencePlugin: [Getter], ModuleFederationPlugin: [Getter], scope: [Getter] }, sharing: { ConsumeSharedPlugin: [Getter], ProvideSharedPlugin: [Getter], SharePlugin: [Getter], scope: [Getter] }, debug: { ProfilingPlugin: [Getter] }, util: { createHash: [Getter], comparators: [Getter], runtime: [Getter], serialization: [Getter], cleverMerge: [Getter], LazySet: [Getter] }, sources: [Getter], experiments: { schemes: { HttpUriPlugin: [Getter] }, ids: { SyncModuleIdsPlugin: [Getter] } } }
fn:
// lib/index.js // fn懒加载出来的webpack核心函数 const fn = lazyFunction(() => require("./webpack"));
lazyFunction:这里我们可以知道
webpack核心函数(lib/webpack)
是怎么接受参数的// lib/index.js const lazyFunction = factory => { // 和mergeExports一样返回一个返回执行了factory后的函数 const fac = memoize(factory); // fac函数一个函数 const f = ( // 这里args就是我们传入的webpack配置参数 (...args) => { /** * fac() 等于 factory() * fac()(...args) 等于 factory()(...args) * factory 等于 () => require("./webpack") * require("./webpack")(...args) */ return fac()(...args); } ); return (f);// 最后返回f这个函数,在mergeExports里getter添加之后作为入口抛出,在webpack启动器里传入webpack配置参数执行 };
webpack.js
lib/webpack.js