返回

从零开始写脚手架,DIY你的代码构建工具

前端

从无到有,构建脚手架

1. 最简实现

首先,我们先来实现一个最简版本的脚手架。这个脚手架只需要具备以下功能:

  • 初始化项目
  • 安装依赖
  • 运行项目

为了实现这些功能,我们需要用到以下库:

  • commander:用于处理命令行参数
  • chalk:用于在控制台输出彩色文字
  • fs-extra:用于操作文件系统

我们可以通过以下步骤来实现最简版本的脚手架:

  1. 安装必要的库
npm install --save commander chalk fs-extra
  1. 创建脚手架命令
const program = require('commander');
const chalk = require('chalk');
const fs = require('fs-extra');

program
  .command('create <project-name>')
  .description('Create a new project')
  .action(async (projectName) => {
    // 创建项目目录
    fs.mkdirSync(projectName);

    // 初始化 package.json 文件
    const packageJson = {
      name: projectName,
      version: '1.0.0',
      scripts: {
        start: 'node index.js',
      },
    };
    fs.writeFileSync(`${projectName}/package.json`, JSON.stringify(packageJson, null, 2));

    // 创建 index.js 文件
    const indexJs = `console.log('Hello, ${projectName}!');`;
    fs.writeFileSync(`${projectName}/index.js`, indexJs);

    // 输出成功信息
    console.log(chalk.green(`Project ${projectName} created successfully!`));
  });

program.parse(process.argv);
  1. 使用脚手架命令
npx create-project my-project
  1. 验证脚手架是否工作
cd my-project
npm install
npm start

如果输出结果为 Hello, my-project!,则说明脚手架工作正常。

2. 添加辅助功能

在最简版本的脚手架的基础上,我们可以添加一些辅助功能,例如选择包管理器、npm 源等等。

我们可以通过以下步骤来添加辅助功能:

  1. commander 中添加选项
program
  .option('-m, --manager <manager>', 'Choose a package manager (npm/yarn/pnpm)', 'npm')
  .option('-r, --registry <registry>', 'Set npm registry');
  1. action 函数中处理选项
program
  .command('create <project-name>')
  .description('Create a new project')
  .action(async (projectName) => {
    // ...

    // 处理包管理器选项
    const manager = program.manager;
    if (manager === 'yarn') {
      await execa('yarn', ['init', '-y'], { cwd: projectName });
    } else if (manager === 'pnpm') {
      await execa('pnpm', ['init', '-y'], { cwd: projectName });
    }

    // 处理 npm 源选项
    const registry = program.registry;
    if (registry) {
      await execa('npm', ['config', 'set', 'registry', registry], { cwd: projectName });
    }

    // ...
  });
  1. 验证辅助功能是否工作
npx create-project my-project -m yarn -r https://registry.yarnpkg.com
  1. 验证脚手架是否仍然正常工作
cd my-project
npm install
npm start

如果输出结果仍然为 Hello, my-project!,则说明脚手架仍然正常工作。

3. 实现插件化

插件化是脚手架的必备功能之一。插件可以帮助我们扩展脚手架的功能,使其更加灵活和强大。

我们可以通过以下步骤来实现插件化:

  1. 创建一个插件接口
class Plugin {
  constructor(options) {
    this.options = options;
  }

  apply(compiler) {
    // ...
  }
}
  1. 创建一个插件
class MyPlugin extends Plugin {
  constructor(options) {
    super(options);

    this.name = options.name;
  }

  apply(compiler) {
    // ...
  }
}
  1. 在脚手架中使用插件
const plugins = [
  new MyPlugin({
    name: 'my-plugin',
  }),
];

const compiler = new Compiler(plugins);
  1. 验证插件化是否工作
npx create-project my-project --plugins my-plugin
  1. 验证脚手架是否仍然正常工作
cd my-project
npm install
npm start

如果输出结果仍然为 Hello, my-project!,则说明脚手架仍然正常工作。

结语

通过本文,我们从零开始实现了一个简单且实用的脚手架。这个脚手架不仅具备了最基本的功能,还支持选择包管理器、npm 源等辅助功能,并实现了插件化。希望本文能够对你有帮助。