返回

webpack核心原理-手把手教你手写一个webpack

前端

手把手教你手写一个webpack(webpack核心原理)

众所周知,一个好的前端就是要于手写各种前端工具链。今天我们就来手写一个webpack。我这个版本省去了webpack中的tapable库和loader概念,但依然能够让你了解webpack的精髓。

webpack原理

Webpack的基本原理是:将文件从某个目录输入到webpack,经过一系列处理后,输出到指定目录中。 webpack使用loader对文件进行处理,loader可以把一种格式的文件转换成另一种格式的文件。

webpack核心

Webpack的核心是一个文件系统,它负责维护一个虚拟文件系统,这个文件系统包含了所有被 webpack 处理的文件。 webpack 还包含了一个插件系统,插件可以对 webpack 的行为进行扩展。

webpack手写

现在,我们一步步来手写一个webpack:

  1. 初始化
const webpack = {
  entry: '', // 入口文件
  output: '', // 输出目录
  plugins: [], // 插件
  loaders: [] // loader
};
  1. 读取文件系统
const fs = require('fs');
const path = require('path');

function readFileSystem(dir) {
  const files = fs.readdirSync(dir);
  const modules = [];
  files.forEach(file => {
    const filePath = path.join(dir, file);
    const stat = fs.statSync(filePath);
    if (stat.isFile()) {
      modules.push({
        id: file,
        filePath
      });
    }
  });
  return modules;
}
  1. 构建依赖图
function buildDependencyGraph(modules) {
  const dependencyGraph = {};
  modules.forEach(module => {
    dependencyGraph[module.id] = [];
  });
  modules.forEach(module => {
    const filePath = module.filePath;
    const content = fs.readFileSync(filePath, 'utf-8');
    const requires = [];
    // 正则匹配require('xxx')
    content.replace(/require\(['"](.*)['"]\)/g, (match, require) => {
      requires.push(require);
    });
    requires.forEach(require => {
      dependencyGraph[module.id].push(require);
    });
  });
  return dependencyGraph;
}
  1. 执行编译
function compile(modules, dependencyGraph) {
  const compiledModules = {};
  modules.forEach(module => {
    const filePath = module.filePath;
    const content = fs.readFileSync(filePath, 'utf-8');
    // 编译内容
    const compiledContent = '';
    compiledModules[module.id] = compiledContent;
  });
  return compiledModules;
}
  1. 写入文件系统
function writeFileSystem(outputDir, compiledModules) {
  fs.mkdirSync(outputDir, { recursive: true });
  Object.keys(compiledModules).forEach(moduleId => {
    const compiledContent = compiledModules[moduleId];
    const filePath = path.join(outputDir, moduleId);
    fs.writeFileSync(filePath, compiledContent);
  });
}
  1. 运行webpack
function runWebpack(config) {
  const modules = readFileSystem(config.entry);
  const dependencyGraph = buildDependencyGraph(modules);
  const compiledModules = compile(modules, dependencyGraph);
  writeFileSystem(config.output, compiledModules);
}

这就是一个简单的手写webpack,它可以让你了解webpack的核心原理和工作方式。