Vue.js is one of the most popular front-end frameworks at present, so developing a component based on vue. js is the wish of every front-end. Each time a new vue.js component is developed, the following things are done:
- Create a project directory
- Git initialization
- NPM initialization
- Setting up the development environment
- Grammar testing
- The code to compile
- The code package
- Local preview and thermal reloading
- Set up production environment
- Grammar testing
- The code to compile
- Code packaging and compression
- Configuration for continuous integration
So why not effectively distill the work and let him generate it with one click? There are many one-click generation tools, such as Yeoman. Yeoman scaffolding projects require yeoman scaffolding packages. Yeoman’s scaffolding package is essentially a project template with a complete file structure that users manually download locally and yeoman automatically generates various projects based on the scaffolding package.
Yeoman was easy to use, but there was always the hassle of having to download the scaffolding package. Cli technology is also popular in the market, where templates for remote repositories are pulled locally based on some configuration. Obviously cli mode is very good, do not need to download. We built ourselves a scaffold called Fecli based on this principle.
Technology stack
- Development environment: OS X El Capitan 10.11.6
- Development tool: Atom
- Node.js: The entire scaffolding environment. Node.js version of this scaffold: 9.11.1.
- Es6: New syntax for JavaScript.
- Commander: A tool developed by TJ to better organize and process command line input. The commander version of this scaffold is 2.15.1.
- Co: asynchronous process control tool. Co version of this scaffold: 4.6.0.
- Co-prompt: Receives user input step by step. Co-prompt version of this scaffold: 1.0.0.
- Chalk: Colorful terminal tool. Chalk version of this scaffold: 2.3.2.
- Ora: Elegant terminal spinner that controls terminal output. Ora version of this scaffold: 2.0.0.
Project core
A diagram illustrates the overall architecture. ⤵ ️
About template
Templates are what the future pulls down. This template usually has some configuration for environment, syntax checking, unit testing, continuous integration, etc.
Information about templates is stored in the templates.json file. You can also manipulate the contents of templates.json with commands.
Scaffolding file structure
Run. ├ ─ ─ the bind / # entry documents │ └ ─ ─... ├ ─ ─ lib / # core code │ ├ ─ ─ table. Js # template list form of encapsulation │ ├ ─ ─ tip. Js # terminal message encapsulation │ ├ ─ ─ cli / # command management │ │ └ ─ ─... │ ├ ─ ├ ─ ├ ─ 08.07.02 ├─ ├─ ├─ ├─ ├─ ├─ └─ templates. Json #
Configure global usage
Create a new directory mkdir fecli and go to CD fecli. And then NPM initializes NPM init. To be used globally, we need to set this in package.json:
"bin": {
"fe": "./bin/fe.js"
},
Copy the code
For local debugging, run: NPM link in the project root directory. The fecli command can be bound globally, so that the command can start with fe.
Entry file Settings
Json and execute NPM install or YARN install:
"Dependencies" : {" chalk ":" ^ "2.3.2," co ":" ^ 4.6.0 ", "co - prompt" : "^ 1.0.0", "commander" : "^ 2.15.1", "ora" : "^ 2.0.0"}Copy the code
Create a fe.js file in the \bin folder in the root directory. The bin/fe.js file is the entry file to the entire scaffold, so we’ll write it first.
We’ll start with some initialization code, which simply references the command management file (lib/cli/index.js) :
require('.. /lib/cli/');Copy the code
Command Management (lib/cli/index.js)
First, a few initialization things:
const program = require('commander'); const packageInfo = require('.. /.. /package.json'); program .version(packageInfo.version)Copy the code
We use commander to set different commands. The command method sets the name of the command. The description method sets the description. The alias method is a shorthand for setting. The action method sets the callback.
Description (' generate a project ').alias(' I ').action(() => {require('.. /cmd/init')(); }); Program.command ('add') // fe add.description ('add new template ').alias('a') // short.action(() => {require('.. /cmd/add')(); }); Program.command ('list') // fe list.description (' view template list').alias('l') // short.action(() => {require('.. /cmd/list')(); }); Program.command ('delete') // fe delete.description (' view template list ').alias('d') // short.action(() => {require('.. /cmd/delete')(); });Copy the code
If there are no arguments, run the help method. Next, parse the parameters in program.args:
program.parse(process.argv); if(! program.args.length){ program.help() }Copy the code
Results after running FE:
The specific usage of COMMANDER is not explained here. You can go to the official website for detailed documentation.
Processing user input
Create a /lib/cmd folder in the root directory of your project to store command processing files. Templates. Json file in the root directory and write the following to hold template information:
{"tpl":{}}
Copy the code
Add a template (fe add
)
Go to /lib/cmd and create the add.js file.
'use strict' const co = require('co'); const prompt = require('co-prompt'); const fs = require('fs'); const table = require('.. /table'); const tip = require('.. /tip'); const tpls = require('.. /.. /templates'); Const writeFile = (err) => {// Handle error if (err) {console.log(err); Tip. Fail (' Please run again! '); process.exit(); } table(tpls); Tip. Suc (' New template added successfully! '); process.exit(); }; const resolve = (result) => { const { tplName, gitUrl, branch, description, } = result; // Avoid repeating if (! tpls[tplName]) { tpls[tplName] = {}; tpls[tplName]['url'] = gitUrl.replace(/[\u0000-\u0019]/g, ''); TPLS [tplName]['branch'] = branch; tpls[tplName]['description'] = description; } else {tip.fail(' Template already exists! '); process.exit(); }; Json fs.writefile (__dirname + '/.. /.. /templates.json', JSON.stringify(tpls), 'utf-8', writeFile); }; Module.exports = () => {co(function *() {const tplName = yield prompt(' template name: '); Const gitUrl = yield prompt('Git HTTPS: '); Const branch = yield prompt('Git branch: '); Const description = yield prompt(' template description: '); return new Promise((resolve, reject) => { resolve({ tplName, gitUrl, branch, description, }); }); }).then(resolve); };Copy the code
Deleting a template (fe delete
)
Go to /lib/cmd and create the delete.js file.
'use strict' const co = require('co'); const prompt = require('co-prompt'); const fs = require('fs'); const table = require('.. /table'); const tip = require('.. /tip'); const tpls = require('.. /.. /templates'); const writeFile = (err) => { if (err) { console.log(err); Tip. Fail (' Please run again! '); process.exit(); } tip.suc(' New template deleted successfully! '); if (JSON.stringify(tpls) ! == '{}') { table(tpls); } else {tip.info(' Template not added yet! '); } process.exit(); }; Const resolve = (tplName) => {if (TPLS [tplName]) {delete TPLS [tplName]; } else {tip.fail(' Template does not exist! '); process.exit(); } // write to template.json fs.writefile (__dirname + '/.. /.. /templates.json', JSON.stringify(tpls), 'utf-8', writeFile); }; Module.exports = () => {co(function *() {const tplName = yield prompt(' template name: '); return new Promise((resolve, reject) => { resolve(tplName); }); }).then(resolve); };Copy the code
Initialize the project (fe init
)
Go to /lib/cmd and create the init.js file.
Const exec = require('child_process'). Exec; const co = require('co'); const ora = require('ora'); const prompt = require('co-prompt'); const tip = require('.. /tip'); const tpls = require('.. /.. /templates'); Const spinner = ora(' generating... '); const execRm = (err, projectName) => { spinner.stop(); if (err) { console.log(err); Tip. Fail (' Please run again! '); process.exit(); } tip.suc(' Initialization complete! '); tip.info(`cd ${projectName} && npm install`); process.exit(); }; const download = (err, projectName) => { if (err) { console.log(err); Tip. Fail (' Please run again! '); process.exit(); } // Delete git file exec(' CD '+ projectName +' && rm -rf. git', (err, out) => {execRm(err, projectName); }); } const resolve = (result) => { const { tplName, url, branch, projectName, } = result; Const cmdStr = 'git clone ${url} ${projectName} && CD ${projectName} && git checkout ${branch}'; spinner.start(); exec(cmdStr, (err) => { download(err, projectName); }); }; Module.exports = () => {co(function *() {// const tplName = yield prompt(' template name: '); Const projectName = yield prompt(' projectName: '); if (! TPLS [tplName]) {tip.fail(' Template doesn't exist! '); process.exit(); } return new Promise((resolve, reject) => { resolve({ tplName, projectName, ... tpls[tplName], }); }); }).then(resolve); }Copy the code
Display template list (fe list
)
Go to /lib/cmd and create the list.js file.
'use strict' const table = require('.. /table'); module.exports = () => { table(require('.. /.. /templates')); process.exit(); };Copy the code
Now that our fecli scaffolding tool is set up, let’s give it a try!
Use the test
fe add
Add the template
fe delete
Add the template
fe list
Add the template
fe init
Add the template
Program source code
For more information, go to fecli.