Интерпретация исходного кода приложения create-реагировать

внешний интерфейс исходный код React.js

недавно поставилvue-cli@2.xа такжеcreate-react-appИсходный код был прочитан еще раз. Поскольку теперь официально рекомендуется использоватьvue-cli@3.0, изменения относительно большие, поэтому писать не будуvue-cliДа (предположительно потому, чтоvue-cli@2.xПри создании проекта операция слишком сложна, поэтому Ю Юйси извлекла из этого урок.create-react-appидея, придумал нулевую конфигурациюvue-cli@3.0, кому интересно, могут съездить и посмотреть сами). Это эссе только объясняетcreate-react-appреализации, однако, посколькуисходный код приложения create-реагироватьВсего более 800 строк кода с комментариями, и я не собираюсь интерпретировать его исходный код один за другим.Если вы хотите интерпретировать весь исходный код, вы можете сначала прочитать эту статью, а затем посмотреть исходный код , должно быть проще понять многое .

Столько глупостей было сказано ранее, теперь пришло время перейти к сути. Этоcreate-react-appЧто за чертовщина? Вот официальная цитатаreadmeПервое предложение документа поясняет:

Create React apps with no build configuration.

Ну, это объясняет это очень ясно:creact-react-appПозволяет создать нулевую конфигурациюReactзаявление! Зачем подчеркивать нулевую конфигурацию? Потому что мы все знаем,ReactЭто компонентная структура подмодулей, которая требует настройкиwebpackУпаковать? также используетсяJSXи высокийES6新特性, что требует настройкиbabelБар? Кроме того, вам нужно проверить стиль кода, вам нужно настроитьeslintБар? Для новичка, чтобы суметь успешно настроить прогонReactсреды, весьма вероятно, что это займет день или два. Таким образом, смысл нулевой конфигурации в том, чтобы позволить Xiaomengxin быстро написать свою первую, не зная конфигурации.react-hello-world, что очень приятно!

если не использовался ранееcreate-react-appЭто не имеет значения, вот его простейшее использование:

create-react-app my-app

Подождите несколько минут, и в текущем каталоге будет создан новый.my-appпроект, затем перейдите в этот корневой каталогnpm startначатьReactпроект. Не забудьте сначала установить его глобальноcreate-react-app.

представилcreate-react-appЧто есть, и его простейшее использование. Теперь давайте реализуемcreate-react-appКопировальная версия. Поскольку то, что мы реализовали, является упрощенной версией, в которой удалены такие функции, как проверка среды, определение версии, автономная установка пакета и т. д., осталось всего около 100 строк кода, который вызывается на данный момент.simple-create-react-app.

Перед реализацией кода разберемся с идеями:

  1. пройти черезcommanderполучить название проекта;
  2. Если имя проекта пустое (на самом деле имя пакета нужно проверить на валидность, что здесь игнорируется), выходим из процесса и подсказываем пользователю, что имя проекта не может быть пустым, иначе переходим к шагу 3;
  3. Создайте подкаталог в текущем каталоге, именем каталога является имя проекта, введенное пользователем, и инициализируйте в нем подкаталогpackage.jsonдокумент;
  4. Перейдите в корневой каталог проекта и установитеreact, react-domа такжеreact-scriptsтри зависимости;
  5. После установки зависимостей вызовитеreact-scriptsизinitметод инициализации проекта (чаще всего для копирования шаблона);
  6. конец;

Следуйте приведенным выше идеям и начните программировать!

Сначала введите некоторые необходимые зависимости, и мы не будем здесь подробно останавливаться на роли этих зависимостей. и определите переменную для хранения имени проектаprojectName:

const commander = require('commander');
const chalk = require('chalk');
const spawn = require('cross-spawn'); 
const fs = require('fs-extra');
const path = require('path');
const os = require('os');

const packageJson = require('./package.json');

let projectName; // 项目名称,通过命令行参数获取

Далее создайтеCommanderЭкземпляр, получить имя элемента, введенное пользователем, и определить, пусто ли оно. Если он пуст, пользователь запрашивает и выходит из процесса.

const program = new commander.Command(packageJson.name)
.version(packageJson.version)
.arguments('<project-directory>')
.usage(`${chalk.green('<project-directory>')} [options]`)
.action(name => {
  projectName = name;
})
.parse(process.argv) // 格式化参数,必须要的

// 如果没有输入项目名称,则给出提示,并退出进程
if(typeof projectName === 'undefined') {
  console.error('please specify the project directory');
  console.log();
  console.log('For examaple: ')
  console.log(`    ${chalk.cyan(program.name())} ${chalk.green('my-react-app')}`)
  console.log();
  process.exit(1);
}

Если имя проекта не пустое, начните создавать пустой проект и инициализируйтеpackgae.jsonдокумент:

// 开始创建项目
createApp(projectName);

function createApp(name) {
  const root = path.resolve(name);
  fs.ensureDirSync(root); // 创建项目空目录
  console.log(`Creating a new React app in ${chalk.green(root)}.`);

  // 创建新项目的package.json
  const packageJson = {
    name: name,
    version: '0.1.0',
    private: true
  };
  fs.writeFileSync(path.join(root, 'package.json'), JSON.stringify(packageJson, null, 2) + os.EOL);

  // 将当前目录的路径存下来。因为下一步我们就要进入到新项目的目录了
  // 后面可能还会用到当前的路径
  const originalDirectory = process.cwd();

  // 进入新创建的项目里面
  process.chdir(root);

  run(root, originalDirectory);
}

После создания нового проекта перейдитеprocess.chdir(root);Пусть рабочий каталог процесса перейдет в новый проект. Затем начните устанавливать зависимости, подождите несколько минут, после завершения установки зависимостей начните звонитьreact-scripts(Этоcreate-react-appПодмодуль, который включает в себя загрузку других плагинов для вашего проекта, разбор окончательной конфигурации вебпака, и здесь он не будет раскрываться, если вам интересно, вы можетекликните сюда)изinitМетод инициализации проекта (в основном копирование шаблона в новый проект):

function run(root, originalDirectory) {
  const allDependencies = ['react', 'react-dom', 'react-scripts'];
  console.log('Installing packages. This migth take a couple of minutes...');
  console.log(`Installing ${chalk.cyan('react')}, ${chalk.cyan('react-dom')}, and ${chalk.cyan('react-scripts')}...`);
  console.log();

  install(root, allDependencies)
  .then(() => {
    console.log();
    console.log('Installing is success!');
    console.log();

    // 执行react-scripts模块下的init方法进行初始化项目
    const scriptsPath = path.resolve(
      process.cwd(),
      'node_modules',
      'react-scripts',
      'scripts',
      'init.js'
    )
    const init  = require(scriptsPath);
    init(root, projectName, null, originalDirectory);
  })
  .catch(reason => {
    console.log();
    console.log('Aborting installation.');
    if(reason.command) {
      console.log(`    ${chalk.cyan(reason.command)} has failed.`);
    } else {
      console.log(chalk.red('Unexpected error!'), reason);
    }
  })
}

// 在指定目录下安装npm依赖
function install(root, dependencies) {
  return new Promise((resolve, reject) => {
    let command = 'yarnpkg';
    const args = ['add'];
    [].push.apply(args, dependencies);
    let child = spawn(command, args, {stido: 'inherit'});
    child.on('close', code => {
      if(code !== 0) {
        reject({
          command: `${command} ${args.join(' ')}`
        });
        return;
      }
      resolve();
    })
  });
}

После подсчета всего более 100 строк кода, так что это легко сделатьcreate-react-appосновная функция. Конечно, на самом деле есть также определение среды, определение версии, автономная установка и т. д., которые мы здесь проигнорировали.Если вам интересно, вы можете сами взглянуть на официальный исходный код.

оcreate-reate-appЭто все, что я написал, исходный код можно найти здесьмой гитхабСкачайте его, если вам это нравится, добро пожаловатьstarДавай~