9-Brief analysis of NodeEnvironmentPlugin module for webpack source

Introducing the construction of Compiler is rather interesting. It's better to go ahead and explain it when you use Compiler.

This section focuses on this line of code:

// No matter here
compiler = new Compiler();
compiler.context = options.context;
compiler.options = options;
// Look here
new NodeEnvironmentPlugin().apply(compiler);

This constructs a NodeEnvironmentPlugin object and calls apply to manipulate the compiler.

Flowchart:

The module source code is as follows:

"use strict";

const NodeWatchFileSystem = require("./NodeWatchFileSystem");
const NodeOutputFileSystem = require("./NodeOutputFileSystem");
const NodeJsInputFileSystem = require("enhanced-resolve/lib/NodeJsInputFileSystem");
const CachedInputFileSystem = require("enhanced-resolve/lib/CachedInputFileSystem");

class NodeEnvironmentPlugin {
    apply(compiler) {
        // File system where input can be cached
        compiler.inputFileSystem = new CachedInputFileSystem(new NodeJsInputFileSystem(), 60000);
        const inputFileSystem = compiler.inputFileSystem;
        // Output File System
        compiler.outputFileSystem = new NodeOutputFileSystem();
        // Monitor File System
        compiler.watchFileSystem = new NodeWatchFileSystem(compiler.inputFileSystem);
        // Add Event Flow before-run
        compiler.plugin("before-run", (compiler, callback) => {
            if (compiler.inputFileSystem === inputFileSystem)
                inputFileSystem.purge();
            callback();
        });
    }
}
module.exports = NodeEnvironmentPlugin;

Apart from adding event streams, the rest of the steps are to mount the node's fs file system on the compiler object. Detailed API usage can be seen on the nodejs website:https://nodejs.org/dist/latest-v8.x/docs/api/

This is just an introduction:

NodeJsInputFileSystem

var fs = require("graceful-fs");

module.exports = NodeJsInputFileSystem;
// Get file information
NodeJsInputFileSystem.prototype.stat = fs.stat.bind(fs);
// Read directory contents
NodeJsInputFileSystem.prototype.readdir = function readdir(path, callback) {
    // files Is not included in the catalog '.' and '..' Array of file names
    fs.readdir(path, function(err, files) {
        callback(err, files && files.map(function(file) {
            // For file names NFC Format
            return file.normalize ? file.normalize("NFC") : file;
        }));
    });
};
// read file
NodeJsInputFileSystem.prototype.readFile = fs.readFile.bind(fs);
// Read Links
NodeJsInputFileSystem.prototype.readlink = fs.readlink.bind(fs);
// Synchronization method
NodeJsInputFileSystem.prototype.statSync = fs.statSync.bind(fs);
NodeJsInputFileSystem.prototype.readdirSync = function readdirSync(path) {/**/};
NodeJsInputFileSystem.prototype.readFileSync = fs.readFileSync.bind(fs);
NodeJsInputFileSystem.prototype.readlinkSync = fs.readlinkSync.bind(fs);

As you can see, here is just a bind binding for some of the methods introduced in graceful-js. Take a look at what graceful-fs is about:

var fs = require('fs')

// ...Tool method

module.exports = patch(require('./fs.js'))
if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH) {
    module.exports = patch(fs)
}

module.exports.close = fs.close = (function(fs$close) { /*...*/ })(fs.close)

module.exports.closeSync = fs.closeSync = (function(fs$closeSync) { /*...*/ })(fs.closeSync)

function patch(fs) {
    // fs Method Secondary Encapsulation
    return fs
}

Like the name, a patch is called internally to encapsulate the fs module twice, making it more'elegant'.

 

NodeOutputFileSystem

"use strict";

const fs = require("fs");
const path = require("path");
const mkdirp = require("mkdirp");

class NodeOutputFileSystem {
    constructor() {
        // New Multilevel Folder
        this.mkdirp = mkdirp;
        // New Single Folder
        this.mkdir = fs.mkdir.bind(fs);
        // remove folders
        this.rmdir = fs.rmdir.bind(fs);
        // Delete Files
        this.unlink = fs.unlink.bind(fs);
        // Write content into a file
        this.writeFile = fs.writeFile.bind(fs);
        // slightly
        this.join = path.join.bind(path);
    }
}

module.exports = NodeOutputFileSystem;

This module is very popular and is a native nodeAPI and is not packaged.

 

NodeWatchFileSystem
"use strict";

const Watchpack = require("watchpack");

class NodeWatchFileSystem {
    constructor(inputFileSystem) {
            this.inputFileSystem = inputFileSystem;
            this.watcherOptions = {
                aggregateTimeout: 0
            };
            this.watcher = new Watchpack(this.watcherOptions);
        }
        // Monitor Files
    watch(files, dirs, missing, startTime, options, callback, callbackUndelayed) { /*...*/ }
}

module.exports = NodeWatchFileSystem;

The content of the module is simple. An inputFileSystem is introduced to initialize the monitoring object, and there is only one watch method on the prototype.(The actual content is very deep and complicated, let's talk later)

  

This module is mainly for preparing the next output package file, mostly nodejs related.

Nevertheless, they are all written in JS.

Tags: Javascript REST

Posted on Thu, 21 May 2020 10:00:36 -0700 by makeshift_theory