Some nonsense (directly look at the code can be skipped)

Now the front circle framework is various, some independent research and development or cooperative development of the company’s internal frame, module/modularization, design idea, structure analysis of the framework and the underlying encapsulation skeleton to build high-rise buildings, in order to “maintenance, reuse, secondary development, high efficiency” concept, such as enrichment is to use two words (toulan)

Internal frameworks tend to be graphical, visual, but most of them go to the last step, which is to modularize the structure, the style (skin) and then want to generate the project with one click, huh? NPM/CNPM dependencies are not what I want! Then this article is to rescue you and let us create our own project structure file dependencies (it’s time to free your hands).


The technical implementation

The following technical implementation is based on JS, Node and its own FS module

What you want to achieve

  1. One command line, one file to create a project structure
  2. Visualize the execution process, and display the file creation progress in the CMD command indicator
  3. You need a tree that generates the project directory
  4. The project structure is arbitrary
  5. Code redeployable

Tools needed

  • node
  • CMD (command indicator)

Creating a minimalist project structure

Step 1: Go to the file directory you want to create with one click

1, win+r enter CMD and press Enter 2, CD enter the project directory (want to create a directory) 3, Node how to install baidu


Step 2: Create server.js

Open your handy editor and copy the following code directly

var fs = require("fs")

var mkDir = ['css'.'fonts'.'img'.'module']
/* Create directory */
for (var i = 0; i < mkDir.length; i++) {
  fs.mkdir(mkDir[i], function (err) {
    if (err) {
      return console.error(err); }})}Copy the code

CTRL + S to save, enter in CMD

node server

Take a look back at your project structure. If nothing else, the project structure has become this

The node FS API address is attached below.

http://nodejs.cn/api/fs.html


Step 3: That’s not all. Read the file and generate the file

We already have the project structure we want, but this is not enough for us, we still need to create JS files and HTML files and so on.

1) Create index.html in this directory

Write the following code inside:Copy the code
<! DOCTYPE html><html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
	  <h1>Hello World!</h1>
	</body>
</html>

Copy the code

2) server. Js

var fs = require("fs")

/* Create indexx.html file */
fs.readFile('index.html'.'utf8'.function (err, data) {
    if (err) {
      return console.error(err);
    }
    fs.appendFile('indexx.html', data, 'utf8'.function (err) {
      if (err) {
        return console.error(err); }}); });Copy the code

CMD to perform

node server

Look in the project directory and see if there is an indexx.html file. If there is an indexx.html file, it is successful. The above operation reads all the text in indexx.html and then creates the indexx.html hypertext.


Create a customized Catalog, Tree, color, Path project structure (advanced)

Tips: The following steps walk you through each stage (complete Github project address at the bottom)Copy the code

Parsing 1: Build server.js code procedurally

var _methods = {
  data: { /* Data storage location */
	now: 0./* Current process count */
	sum: 0./* Total number of processes */
	log: ' ' /* Output tree*/
  },
  _nodeInit: function (mkDir) { /* Initialize */
    this._nodeSum(mkDir) /* Count the number of asynchronous returns */
    this._nodeFor(mkDir) /* Go to the next process -- create */
  },
  _nodeFor: function (mkDir) { / * * / creation
	/* This is where the directory structure creation is performed and this._nodetree (++now) is executed after each asynchronous callback to show the current creation progress */
  },
  _nodeSum: function () { /* Count the total number of builds */
	/* The tree is created asynchronously, so it is difficult to determine whether the tree is created asynchronously or not
  },
  _nodeTree: function () { /* Check the current progress */
	/* If the current progress === total progress, execute the previously created one to console.log(this.tree) */}}var fs = require("fs") / * introduction of fs * /
var mkDir = [ /* Project structure tree */
  {
    name: 'csss'./* Folder name */
    child: [
      {
        name: 'public.css'./* File name */
        val: ' ' /* File contents */
      }, {
	    name: 'asd'.child: [{name: 'asd'
		  }
		]
      }
    ]
  }
]
_methods._nodeInit(mkDir)
Copy the code

The general flow is as follows, here are some technology stacks:

1, _nodeSum: in the case of multi-thread asynchronous, it is not very good to know whether all the execution is complete, so this method is adopted (timer is not recommended). 2, _nodeTree: console.log is not perfectCopy the code

_nodeFor: create directory structure for infinite child asynchronous callback

_nodeFor: function (mkDir, path) {
    var self = this
    for (var i = 0; i < mkDir.length; i++) {
      var name = mkDir[i].name
      var child = mkDir[i].child
      var path_block = path ? (path + '/' + name) : name 
      if (name.lastIndexOf('. ') === -1) {/* Select * from */function(path, child, name) {/* Prevent variable contamination after asynchronous callback */ fs.mkdir(path, child, name) {/* Prevent variable contamination after asynchronous callback */ fs.mkdir(path, child, name)function (err) {
            if (err) {
              returnConsole. error(err)} self._nodetree (++self.data.now, path, name) /* Loading loading*/if(child) {self._nodefor (child, path) /* recursion */}})})(path_block, child, name)}else{/* file */ (function (path, val, name) {
          fs.appendFile(path_block, val ? val : ' '.'utf8'.function (err) {
            if (err) {
              returnConsole. error(err)} self._nodeTree(++self.data.now, path, name) /* Loading loading*/})})(path_block, mkDir[I]. Val, name) } } }Copy the code

Technology stack:

This code is not that hard to understand, but it is difficult to debug. After all, there is no guarantee that 40 lines of complex code with recursion and async will be written successfully in one time. Here’s a powerful Node-debug environment that lets you debug in your favorite Google Settings

Technical learning or recommendation

node-inspector
Copy the code

Debugging tool (based on NPM installation) : Node-inspector

Execution process:

1. Install the Node-Inspector

npm install node-inspector -g

2. Listening port (execution)

node-inspector

CMD to your directory to execute node Debug mode

node –debug-brk server.js

4, open the Google browser, type in the address bar above shows the address: http://127.0.0.1:8080/debug? Port =5858 can be debugged, after success will go to the following page, press F8 to execute to the point you interrupted, if not directly end. (Please refresh if not)


_nodeSum: Calculates the total number of executions

    console.log('\x1B[90m' + 'Downloading Current JS to ' + __dirname + '\x1B[39m')
    var self = this
    functionCount (mkDir, j) {/* I is the number, j is the level */for (var i = 0; i < mkDir.length; i++) {
        (function (mkDir, i, j) {
          var log = log_j(j)
          var name = mkDir[i].name.lastIndexOf('. ') === -1 ? mkDir[i].name : ('\x1B[90m' + mkDir[i].name + '\x1B[39m')
          self.data.log += log + The '-' + name + '\n'
          if (mkDir[i].child) {
            count(mkDir[i].child, ++j)
          }
          self.data.sum++
        })(mkDir, i, j ? j : 0)
      }
    }
    function log_j (val) {
      var log = ' '
      if (val === 0) return '|'
      for (var i = 0; i < val; i++) {
        log+ =' ' + '|'
      }
      return '|' + log
    }
    count(arr)
    console.log('\x1B[90m' + 'Altogether contains ' + this.data.sum + 'second Execution process' + '\x1B[90m')
Copy the code

Description:

The tree structure and total number of executions are pre-parsed before executing _nodeFor asynchronously, as long as you pay attention to scope and avoid variable contamination because of the idea of synchronous recursion.

Technology stack:

As mentioned earlier, there is no good way to hear if all asynchronous multithreaded callbacks have been executed, if so please comment below and there is no nice output tree structure, still some flaws.

Technical learning or recommendation

Make your console.log colorfulCopy the code

There are two types, one is written on Node, and one is written on ordinary web page debugging (the two are different).

1, node writing

console.log('\x1B[90m' + 'Hello, Do you think my color has changed?'  + '\x1B[39m')
Copy the code
/* Color reference */'bold'          : ['\x1B[1m'.'\x1B[22m'].'italic'        : ['\x1B[3m'.'\x1B[23m'].'underline'     : ['\x1B[4m'.'\x1B[24m'].'inverse'       : ['\x1B[7m'.'\x1B[27m'].'strikethrough' : ['\x1B[9m'.'\x1B[29m'].'white'         : ['\x1B[37m'.'\x1B[39m'].'grey'          : ['\x1B[90m'.'\x1B[39m'].'black'         : ['\x1B[30m'.'\x1B[39m'].'blue'          : ['\x1B[34m'.'\x1B[39m'].'cyan'          : ['\x1B[36m'.'\x1B[39m'].'green'         : ['\x1B[32m'.'\x1B[39m'].'magenta'       : ['\x1B[35m'.'\x1B[39m'].'red'           : ['\x1B[31m'.'\x1B[39m'].'yellow'        : ['\x1B[33m'.'\x1B[39m'].'whiteBG'       : ['\x1B[47m'.'\x1B[49m'].'greyBG'        : ['\x1B[49;5;8m'.'\x1B[49m'].'blackBG'       : ['\x1B[40m'.'\x1B[49m'].'blueBG'        : ['\x1B[44m'.'\x1B[49m'].'cyanBG'        : ['\x1B[46m'.'\x1B[49m'].'greenBG'       : ['\x1B[42m'.'\x1B[49m'].'magentaBG'     : ['\x1B[45m'.'\x1B[49m'].'redBG'         : ['\x1B[41m'.'\x1B[49m'].'yellowBG'      : ['\x1B[43m'.'\x1B[49m']  
Copy the code

2. Debug writing on the Web side

console.log("%cHello, Do you think my color has changed?" , "color: green")Copy the code

This is easy to read.


_nodeTree: the comparison between the current value and sum creates a real-time progress like CNPM

  _nodeTree: function(now, path, name) {/* Async process interface */ console.log('[' + now + '/' + this.data.sum + ']\x1B[90m ' + name + '\x1B[39m' + '\x1B[32m' + ' installed ' + '\x1B[39m' + 'at ' + path)
    if(now == this.data.sum) {/* When current progress === sum */ console.log(now == this.data.sum)'\x1B[32m' + 'All package installed ' + this.data.sum + ' project installed from ' + __dirname + '\x1B[39m')
      console.log('\x1B[35m' + 'Project catalogue:' + '\x1B[39m')
      console.log(this.data.log + '-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -')
      console.log(", "' ╭ ⌒ ╮ ⌒ ╮. ', ' ' ', ',. 'and,', ' ',. \ n" +
      "╱ ◥ █ █ ◣" 'o', ' ' ', and ', ' ' ' ', ',. \ n" +
      "| tian | Tian Tian",, ". ", ". "\n" +
      "╬ ╬ ╬ ╬ ╬ ╬ ╬ ╬ ╬ ╬ ╬ ╬ ╬ ╬ ╬ ╬ ╬ ╬" + '\n------------------------------------')
      console.log('\x1B[35m' + MAKE: 'o ︻ そ ╆ OVE ▅ ▅ ▅ ▆ ▇ ◤ \ nBLOG:http://blog.csdn.net/mcky_love\nGITHUB:https://github.com/gs3170981' + '\x1B[39m')}}Copy the code

Description:

This is to display the current progress of the tree and my personal information (#^.^#).Copy the code

Real-time current Progress:

Tree after the end

Personal Information


MkDir: an array of arguments

/ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- notice -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1, folder name cannot be the same, the same file name suffix is not the same 2, folder can create child components directory, 3. The folder name cannot be included'. 'Character -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- END -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * / var mkDir = ({name:'csss',
    child: [
      {
        name: 'public.css',
        val: 'body{font-size: 12px; } '
      }, {
        name: 'publicccc',
        child: [
          {
            name: 'asd'}]}]}, {//...... }]Copy the code

Description:

Git git git git git git git git git git git git git git git


A full DEMO

github:https://github.com/gs3170981/cnpmDIY (use word remember star oh!


# # about

Make: o sof f OVE▅▅▅▆ tune Tune Sky

blog:http://blog.csdn.net/mcky_love


conclusion

The custom project structure fits perfectly with the custom framework. It is suitable for visual development, modular collaborative development, single-person project development, multi-person maintenance, etc. There is no specific use here. Fs solves most of the problems for us, and the rest is limited to your imagination!