解析方法

根据terminal的输出去@electron-forge里面查代码位置,再做端点debug
image.png

目的

想自己写个script去打包,更好的去学一下electron

命令执行过程

electron-forge start 命令

@electron-forge/cli/dist/electron-forge.js

_commander会将其拼接为electron-forge-start去执行subCommand.

// Line 50
//
// var _commander = _interopRequireDefault(require("commander"));
(async () => {
  let goodSystem;
  await (0, _asyncOra.asyncOra)('Checking your system', async ora => {
    goodSystem = await (0, _checkSystem.default)(ora);
  });

  if (!goodSystem) {
    console.error(_chalk.default.red(`It looks like you are missing some dependencies you need to get Electron running.
Make sure you have git installed and Node.js version ${metadata.engines.node}`));
    process.exit(1);
  }

  _commander.default.parse(process.argv);
})();

@electron-forge\cli\dist\electron-forge-start.js

整合以下参数,执行_core.api.start
并使用listenForExit监听

// Line 58
//
// var _core = require("@electron-forge/core");
// _core.api.start = require("@electron-forge/core/dist/start.js")
const spawned = await _core.api.start(opts);
await new Promise(resolve => {
    const listenForExit = child => {
      // 此次省略
    };

    listenForExit(spawned);
  });
});

@electron-forge\core\dist\api\start.js

_default

// Line 63
// 从package.json 或者 forge.config.js读配置
// 这个位置使用了Proxy
const forgeConfig = await (0, _forgeConfig.default)(dir);
// 读出pack.json
const packageJSON = await (0, _readPackageJson.readMutatedPackageJson)(dir, forgeConfig);

if (!packageJSON.version) {
    throw new Error(`Please set your application's 'version' in '${dir}/package.json'.`);
}

const platform = process.env.npm_config_platform || process.platform;
const arch = process.env.npm_config_arch || process.arch;
// 注入pluginInterface等用于打包,请参考@electron-forge\core\dist\util\plugin-interface.js
await (0, _rebuild.default)(dir, await (0, _electronVersion.getElectronVersion)(dir, packageJSON), platform, arch, forgeConfig.electronRebuildConfig);
// 先不看
await (0, _hook.runHook)(forgeConfig, 'generateAssets', platform, arch);
let lastSpawned = null;

forgeSpawnWrapper() -> forgeSpawn()

// Line 76
const forgeSpawn = async () => {
    let electronExecPath = null; // If a plugin has taken over the start command let's stop here
    // 进入打包流程
    const spawnedPluginChild = await forgeConfig.pluginInterface.overrideStartLogic({
      dir,
      appPath,
      interactive,
      enableLogging,
      args,
      runAsNode,
      inspect
    });
       // 略...

    let spawned;
    await (0, _asyncOra.asyncOra)('Launching Application', async () => {
      spawned = (0, _child_process.spawn)(electronExecPath, // eslint-disable-line @typescript-eslint/no-non-null-assertion
      prefixArgs.concat([appPath]).concat(args), spawnOpts);
    });
    await (0, _hook.runHook)(forgeConfig, 'postStart', spawned);
    return spawned;
  };

@electron-forge\plugin-webpack\dist\WebpackPlugin.js

overrideStartLogic() -> startLogic()

// Line 409
async startLogic() {
  if (this.alreadyStarted) return false;
  this.alreadyStarted = true;
  await _fsExtra.default.remove(this.baseDir);
  const logger = new _webMultiLogger.default(this.loggerPort);
  this.loggers.push(logger);
  await this.compileMain(true, logger);
  await this.launchDevServers(logger);
  await logger.start();
  return false;
}
Line 205
_defineProperty(this, "compileMain", async (watch = false, logger) => {
  let tab;

  if (logger) {
    tab = logger.createTab('Main Process');
  }

  await (0, _asyncOra.asyncOra)('Compiling Main Process Code', async () => {
    const mainConfig = this.configGenerator.getMainConfig();
    await new Promise((resolve, reject) => {
      // 与webpack打包基本相同了
      const compiler = (0, _webpack.default)(mainConfig);
      const [onceResolve, onceReject] = (0, _once.default)(resolve, reject);

      const cb = async (err, stats) => {
        if (tab && stats) {
          tab.log(stats.toString({
            colors: true
          }));
        }

        if (this.config.jsonStats) {
          await this.writeJSONStats('main', stats, mainConfig.stats);
        }

        if (err) return onceReject(err);

        if (!watch && stats !== null && stats !== void 0 && stats.hasErrors()) {
          return onceReject(new Error(`Compilation errors in the main process: ${stats.toString()}`));
        }

        return onceResolve(undefined);
      };

      if (watch) {
        this.watchers.push(compiler.watch({}, cb));
      } else {
        compiler.run(cb);
      }
    });
  });
});

不更了


MadaoLi666
0 声望0 粉丝

2022年广州市吃饭最快的前端工程师