introduce

Some scaffolding tools like VUE-CLI are often used to quickly generate the required project structure, files and some basic functions. Koa-setup, described in this article, can help you quickly generate a simple Node-koa project.

The basic idea

Review the normal steps for creating a project using NPM:

  1. usenpm initCommand to initialize the project, which will ask us to input the project name, version number and other contents;
  2. When complete, the necessary files for the project are generatedpackage.json, which contains the basic project information, configuration and third-party dependency packages required by the project, etc.
  3. Create another project entry file,index.js, can complete the construction of a simple project;
  4. If you need to build a Vue project or node project, you can add related configuration files and third package dependency packages on the current basis.

Therefore, we need to build a scaffolding tool for koA project rapid creation. The necessary functions of the scaffolding tool are to help us create package.json file and the entry file index.js, and then to help us create KOA-related content and download the third-party dependencies required by KOA.

Note: For details about package.json, see the Node official documentation

The detailed content

Koa-setup project file structure

1. Koa-setup main entry JS file

This file is the main file of the project and is used to generate the project folder, index.js, package.json files, and third-party dependent installations.

#! /usr/bin/env node // import fs from 'fs'; import chalk from 'chalk'; Import {execa} from 'execa'; import {execa} from 'execa'; Import createIndexTemplate from './createIndexTemplate.js'; / / create index. Js import createPackageTemplate from '. / createPackageTemplate. Js'; // create package.json import question from './question/index.js'; Import {createConfig} from './config.js'; // Generate project configuration const answer = await question(); // Get the answer to the user interaction const config = createConfig(answer); Log (' chalk. Blue '(' create folder -> ${config.packagename}')); fs.mkdirSync(getRootPath()); // 2. Create entry file = "index.js console.log(chalk. Blue (' create entry file ')); fs.writeFileSync(`${getRootPath()}/index.js`, createIndexTemplate(config)); // 3. Create package.json console.log(chalk. Blue (' create package.json')); fs.writeFileSync(`${getRootPath()}/package.json`, createPackageTemplate(config)); // 4. Install dependency console.log(chalk. Blue (' install dependency ')); execa('yarn', { cwd: getRootPath(), stdio: [2, 2, 2], }); Function getRootPath() {return './${config.packagename} '; }Copy the code

2. koa-setupProject profile

{" name ":" koa - setup ", "version" : "1.0.0", "description" : ""," main ":" index. Js ", "bin" : {" mykoa ": "./bin/index.js" }, "type": "module", "files": [ "bin", "package.json" ], "scripts": { "test": "rm -rf hei && node index.js", "test-g": "rm -rf hei && koa-setup" }, "keywords": [], "author": "", "license": "ISC", "dependencies" : {" chalk ":" ^ 5.0.0 ", "ejs" : "^ 3.1.6", "execa" : "^ 6.0.0", "the inquirer" : "^ 8.2.0", "prettier" : "^ 2.5.1"}, "devDependencies" : {" @ types/node ":" ^ 17.0.8 "}}Copy the code

3. Configure user interactionquestionfolder

The third-party library Inquirer is used for user interaction operations, requiring users to input project name, input project port, select project middleware and other operations. The plug-in provides text input, number input, select box selection, password input, notepad input and other functions, according to the need to use.

The following example text input is used:

// bin/question/packageName.js export default () => { return { type: 'input', name: 'packageName', message: 'set package name', validate(val) { if (val) return true; return 'Please enter package name'; }}; };Copy the code

Finally, bin/question/index.js will throw up the options given by the user for subsequent use.

import inquirer from 'inquirer';
import packageName from './packageName.js';
import port from './port.js';
import middleware from './middleware.js';

export default () => {
    return inquirer.prompt([packageName(), port(), middleware()]);
};

Copy the code

Because the inquirer plug-in ultimately presents user options with a different data structure from the one used, the user options are reassembled and thrown through config.js to get the user’s options, which can be used to create content.

// bin/config.js export function createConfig(answer) { function haveMiddle(name) { return answer.middleware.indexOf(name) ! = = 1; } return { packageName: answer.packageName, port: answer.port, middleware: { static: haveMiddle('koaStatic'), router: haveMiddle('koaRouter'), }, }; }Copy the code

Note: Detailed configuration and other usage of inquirer can be found here

4. Create an entry file based on user optionsindex.jsAnd configuration filespackage.json

Createindextemplate.js and createpackageTemplate.js, as well as the two corresponding templates, are created based on the user’s answers. Bin/template/index ejs, bin/template/package. The ejs.

Ejs to create index.js based on the project configuration.

// bin/createIndexTemplate.js import ejs from 'ejs'; import fs from 'fs'; import prettier from 'prettier'; import path from 'path'; import { fileURLToPath } from 'url'; export default config => { const __dirname = fileURLToPath(import.meta.url); const indexTemplate = fs.readFileSync(path.resolve(__dirname, '.. /template/index.ejs')); const code = ejs.render(indexTemplate.toString(), { middleware: config.middleware, port: config.port, }); return prettier.format(code, { parser: 'babel' }); };Copy the code

The use of EJS template, according to the incoming parameters of the middleware needs to control, and realize the operation of self-configuration port number.

// bin/template/index.ejs
    const Koa = require('koa');
<% if (middleware.static) { %>
    const serve = require('koa-static');
<% } %>

<% if (middleware.router) { %>
    const Router = require('koa-router');
<% } %>
    const app = new Koa();

<% if (middleware.static) { %>
    app.use(serve(__dirname + '/static'));
<% } %>

<% if (middleware.router) { %>
    const router = new Router();
    router.get('/', ctx => {
        ctx.body = 'hello koa-setup';
    });
    app.use(router.routes());
<% } %>

    app.listen(<%= port %> , () => {
        console.log('open server localhost:<%= port %> ');
    });

Copy the code

Similarly, createpackageTemplate.js is called to create package.json, which controls the middleware based on the parameters passed in, with the name field using the project name entered by the user.

// bin/createPackageTemplate.js import ejs from 'ejs'; import fs from 'fs'; import prettier from 'prettier'; import path from 'path'; import { fileURLToPath } from 'url'; export default config => { const __dirname = fileURLToPath(import.meta.url); const indexTemplate = fs.readFileSync(path.resolve(__dirname, '.. /template/package.ejs')); const code = ejs.render(indexTemplate.toString(), { packageName: config.packageName, middleware: config.middleware, }); return prettier.format(code, { parser: 'json' }); };Copy the code
/ / bin/template/package. Ejs {" name ":" < % = packageName % > ", "version" : "1.0.0", "description" : ""," main ": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "" and" license ", "ICS", "dependencies" : {" koa ":" tokens ^ 2.13.1 "< % if (middleware. The router) {% >," koa - the router ": "^" 10.0.0} < % % > < % if (middleware. The static) {% >, "koa - static" : "^ 5.0.0" % > < %}}}Copy the code

5. Application

Js and package.json. After installing the dependencies, a simple KOA project can be generated.

Local tests:

Once the development is complete, you can first test it locally. After linking the current project to the NPM global using the NPM link command, you can start creating a new KOA project from the command line window using the global command koa-setup.

Note:

  1. The command koa-setup is used to create the name field in the package.json file in the Koa-setup project. Json file, “bin”:{“mykoa”: “./bin/index.js”}. After executing NPM link again, mykoa command can be used to create the project. If the default value of the command is name, the bin field still needs to specify the entry file to be executed. “bin”: “./bin/index.js”.

  2. /bin/index.js file, so we have to tell the computer in which environment to execute the js file, so we have to add #! /usr/bin/env node, which tells the computer to execute js files in the node environment.

  3. NPM unlink moduleName. You can use this command to unlink a project to the NPM global.

NPM package release:

The final package can also be released to NPM after the local testing is successful, and others can download and use the tools we developed through NPM.

  1. You have to havenpmCan go to NPM official website to register;
  2. Second, use it on the command linenpm loginCommand to log in to your ownnpmAccounts.
  3. inpackage.jsonSpecify the file to be published in the file;
"files": [
    "bin",
    "package.json"
],
Copy the code
  1. npmDo not allow packages with the same name to exist onnpmOn the website, check to see if there is a bag with the same name;
  2. usenpm publishCommand to publish the package tonpmOfficial website.

conclusion

  1. User interaction using Inquirer;

  2. Get user input from Inquirer, use EJS template, automatically create entry files index.js, package.json;

  3. Use the execa plug-in to run the yarn command to install the dependency package.

Project code: GitHub

extension

  1. inquirer

    An interactive command-line tool, Inquirer simplifies asking end users questions, parsing, verifying answers, providing error feedback, and more. Get user information in an interactive way.

  2. chalk

    A tool for modifying the style of printed information in the console, you can modify the color of the character, etc.

  3. execa

    Execa is a javascript wrapper that can call shells and local external programs. The child process is started to execute. Supports multiple operating systems, including Windows. If the parent exits, all generated child processes are killed.

    In this document, run the yarn command to install project dependencies.

  4. npm

    This article mainly uses NPM link, NPM publish and other commands.

  5. Esm modular

    Cui da’s video explains the esM modularization related content in detail, interested can have a look.

  6. ora

    To implement the loading effect of node.js command line environment, and display various state ICONS, etc.

  7. commander

    The core function of Commander is to parse command line parameters. For example, in the NPM init -y command, you can use this tool to parse -y. Scaffolding tools often use similar operations to parse command-line parameters for more convenient functionality.

These are some of the tools that are often used when developing a scaffold tool. The use of relevant tools, can simplify our development, rich scaffolding function, thus more convenient output of a convenient, beautiful scaffold tools.