Zero, preface,
In the last article, I wrote the basic idea of Joao-CLI. Some students didn’t understand it. This time, I will directly take you to write my own CLI tool, which can be implemented
- Template code is pulled locally
- Install the material component to the specified directory
- Install modules and replace them
- Pull the specified folder from the material store
First, preparation
Step will give the corresponding GIF, if the figure is not moving, it is recommended to right-click a new connection to open.
1. Initialize the NPM and install the dependency.
// Create a new folder to store the CLI tools, the current directory open command line NPM init package name enter your CLI name, press Enter to skip the rest...Copy the code
2. Registered node. Js
Create command-js in the current directory#! /usr/bin/env node
console.log('Command script executed'// Register the above content so that the command. Js can be executed by Node and then added to packge.json"bin": { "joao": "./command.js" }
{
"name": yourcli","version":"0.0.1","description":"Build the front end station quickly and develop it automatically","main":"command.js","dependencies": {},"devDependencies": {},"bin": {"joaocli":"./command.js"}} // The current path open the command line tool, type NPM link, declare the environment variable NPM link // After successfully typing joaocli, the script joaocli will be prompted... The command script is executed. ProcedureCopy the code
3. Install dependencies to be used
Install dependencies | Install the purpose |
---|---|
commander | Command line tool |
fs | For processing files |
git-clone | Used to download your files from a Git hosting location |
inquirer | Dialog or options are now available on the command line |
path | To handle paths |
shelljs | To execute the shell |
tracer | For fancy log typing |
NPM install ${pageage.json}
npm install commander
npm install fs
...
Copy the code
Two, function demonstration and code implementation
Once you've done your homework (all dependencies installed!) Now that you have an executable script, it's time to refine the functionality
- Complete the dialogue with Inquirer + Commander
/ / modify command. Js#! /usr/bin/env node console.log('Command script executed') const commander = require('commander'); const inquirer = require('inquirer'); const questions = [ { type: 'input', name: 'projectName', message: 'Please name the project', filter: function(val) { returnval; }}, {type: 'list', name: 'type', message: 'Please select a template to use', choices: ['empty-vue-template'.Template '2'.Template '3'], filter: function(val) { returnval.toLowerCase(); }}] // Create a new project pull template commander. Command ('init') .description('To initialize the project, pull the template') .action(() => { console.log('Building... ') inquirer.prompt(questions) .then(answers => { console.log('answers', answers)})}) commander. Parse (process.argv)Copy the code
Typing JoaoCLI init now outputs the dialog and gets the user’s input and options
- Create an empty project and pull the template locally
Git clone, used for git clone, used for git shelljs, used for deleting project, git file, used for color console
const clone = require('git-clone');
const shell = require('shelljs');
const log = require('tracer').colorConsole();
Copy the code
Add necessary constants
// Project address const projectUrl = {'empty-vue-template': 'https://github.com/murongqimiao/joao-template', // blank library}Copy the code
After getting the callback of the user’s input
const { projectName, type } = answers
console.log(projectName)
console.log(type)
clone(`${projectUrl[type]}`, `. /${projectName}`,null, function() {
log.info('Project build completed')
shell.rm('-rf', `. /${projectName}/.git`); Clear the log. The info (`${projectName}NPM install ')})Copy the code
Now execute joaoCLI init in your directory. You will pull down the template project and clear.git
- Pull materials from storage to local. Add the dependent
const path = require('path')
Copy the code
Add the materials folder in the same directory as packgejson
mkdir material
cd material
Copy the code
Added new COMMANDER to enable material download
// Update materials commander. Command ('update')
.description('Update Stores')
.action(() => {
let pwd = shell.pwd()
shell.cd(__dirname)
shell.exec('rm -rf .git')
const updateFiles = () => {
shell.cd(path.join(__dirname, '/material'))
shell.rm('-rf'.The '*')
shell.cd(__dirname)
shell.exec('git pull origin master')
}
shell.exec('git init')
shell.exec('git remote add origin [email protected]:murongqimiao/joao-website.git'// Shell. Exec ('git config core.sparseCheckout true')
shell.exec("echo 'material' >> .git/info/sparse-checkout"Parse (process.argv)Copy the code
Run joaocli update to update the material to /material
There are many ways to manage materials. Here, the author uses a relatively simple Git repository to set up a private folder to host materials. Using Git’s core.sparsecheckout to download part of the folder is not the best way, because in terms of the working mechanism of Git, SparseCheckout still tracks all historical changes and deletes unnecessary contents. If the project is hosted on Github, the storage of Github can also be transferred to SVN for download. For specific operations, you can check how SVN downloads part of github content, because our factory’s code is stored on GitLab, so it is selected by reason Use core.sparSecheckout to download material files.
Meanwhile, the update will be very slow to execute because the entire project is downloaded by reference. Please be patient.
Generate_components and module generate_modules will be added under the material file after the update
- Adding components to your templates involves reading and writing files using Node’s FS series
const fs = require('fs')
Copy the code
Continue adding content to command-js
/** * Introduce something that can be pulled away: Commander shortcuts | getComponentsFiles access catalog | _getFileName is access to files or folders | generateComponent placed in the specified directory object file * * / commander in version ('1.0.0')
.option('-c, --component'.'Add component')
.option('-p, --page'.'Add page')
const getComponentsFiles = () => {
return _getFileName('.. /material/generate_components')
}
const _getFileName = (url) => {
let _url = path.join(__dirname, url)
let _back = fs.readdirSync(_url)
return _back
}
const generateComponent = (componentType, fileName, pwd) => {
fs.readFile(path.join(__dirname, `./material/generate_components/${componentType}${fileName}`), 'utf-8', (error, data) => {
if (error) throw error
// if (componentName) {
// data = data.replace(/__className__/g, componentName)
// componentType = componentName
// }
fs.writeFile(path.join(`${pwd}/src/components/${componentType}${fileName}`), data, (err) => {
if(err) {
console.log('err:', err);
} else {
console.log(`${componentType}${fileName}Write successful! . ')}})})} // Add material commander. Command ('add [args...] ')
.description('Add Material - C component - P page'Action ((args) => {// Missing argumentsif(! commander.component && ! commander.page) { log.warn('Missing -c or -p parameters to distinguish material types, see --help'} // Add componentsif (commander.component) {
let pwd = shell.pwd()
args.map(componentType => {
_componentType = getComponentsFiles().indexOf(componentType) > -1 ? componentType : getComponentsFiles().indexOf(componentType + '.vue') > 1? componentType +'.vue' : void 0
if(! _componentType) { log.warn(`:${componentType}--> component does not exist, please check spelling ')}else {
let _filePath = path.join(__dirname, `./material/generate_components/${_componentType}`)
let _isFile = fs.statSync(_filePath).isFile()
if (_isFile) {
generateComponent(_componentType, ' '.pwd)}else {
let_aimFiles = fs.readdirsync (_filePath) // Create folder fs.mkdir('${pwd}/src/components/${_componentType}`, 0777, (err) => {
if (err) {
log.info(`${componentType}Directory already established ')}}) _aimfiles.map (item => {generateComponent(_componentType, '/${item}`, pwd)})}})} // Add pagesif(commander. Page) {/ * * * here is to add the logic of modules, the next added * * /}})... Commander. Parse (process.argv)Copy the code
Now run joaocli add -c empty or joaocli add -c Layout in the root directory of the empty project you init to test whether the material can be added properly.
- Add modules to your project
Once you can add components, adding modules isn’t that difficult, just a custom path compared to components
First add a new problem
const modulesFileContent = ['data.js'.'index.js'.'vx.js'.'__className__.vue'Const pageQuestions = [{type: 'input',
name: 'modelType',
message: 'Please enter the type of page you want to use',
filter: function(val) {
returnval; }}]Copy the code
Add Adds moduls logic
/** * Const generateModule = (modelType, pageName, fileName,pwd) = > {let aimFileName = fileName
let _directory = ' '// Consider a level 1 directoryif (pageName.split('/').length > 2) {
console.log('Currently supports up to level 2 directories, such as Dashboard /example')}if (pageName.split('/').length === 2) {
_directory = pageName.split('/') [0] +'/'
pageName = pageName.split('/')[1]
}
if (new RegExp(/.vue/).test(fileName)) {
aimFileName = pageName + '.vue'
}
fs.readFile(path.join(__dirname, `./material/generate_modules/${modelType}/${fileName}`), 'utf-8', (error, data) => {
if (error) throw error
data = data.replace(/__className__/g, pageName)
fs.writeFile(path.join(`${pwd}/src/views/${_directory}${pageName}/${aimFileName}`), data, (err) => {
if(err) {
console.log('err:', err);
} else {
console.log(`${fileName}Write successful! . ')}})})} // Add pagesif(com.page) {/** * here is the logical addition to add modules **/ inquirer. Prompt (pageQuestions). Then (answers => {const {modelType} = answerslet pwd = shell.pwd()
console.log(`commander.page`, args)
args.map(pageName => {
console.log('pageName', pageName) // Create a folder corresponding to the directoryif (pageName.split('/').length === 2) {
fs.mkdir(`${pwd}/src/views/${pageName.split('/')[0]}`, 0755, (err) => {
log.info(`${pageName.split('/')[0]}Existing ')})} fs.mkdir('${pwd}/src/views/${pageName}`, 0755, (err) => {
log.info(`${pageName}/ / ModulesFileconten. map(fileName => {generateModule(modelType, pageName, fileName,pwd)})})})}Copy the code
Execute at the root of the template project
joaocli add -p yourlogin
Copy the code
Enter the module type, such as login
This completes the process of installing Modules in one click.
The source code to view
npm install -g joao-cli
Copy the code
Go to the joao-CLI directory and look at the code directly, exactly the same.
website
At present, there is not much material, I will maintain it when I have time, welcome all the big guys to plug the material, suggest to add readme. md, place the material usage method and payment code, you can reward the material developer if you use cool.