preface

By writing scaffolding, you can effectively improve development efficiency and reduce some of the repetitive work. Pulling remote templates during project initialization is a good direction.

The download-git-repo library can only be used to pull project templates from the root directory of the project. This library can only be used to pull project templates from the root directory. If we want to centrally manage these templates in a repository, put the template in a directory in the repository, the library will not be able to do, here is a reference to the Node Cli to improve the work efficiency of the idea, from the specified directory recursively through the file and pull to the local.

To prepare

The github/ GitLab API is used to retrieve project file information, which is basically two apis: retrieve directory file information and retrieve files.

gitlab

/ / GET/directory specified file information is the projects / : id/repository/treeCopy the code
/ / the specified path file, need warehouse is an open public GET/projects / : id/repository/files / : file_path/rawCopy the code

For details, you can go to the GitLab API. Since you are not in the company and do not have access to GitLab, the sample code in this paper is written based on Github, and the use of GitLab API is similar to that of Github.

github

GET /repos/{owner}/{repo}/contents/{path}Copy the code

A download link to the file is available in the API’s return. You can check out the Github API for details.

Simple implementation

DFS(depth-first search) is used for traversal of template files. The traversal starts from the directory where the template resides, continues recursion when encountering a directory, and executes local write operation when encountering a file.

  1. First the definition of some variables, including the name of the template in the warehouse, user name, such as template directory (scaffolding needed some rely on the comparison of before installation and configuration of the article has described in detail, here no longer tautology, specific to see touch hands for senior front-end 】 【 teach you lu a scaffolding) :
import got from 'got';
import fs from 'fs';

const baseUrl = 'https://api.github.com'
const user = 'xxx';  // Replace it with your github user name
const repositry = 'xxx'; // Create a repository on github
const basePath = 'templates/'; // Path of the template
const getRootList = `${baseUrl}/repos/${user}/${repositry}/contents`; // Get the list of files
Copy the code
  1. Gets a list of files in the template directory. The parameters are the local directory name and the path of the file relative to the repository root
  1. First, assemble the requested address, the project root directory + the incoming path can be

  2. Because the file path is the entire path from the root directory of the repository to the template file, you need to delete the template path when stitching local paths

    For example: path = ‘/templates/a.js’, copy to the local demo directory will be ‘demo/a.js’

  3. Check whether the local concatenation directory exists. If not, create the directory. This step is to prepare for writing files later

  4. Parse the obtained data, determine the type field of the array items, file is written to the file operation, dir continues recursive processing

const getList = async function (root, path) {
    let url = getRootList + path;
    let list = await got(url);
    let targetDir = root + path.replace(basePath, ' ');
    // Check whether the current directory exists. If not, create a new directory
    if(! fs.existsSync(targetDir)) { fs.mkdirSync(targetDir); }for (let e of JSON.parse(list.body)) {
        if (e.type === 'file') {
            await getFile(root, e)
        } else if (e.type === 'dir') {
            await getList(root, '/'+ e.path); }}}Copy the code
  1. Get the file and write it locally. I didn’t start by saying that the new directory must not exist, so I didn’t overwrite the files in the directory
  1. Assemble the path of the local file. Similarly, remove the path of the template from the path returned by the interface
  2. Check if the file exists, and if you start with a constraint that your local folder has to be empty you don’t have to write here
  3. Obtaining file contents
  4. Do some placeholder substitutions
  5. Write the file to the local directory
const getFile = async (root, info) => {
    let target = `${root}/${info.path.replace(basePath, ' ')}`;
    if (fs.existsSync(target)) {
        return;
    }
    let { body } = await got(info.download_url);
    Path = 'XXX ') body = body.replace(/$[^$]+$/, root)
    fs.writeFileSync(target, body);
}
Copy the code
  1. An exit function that simply takes an argument and displays an error message if there is no input
export default function (. args) {
    if(! args.length) {console.log(chalk.red('Please enter a project name'))
        return
    }
    if(! fs.existsSync(args[0])) fs.mkdirSync(args[0])
    // The initial directory is the directory where the template resides
    return getList(args[0].'/' + basePath)
}
Copy the code

At this point, a simple operation to pull files from the repository specified directory is complete.

A couple of things to watch out for

  1. In the above function getList, there will be a lot of request operations. I use the async/await single line operation, which will indeed slow down the file pull efficiency. The main purpose of this operation is to facilitate some subsequent operations after the template pull operation is completed, such as:
let fn = require('./init.js')
fn.default().then((a)= > {
	console.log(chalk.green('completed'))})Copy the code
  1. Github API has a pit, the speed is slow, you need to configure the relevant host (can refer to this article to get started DNS? Start with GitHub) and sometimes get stuck in the middle. If the number of files is too large, the number of unauthorized requests can only be 60 in an hour, and the number of unauthorized requests can only be 5000. Therefore, this method is not recommended for templates on Github. Gitlab’s API does not have this limitation on the company’s written requests.
  2. This article only implements the scaffolding to pull the remote template of the simple operation init.js, scaffolding complete configuration suggestions refer to the first few articles, write more detailed. The main purpose of this article is to use the GitLab/Github API to perform some operations. In fact, the API can also be used to create a repository, delete or change files in the repository.