For the latest content, please read it on GitHub. Also, all issue and star welcomed!
Description of 1.prepack vs Webpack
Today, Facebook opens up a prepack, and it was curious. What is the relationship between it and Webpack? So all kinds of Google, and finally went to the official network to see the following examples. Examples are well understood, but the relationship with Webpack is a bit confusing. Finally found a good use of plug-ins, that is, Prepack-webpack-plugin, which suddenly dawned ~
2. Analysis Prepack-webpack-plugin See Prepack
Below we directly give this plugin's apply source code, because Webpack's plugin all logic is in the Apply method processing. The contents are as follows:
Import Modulefilenamehelpers from' Webpack/lib/modulefilenamehelpers '; import {Rawsource} from' webpack-sources '; import {Prepack} from' Prepack '; Import type {pluginconfigurationtype, userpluginconfigurationtype} from'./types ';ConstDefaultconfiguration = {prepack: {}, Test:/\.js ($|\?) /I};exportdefault classPrepackplugin {configuration:pluginconfigurationtype; Constructor (userconfiguration?: Userpluginconfigurationtype) { This. Configuration = {... defaultconfiguration, ... userconfiguration}; } Apply (Compiler:Object) {ConstConfiguration = This. Configuration; Compiler.plugin (' compilation ', (Compilation) = {Compilation.plugin (' Optimize-chunk-assets ', (chunks, callback) = { for(ConstChunk of chunks) {ConstFiles = chunk.files;//chunk.files Get all the output files generated by the chunk, remember that it is the output file for(Constfile of files) {ConstMatchobjectconfiguration = {Test:configuration.test};if(! Modulefilenamehelpers.matchobject (matchobjectconfiguration, file)) {//Eslint-disable-next-line no-continue Continue; }ConstAsset = Compilation.assets[file];//Get the file itself ConstCode = Asset.source ();//Get the code content of the file ConstPrepackedcode = Prepack (code, {... configuration.prepack, filename:file});//So, here is the processing of the ES5 code after webpack packagingCompilation.assets[file] =NewRawsource (Prepackedcode.code); }} callback (); }); }); }}
First of all, for the webpack of various hook functions can not understand the time to click here. If you are not aware of the properties of individual objects in Webpack, you can click here. Next we have a simple anatomy of the above code:
(1) First look at the front of the For loop
const files = chunk.files; //chunk.files获取该chunk产生的所有的输出文件,记住是输出文件 for (const file of files) { //这里我们只会对该chunk包含的文件中符合test规则的文件进行后续处理 const matchObjectConfiguration = { test: configuration.test }; if (!ModuleFilenameHelpers.matchObject(matchObjectConfiguration, file)) { // eslint-disable-next-line no-continue continue; }}
We also give the Modulefilenamehelpers.matchobject code here:
//Convert a string to a regex function asregexp(test) { if(typeofTest = = ="string") test =New RegExp("^"+ Test.replace (/[-[\]{} () *+?., \\^$|#\s]/g,"\\$&"));returnTest;} Modulefilenamehelpers.matchpart = function matchpart(str, test) { if(!test)return true; Test = asregexp (test);if(Array. IsArray (test)) {returnTest.map (ASREGEXP). Filter ( function(REGEXP) { returnRegexp.test (str); }). length >0; }Else{returnTest.test (str); }}; Modulefilenamehelpers.matchobject = function matchobject(obj, str) { if(obj.test)if(! Modulefilenamehelpers.matchpart (str, obj.test))return false;//Get test, if this file name conforms to the test rule returns true, otherwise false if(Obj.include)if(! Modulefilenamehelpers.matchpart (str, obj.include))return false;if(Obj.exclude)if(Modulefilenamehelpers.matchpart (str, obj.exclude))return false;return true;};
These few lines of code are at a glance, if the resulting file name conforms to the test rule returns true, otherwise false.
(2) We continue to look back. Handling of rules-compliant documents
//如果满足规则我们继续处理~const asset = compilation.assets[file];//获取编译产生的资源const code = asset.source();//获取文件的代码内容const prepackedCode = prepack(code, { ...configuration.prepack, filename: file});//所以,这里是在webpack打包后对ES5代码的处理new RawSource(prepackedCode.code);
Where Asset.source represents the contents of the module, you can click here to view. If our module is an HTML, the content is as follows:
<header class="header">{{text}}</header>
The final package results are:
"header\\">{{text}};‘ }
That's why we have the following code:
compilation.assets[basename] = { function () { return results.source; }, //source是文件的内容,通过fs.readFileAsync完成 function () { return results.size.size; //size通过 fs.statAsync(filename)完成 } }; return basename; });
We have analyzed the previous two lines of code, and we continue to look at the following:
const prepackedCode = prepack(code, { ...configuration.prepack, filename: file});//所以,这里是在webpack打包后对ES5代码的处理new RawSource(prepackedCode.code);
At this point only really to webpack packaging after the code processing, Prepack Nodejs usage can be viewed here. The last code is the operation of our output resources, in the output resources to add a file, the content of the file is Prepack packaged code. One of the Webpack-source content you can click here. According to the official instructions, the object can get all the information such as source code, hash, content size, sourcemap and so on.
Thoroughly understand the relationship between Prepack and Webpack