±à¼ÍƼö: |
±¾ÎÄÀ´×Ô¸öÈ˲©¿Í£¬±¾ÎÄÖ÷Òª½éÉÜÁË¿ª·¢Ò»¸ö½ÅÊּܹ¤¾ß£¬¿ÉÒÔ¸ù¾Ý½»»¥¶¯Ì¬Éú³ÉÏîÄ¿½á¹¹£¬×Ô¶¯Ìí¼ÓÒÀÀµºÍÅäÖ㬲¢ÒƳý²»ÐèÒªµÄÎļþ¡£ |
|
ǰÑÔ
ÎÒÃÇÍŶӵÄǰ¶ËÏîÄ¿ÊÇ»ùÓÚÒ»Ì×ÄÚ²¿µÄºǫ́¿ò¼Ü½øÐпª·¢µÄ£¬ÕâÌ׿ò¼ÜÊÇ»ùÓÚvueºÍElementUI½øÐÐÁËһЩ¶¨ÖÆ»¯°ü×°£¬²¢¼ÓÈëÁËһЩ×Ô¼ºÍŶÓÉè¼ÆµÄÄ£¿é£¬¿ÉÒÔ½øÒ»²½¼ò»¯ºóÌ¨Ò³ÃæµÄ¿ª·¢¹¤×÷¡£
ÕâÌ׿ò¼Ü²ð·ÖΪ»ù´¡×é¼þÄ£¿é£¬Óû§È¨ÏÞÄ£¿é£¬Êý¾Ýͼ±íÄ£¿éÈý¸öÄ£¿é£¬ºǫ́ҵÎñ²ãµÄ¿ª·¢ÖÁÉÙÒª»ùÓÚ»ù´¡×é¼þÄ£¿é£¬¿ÉÒÔ¸ù¾Ý¾ßÌåÐèÒª¼ÓÈëÓû§È¨ÏÞÄ£¿é»òÕßÊý¾Ýͼ±íÄ£¿é¡£¾¡¹ÜvueÌṩÁËһЩ½ÅÊּܹ¤¾ßvue-cli£¬µ«ÓÉÓÚÎÒÃǵÄÏîÄ¿ÊÇ»ùÓÚ¶àÒ³ÃæµÄÅäÖýøÐпª·¢ºÍ´ò°ü£¬Óëvue-cliÉú³ÉµÄÏîÄ¿½á¹¹ºÍÅäÖÃÓÐЩ²»Ò»Ñù£¬ËùÒÔ´´½¨ÏîÄ¿µÄʱºò£¬ÈÔÈ»ÐèÒªÈ˹¤È¥ÐÞ¸ÄºÜ¶àµØ·½£¬ÉõÖÁΪÁË·½±ã£¬Ö±½Ó´Ó֮ǰµÄÏîÄ¿copy¹ýÀ´È»ºó½øÐÐħ¸Ä¡£±íÃæÉÏ¿´ÎÊÌâ²»´ó£¬µ«Æäʵ´æÔںܶàÎÊÌ⣺
1.ÖØ¸´ÐÔ¹¤×÷£¬·±Ëö¶øÇÒÀË·Ñʱ¼ä
2.copy¹ýÀ´µÄÄ£°åÈÝÒ×´æÔÚÎ޹صĴúÂë
3.ÏîÄ¿ÖÐÓкܶàÐèÒªÅäÖõĵط½£¬ÈÝÒ׺öÂÔһЩÅäÖõ㣬½ø¶øÂñ¿Ó
4.È˹¤²Ù×÷ÓÀÔ¶¶¼ÓпÉÄÜ·¸´í£¬½¨ÐÂÏîĿʱ£¬×ÜÒª»¨Ê±¼äÈ¥ÅÅ´í
5.ÄÚ²¿¿ò¼ÜÒ²ÔÚ²»Í£µÄµü´ú£¬È˹¤½¨ÏîÄ¿ÍùÍù²»ÖªµÀ¿ò¼Ü×îеİ汾ºÅÊǶàÉÙ£¬Ê¹Óþɰ汾µÄ¿ò¼Ü¿ÉÄÜ»áÖØÐÂÒýÈëһЩbug
½ÓÏÂÀ´ÕûÀíÒ»ÏÂÎÒµÄÕû¸ö¿ª·¢¾Àú¡£
»ù±¾Ë¼Â·
¿ªÊ¼ß£´úÂë֮ǰ£¬ÏÈÞÛÒ»ÞÛ˼·¡£Æäʵ£¬ÔÚʵÏÖ×Ô¼ºµÄ½ÅÊÖ¼Ü֮ǰ£¬ÎÒ·´¸´ÕûÀí·ÖÎöÁËvue-cliµÄʵÏÖ£¬·¢ÏֺܶàÓÐÒâ˼µÄÄ£¿é£¬²¢´ÓÖÐ½è¼øÁËËüµÄһЩºÃµÄ˼Ïë¡£

vue-cliÊǽ«ÏîĿģ°å×÷Ϊ×ÊÔ´¶ÀÁ¢·¢²¼ÔÚgitÉÏ£¬È»ºóÔÚÔËÐеÄʱºò½«Ä£°åÏÂÔØÏÂÀ´£¬¾¹ýÄ£°åÒýÇæäÖȾ£¬×îºóÉú³É¹¤³Ì¡£ÕâÑù½«ÏîĿģ°åÓ빤¾ß·ÖÀëµÄÄ¿µÄÖ÷ÒªÊÇ£¬ÏîĿģ°å¸ºÔðÏîÄ¿µÄ½á¹¹ºÍÒÀÀµÅäÖ㬽ÅÊּܸºÔðÏîÄ¿¹¹½¨µÄÁ÷³Ì£¬ÕâÁ½²¿·Ö²¢Ã»ÓÐÌ«´óµÄ¹ØÁª£¬Í¨¹ý·ÖÀ룬¿ÉÒÔÈ·±£ÕâÁ½²¿·Ö¶ÀÁ¢Î¬»¤¡£¼ÙÈçÏîÄ¿µÄ½á¹¹¡¢ÒÀÀµÏî»òÕßÅäÖÃÓб䶯£¬Ö»ÐèÒª¸üÐÂÏîĿģ°å¼´¿É¡£
²ÎÕÕvue-cliµÄ˼·£¬ÎÒÒ²½«ÏîĿģ°å¶ÀÁ¢·¢²¼µ½gitÉÏ£¬È»ºóͨ¹ý½ÅÊּܹ¤¾ßÏÂÔØÏÂÀ´£¬¾¹ýÓë½ÅÊּܵĽ»»¥»ñÈ¡ÐÂÏîÄ¿µÄÐÅÏ¢£¬²¢½«½»»¥µÄÊäÈë×÷ΪԪÐÅÏ¢äÖȾÏîĿģ°å£¬×îÖյõ½ÏîÄ¿µÄ»ù´¡½á¹¹¡£
¹¤³Ì½á¹¹
¹¤³Ì»ùÓÚnodejs 8.4ÒÔ¼°ES6½øÐпª·¢£¬Ä¿Â¼½á¹¹ÈçÏÂ
/bin
# ------ ÃüÁîÖ´ÐÐÎļþ
/lib # ------ ¹¤¾ßÄ£¿é
package.json |
ÏÂÃæµÄ²¿·Ö´úÂëÐèÒªÄãÏȶÔPromiseÓÐÒ»¶¨µÄÁ˽â²Å¸üºÃµÄÀí½â¡£
ʹÓÃcommander.js¿ª·¢ÃüÁîÐй¤¾ß
nodejsÄÚÖÃÁ˶ÔÃüÁîÐвÙ×÷µÄÖ§³Ö£¬node¹¤³ÌÏÂpackage.jsonÖеÄbin×ֶοÉÒÔ¶¨ÒåÃüÁîÃûºÍ¹ØÁªµÄÖ´ÐÐÎļþ¡£
{
"name": "macaw-cli",
"version": "1.0.0",
"description": "ÎÒµÄcli",
"bin": {
"macaw": "./bin/macaw.js"
}
} |
¾¹ýÕâÑùÅäÖõÄnodejsÏîÄ¿£¬ÔÚʹÓÃ-gÑ¡Ïî½øÐÐÈ«¾Ö°²×°µÄʱºò£¬»á×Ô¶¯ÔÚϵͳµÄ[prefix]/binĿ¼Ï´´½¨ÏàÓ¦µÄ·ûºÅÁ´½Ó£¨symlink£©¹ØÁªµ½Ö´ÐÐÎļþ¡£Èç¹ûÊDZ¾µØ°²×°£¬Õâ¸ö·ûºÅÁ´½Ó»áÉú³ÉÔÚ./node_modules/.binĿ¼Ï¡£ÕâÑù×öµÄºÃ´¦ÊÇ¿ÉÒÔÖ±½ÓÔÚÖÕ¶ËÖÐÏñÖ´ÐÐÃüÁîÒ»ÑùÖ´ÐÐnodejsÎļþ¡£¹ØÓÚprefix£¬¿ÉÒÔͨ¹ýnpm
config get prefix»ñÈ¡¡£
hello, commander.js
ÔÚbinĿ¼Ï´´½¨Ò»¸ömacaw.jsÎļþ£¬ÓÃÓÚ´¦ÀíÃüÁîÐеÄÂß¼¡£
½ÓÏÂÀ´¾ÍÒªÓõ½githubÉÏһλÉñ¼¶ÈËÎ¡ªtj¡ª¡ª¿ª·¢µÄÄ£¿écommander.js¡£commander.js¿ÉÒÔ×Ô¶¯µÄ½âÎöÃüÁîºÍ²ÎÊý£¬ºÏ²¢¶àÑ¡Ï´¦Àí¶Ì²Î£¬µÈµÈ£¬¹¦ÄÜÇ¿´ó£¬ÉÏÊÖ¼òµ¥¡£¾ßÌåµÄʹÓ÷½·¨¿ÉÒԲμûÏîÄ¿µÄREADME¡£
ÔÚmacaw.jsÖбàдÃüÁîÐеÄÈë¿ÚÂß¼
#!/usr/bin/env
node
const program = require('commander') // npm
i commander -D
program.version('1.0.0')
.usage('<command> [ÏîÄ¿Ãû³Æ]')
.command('hello', 'hello')
.parse(process.argv)
|
½Ó×Å£¬ÔÚbinĿ¼Ï´´½¨macaw-hello.js£¬·ÅÒ»¸ö´òÓ¡Óï¾ä
touch
./bin/macaw-hello.js
echo "console.log('hello, commander')"
> ./bin/macaw-hello.js |
ÕâÑù£¬Í¨¹ýnodeÃüÁî²âÊÔÒ»ÏÂ
node
./bin/macaw.js hello |
²»³öÒâÍ⣬¿ÉÒÔÔÚÖÕ¶ËÉÏ¿´µ½Ò»¾ä»°£ºhello, commander¡£
commanderÖ§³Ögit·ç¸ñµÄ×ÓÃüÁî´¦Àí£¬¿ÉÒÔ¸ù¾Ý×ÓÃüÁî×Ô¶¯Òýµ¼µ½ÒÔÌØ¶¨¸ñʽÃüÃûµÄÃüÁîÖ´ÐÐÎļþ£¬ÎļþÃûµÄ¸ñʽÊÇ[command]-[subcommand]£¬ÀýÈ磺
1.macaw hello => macaw-hello
2.macaw init => macaw-init
¶¨Òåinit×ÓÃüÁî
ÎÒÃÇÐèҪͨ¹ýÒ»¸öÃüÁîÀ´Ð½¨ÏîÄ¿£¬°´ÕÕ³£ÓõÄһЩÃû´Ê£¬ÎÒÃÇ¿ÉÒÔ¶¨ÒåÒ»¸öÃûΪinitµÄ×ÓÃüÁî¡£
¶Ôbin/macaw.js×öһЩ¸Ä¶¯¡£
const
program = require('commander')
program.version('1.0.0')
.usage('<command> [ÏîÄ¿Ãû³Æ]')
.command('init', '´´½¨ÐÂÏîÄ¿')
.parse(process.argv)
|
ÔÚbinĿ¼Ï´´½¨Ò»¸öinitÃüÁî¹ØÁªµÄÖ´ÐÐÎļþ
touch
./bin/macaw-init.js |
Ìí¼ÓÈçÏ´úÂë
#!/usr/bin/env
node
const program = require('commander')
program.usage('<project-name>').parse(process.argv)
// ¸ù¾ÝÊäÈ룬»ñÈ¡ÏîÄ¿Ãû³Æ
let projectName = program.args[0]
if (!projectName) { // project-name ±ØÌî
// Ï൱ÓÚÖ´ÐÐÃüÁîµÄ--helpÑ¡ÏÏÔʾhelpÐÅÏ¢£¬ÕâÊÇcommanderÄÚÖõÄÒ»¸öÃüÁîÑ¡Ïî
program.help()
return
}
go()
function go () {
// Ô¤Áô£¬´¦Àí×ÓÃüÁî
}
|
×¢ÒâµÚÒ»ÐÐ#!/usr/bin/env nodeÊǸÉÂïµÄ£¬Óиö¹Ø¼ü´Ê½ÐShebang£¬²»Á˽âµÄ¿ÉÒÔÈ¥ËÑËÑ¿´
project-nameÊDZØÌî²ÎÊý£¬²»¹ý£¬ÎÒÏë¶Ôproject-name½øÐÐһЩ×Ô¶¯»¯µÄ´¦Àí¡£
µ±Ç°Ä¿Â¼Îª¿Õ£¬Èç¹ûµ±Ç°Ä¿Â¼µÄÃû³ÆºÍproject-nameÒ»Ñù£¬ÔòÖ±½ÓÔÚµ±Ç°Ä¿Â¼Ï´´½¨¹¤³Ì£¬·ñÔò£¬ÔÚµ±Ç°Ä¿Â¼Ï´´½¨ÒÔproject-name×÷ΪÃû³ÆµÄĿ¼×÷Ϊ¹¤³ÌµÄ¸ùĿ¼
µ±Ç°Ä¿Â¼²»Îª¿Õ£¬Èç¹ûĿ¼Öв»´æÔÚÓëproject-nameͬÃûµÄĿ¼£¬Ôò´´½¨ÒÔproject-name×÷ΪÃû³ÆµÄĿ¼×÷Ϊ¹¤³ÌµÄ¸ùĿ¼£¬·ñÔòÌáʾÏîÄ¿ÒѾ´æÔÚ£¬½áÊøÃüÁîÖ´ÐС£
¸ù¾ÝÒÔÉÏÉ趨£¬ÔÙ¶ÔÖ´ÐÐÎļþ×öһЩÍêÉÆ
#!/usr/bin/env
node
const program = require('commander')
const path = require('path')
const fs = require('fs')
const glob = require('glob') // npm i glob -D
program.usage('<project-name>')
// ¸ù¾ÝÊäÈ룬»ñÈ¡ÏîÄ¿Ãû³Æ
let projectName = program.args[0]
if (!projectName) { // project-name ±ØÌî
// Ï൱ÓÚÖ´ÐÐÃüÁîµÄ--helpÑ¡ÏÏÔʾhelpÐÅÏ¢£¬ÕâÊÇcommanderÄÚÖõÄÒ»¸öÃüÁîÑ¡Ïî
program.help()
return
}
const list = glob.sync('*') // ±éÀúµ±Ç°Ä¿Â¼
let rootName = path.basename(process.cwd())
if (list.length) { // Èç¹ûµ±Ç°Ä¿Â¼²»Îª¿Õ
if (list.filter(name => {
const fileName = path.resolve(process.cwd(),
path.join('.', name))
const isDir = fs.stat(fileName).isDirectory()
return name.indexOf(projectName) !== -1 &&
isDir
}).length !== 0) {
console.log(`ÏîÄ¿${projectName}ÒѾ´æÔÚ`)
return
}
rootName = projectName
} else if (rootName === projectName) {
rootName = '.'
} else {
rootName = projectName
}
go()
function go () {
// Ô¤Áô£¬´¦Àí×ÓÃüÁî
console.log(path.resolve(process.cwd(), path.join('.',
rootName)))
}
|
ËæÒâÕÒ¸ö·¾¶Ï½¨Ò»¸ö¿ÕĿ¼£¬È»ºóÔÚÕâ¸öĿ¼ÏÂÖ´ÐÐÔÛÃǶ¨ÒåµÄ³õʼ»¯ÃüÁî
node
/[pathto]/macaw-cli/bin/macaw.js init hello-cli |
Õý³£µÄ»°£¬¿ÉÒÔ¿´µ½ÖÕ¶ËÉÏ´òÓ¡³öÏîÄ¿µÄ·¾¶¡£

ʹÓÃdownload-git-repoÏÂÔØÄ£°å
ÏÂÔØÄ£°åµÄ¹¤¾ßÓõ½ÁíÍâÒ»¸önodeÄ£¿édownload-git-repo£¬²ÎÕÕÏîÄ¿µÄREADME£¬¶ÔÏÂÔØ¹¤¾ß½øÐмòµ¥µÄ·â×°¡£
ÔÚlibĿ¼Ï´´½¨Ò»¸ödownload.js
const
download = require('download-git-repo')
module.exports = function (target) {
target = path.join(target || '.', '.download-temp')
return new Promise(resolve, reject) {
// ÕâÀï¿ÉÒÔ¸ù¾Ý¾ßÌåµÄÄ£°åµØÖ·ÉèÖÃÏÂÔØµÄurl£¬×¢Ò⣬Èç¹ûÊÇgit£¬urlºóÃæµÄbranch²»ÄܺöÂÔ
download('https://github.com:username/templates-repo.git#master',
target, { clone: true }, (err) => {
if (err) {
reject(err)
} else {
// ÏÂÔØµÄÄ£°å´æ·ÅÔÚÒ»¸öÁÙʱ·¾¶ÖУ¬ÏÂÔØÍê³Éºó£¬¿ÉÒÔÏòÏÂ֪ͨÕâ¸öÁÙʱ·¾¶£¬ÒÔ±ãºóÐø´¦Àí
resolve(target)
}
})
}
}
|
download-git-repoÄ£¿é±¾ÖÊÉϾÍÊÇÒ»¸ö·½·¨£¬Ëü×ñÑnode.jsµÄCPS£¬Óûص÷µÄ·½Ê½´¦ÀíÒì²½½á¹û¡£Èç¹ûÊìϤnode.jsµÄ»°£¬Ó¦¸Ã¶¼ÖªµÀÕâÑù´¦Àí´æÔÚÒ»¸ö±×¶Ë£¬ÎÒ°ÑËü½øÐÐÁË·â×°£¬×ª»»³ÉÏÖÔÚ¸ü¼ÓÁ÷ÐеÄPromiseµÄ·ç¸ñ´¦ÀíÒì²½¡£
ÔÙÒ»´Î¶Ô֮ǰµÄmacaw-init.js½øÐÐÐÞ¸Ä
const
download = require('./lib/download')
... // ֮ǰµÄÊ¡ÂÔ
function go () {
download(rootName)
.then(target => console.log(target))
.catch(err => console.log(err))
}
|
ÏÂÔØÍê³ÉÖ®ºó£¬ÔÙ½«ÁÙʱÏÂÔØÄ¿Â¼ÖеÄÏîĿģ°åÎļþ×ªÒÆµ½ÏîĿĿ¼ÖУ¬Ò»¸ö¼òµ¥µÄ½ÅÊÖ¼ÜËãÊÇ»ù±¾Íê³ÉÁË¡£×ªÒƵľßÌåʵÏÖ·½·¨¾Í²»Ï¸ËµÁË£¬¿ÉÒԲμûnode.jsµÄAPI¡£ÄãµÄnode.js°æ±¾Èç¹ûÔÚ8ÒÔÏ£¬¿ÉÒÔÓÃstreamºÍpipeµÄ·½Ê½ÊµÏÖ£¬Èç¹ûÊÇ8»òÕß9£¬¿ÉÒÔʹÓÃеÄAPI¡ª¡ªcopyFile()»òÕßcopyFileSync()¡£
but...
Õâ¸öÊÀ½ç²¢·ÇÎÒÃÇÏëÏóµÄÄÇô¼òµ¥¡£ÎÒÃÇ¿ÉÄÜ»áÏ£ÍûÏîĿģ°åÖÐÓÐЩÎļþ»òÕß´úÂë¿ÉÒÔ¶¯Ì¬´¦Àí¡£±ÈÈ磺
ÐÂÏîÄ¿µÄÃû³Æ¡¢°æ±¾ºÅ¡¢ÃèÊöµÈÐÅÏ¢µÈ£¬¿ÉÒÔͨ¹ý½ÅÊּܵĽ»»¥½øÐÐÊäÈ룬Ȼºó½«ÊäÈë²åÈ뵽ģ°åÖÐ
ÏîĿģ°å²¢·ÇËùÓÐÎļþ¶¼»áÓõ½£¬¿ÉÒÔͨ¹ý½ÅÊÖ¼ÜÌṩµÄÑ¡ÏîÒÆ³ýµôÄÇЩÎÞÓõÄÎļþ»òÕßĿ¼¡£
¶ÔÓÚÕâÀàÇé¿ö£¬ÎÒÃÇ»¹ÐèÒª½èÖúÆäËû¹¤¾ß°üÀ´Íê³É¡£
ʹÓÃinquirer.js´¦ÀíÃüÁîÐн»»¥
¶ÔÓÚÃüÁîÐн»»¥µÄ¹¦ÄÜ£¬¿ÉÒÔÓÃinquirer.jsÀ´´¦Àí¡£Ó÷¨ÆäʵºÜ¼òµ¥£º
const
inquirer = require('inquirer') // npm i inquirer
-D
inquirer.prompt([
{
name: 'projectName',
message: 'ÇëÊäÈëÏîÄ¿Ãû³Æ'
}
]).then(answers => {
console.log(`ÄãÊäÈëµÄÏîÄ¿Ãû³ÆÊÇ£º${answers.projectName}`)
})
|
prompt()½ÓÊÜÒ»¸öÎÊÌâ¶ÔÏóµÄÊý¾Ý£¬ÔÚÓû§ÓëÖն˽»»¥¹ý³ÌÖУ¬½«Óû§µÄÊäÈë´æ·ÅÔÚÒ»¸ö´ð°¸¶ÔÏóÖУ¬È»ºó·µ»ØÒ»¸öPromise£¬Í¨¹ýthen()»ñÈ¡µ½Õâ¸ö´ð°¸¶ÔÏó¡£so
easy£¡
½ÓÏÂÀ´¼ÌÐø¶Ômacaw-init.js½øÐÐÍêÉÆ¡£
//
...
const inquirer = require('inquirer')
const list = glob.sync('*')
let next = undefined
if (list.length) {
if (list.filter(name => {
const fileName = path.resolve(process.cwd(),
path.join('.', name))
const isDir = fs.stat(fileName).isDirectory()
return name.indexOf(projectName) !== -1 &&
isDir
}).length !== 0) {
console.log(`ÏîÄ¿${projectName}ÒѾ´æÔÚ`)
return
}
next = Promise.resolve(projectName)
} else if (rootName === projectName) {
next = inquirer.prompt([
{
name: 'buildInCurrent',
message: 'µ±Ç°Ä¿Â¼Îª¿Õ£¬ÇÒĿ¼Ãû³ÆºÍÏîÄ¿Ãû³ÆÏàͬ£¬ÊÇ·ñÖ±½ÓÔÚµ±Ç°Ä¿Â¼Ï´´½¨ÐÂÏîÄ¿£¿'
type: 'confirm',
default: true
}
]).then(answer => {
return Promise.resolve(answer.buildInCurrent
? '.' : projectName)
})
} else {
next = Promise.resolve(projectName)
}
next && go()
function go () {
next.then(projectRoot => {
if (projectRoot !== '.') {
fs.mkdirSync(projectRoot)
}
return download(projectRoot).then(target =>
{
return {
projectRoot,
downloadTemp: target
}
})
})
}
|
Èç¹ûµ±Ç°Ä¿Â¼Êǿյ쬲¢ÇÒĿ¼Ãû³ÆºÍÏîÄ¿Ãû³ÆÏàͬ£¬ÄÇô¾Íͨ¹ýÖն˽»»¥µÄ·½Ê½È·ÈÏÊÇ·ñÖ±½ÓÔÚµ±Ç°Ä¿Â¼Ï´´½¨ÏîÄ¿£¬ÕâÑù»áÈýÅÊּܸü¼ÓÈËÐÔ»¯¡£
Ç°ÃæÌáµ½£¬ÐÂÏîÄ¿µÄÃû³Æ¡¢°æ±¾ºÅ¡¢ÃèÊöµÈÐÅÏ¢¿ÉÒÔÖ±½Óͨ¹ýÖն˽»»¥²åÈëµ½ÏîĿģ°åÖУ¬ÄÇôÔÙ½øÒ»²½ÍêÉÆ½»»¥Á÷³Ì¡£
//
...
// Õâ¸öÄ£¿é¿ÉÒÔ»ñÈ¡node°üµÄ×îа汾
const latestVersion = require('latest-version')
// npm i latest-version -D
// ...
function go () {
next.then(projectRoot => {
if (projectRoot !== '.') {
fs.mkdirSync(projectRoot)
}
return download(projectRoot).then(target =>
{
return {
name: projectRoot,
root: projectRoot,
downloadTemp: target
}
})
}).then(context => {
return inquirer.prompt([
{
name: 'projectName',
message: 'ÏîÄ¿µÄÃû³Æ',
default: context.name
}, {
name: 'projectVersion',
message: 'ÏîÄ¿µÄ°æ±¾ºÅ',
default: '1.0.0'
}, {
name: 'projectDescription',
message: 'ÏîÄ¿µÄ¼ò½é',
default: `A project named ${context.name}`
}
]).then(answers => {
return latestVersion('macaw-ui').then(version
=> {
answers.supportUiVersion = version
return {
...context,
metadata: {
...answers
}
}
}).catch(err => {
return Promise.reject(err)
})
})
}).then(context => {
console.log(context)
}).catch(err => {
console.error(err)
})
}
|
ÏÂÔØÍê³Éºó£¬ÌáʾÓû§ÊäÈëÐÂÏîÄ¿ÐÅÏ¢¡£µ±È»£¬½»»¥µÄÎÊÌâ²»½öÏÞÓÚ´Ë£¬¿ÉÒÔ¸ù¾Ý×Ô¼ºÏîÄ¿µÄÇé¿ö£¬Ìí¼Ó¸ü¶àµÄ½»»¥ÎÊÌâ¡£inquirer.jsÇ¿´óµÄµØ·½ÔÚÓÚ£¬Ö§³ÖºÜ¶àÖÖ½»»¥ÀàÐÍ£¬³ýÁ˼òµ¥µÄinput£¬»¹ÓÐconfirm¡¢list¡¢password¡¢checkboxµÈ£¬¾ßÌå¿ÉÒԲμûÏîÄ¿µÄREADME¡£
È»ºó£¬Ôõô°ÑÕâЩÊäÈëµÄÄÚÈݲåÈ뵽ģ°åÖÐÄØ£¬ÕâʱºòÓÖÓõ½ÁíÍâÒ»¸ö¼òµ¥µ«ÓÖ²»¼òµ¥µÄ¹¤¾ß°ü¡ª¡ªmetalsmith¡£
ʹÓÃmetalsmith´¦ÀíÄ£°å
ÒýÓùÙÍøµÄ½éÉÜ£º
An
extremely simple, pluggable static site generator. |
Ëü¾ÍÊÇÒ»¸ö¾²Ì¬ÍøÕ¾Éú³ÉÆ÷£¬¿ÉÒÔÓÃÔÚÅúÁ¿´¦ÀíÄ£°åµÄ³¡¾°£¬ÀàËÆµÄ¹¤¾ß°ü»¹ÓÐWintersmith¡¢Assemble¡¢Hexo¡£Ëü×î´óµÄÒ»¸öÌØµã¾ÍÊÇEVERYTHING
IS PLUGIN£¬ËùÒÔ£¬metalsmith±¾ÖÊÉϾÍÊÇÒ»¸ö½ºË®¿ò¼Ü£¬Í¨¹ýð¤ºÏ¸÷ÖÖ²å¼þÀ´Íê³ÉÉú²ú¹¤×÷¡£
¸øÏîĿģ°åÌí¼Ó±äÁ¿Õ¼Î»·û
Ä£°åÒýÇæÎÒÑ¡Ôñhandlebars¡£µ±È»£¬»¹¿ÉÒÔÓÐÆäËûÑ¡Ôñ£¬ÀýÈçejs¡¢jade¡¢swig¡£
ÓÃhandlebarsµÄÓï·¨¶ÔÄ£°å×öһЩµ÷Õû£¬ÀýÈçÐÞ¸ÄÄ£°åÖеÄpackage.json
{
"name": "{{projectName}}",
"version": "{{projectVersion}}",
"description": "{{projectDescription}}",
"author": "Forcs Zhang",
"private": true,
"scripts": {
"dev": "node build/dev-server.js",
"start": "node build/dev-server.js",
"build": "node build/build.js",
"unit": "cross-env BABEL_ENV=test
karma start test/unit/karma.conf.js --single-run",
"test": "npm run unit",
"lint": "eslint --ext .js,.vue
src test/unit/specs"
},
"dependencies": {
"element-ui": "^2.0.7",
"macaw-ui": "{{supportUiVersion}}",
"vue": "^2.5.2",
"vue-router": "^2.3.1"
},
...
}
|
package.jsonµÄname¡¢version¡¢description×ֶεÄÄÚÈݱ»Ìæ»»³ÉÁËhandlebarÓï·¨µÄռλ·û£¬Ä£°åÖÐÆäËûµØ·½Ò²×öÀàËÆµÄÌæ»»£¬Íê³ÉºóÖØÐÂÌύģ°åµÄ¸üС£
ʵÏÖ½ÅÊּܸøÄ£°å²åÖµµÄ¹¦ÄÜ
ÔÚlibĿ¼Ï´´½¨generator.js£¬·â×°metalsmith¡£
//
npm i handlebars metalsmith -D
const Metalsmith = require('metalsmith')
const Handlebars = require('handlebars')
const rm = require('rimraf').sync
module.exports = function (metadata = {}, src,
dest = '.') {
if (!src) {
return Promise.reject(new Error(`ÎÞЧµÄsource£º${src}`))
}
return new Promise((resolve, reject) => {
Metalsmith(process.cwd())
.metadata(metadata)
.clean(false)
.source(src)
.destination(dest)
.use((files, metalsmith, done) => {
const meta = metalsmith.metadata()
Object.keys(files).forEach(fileName => {
const t = files[fileName].contents.toString()
files[fileName].contents = new Buffer(Handlebars.compile(t)(meta))
})
done()
}).build(err => {
rm(src)
err ? reject(err) : resolve()
})
})
}
|
¸ømacaw-init.jsµÄgo()Ìí¼ÓÉú³ÉÂß¼¡£
//
...
const generator = require('../lib/generator')
function go () {
next.then(projectRoot => {
// ...
}).then(context => {
// Ìí¼ÓÉú³ÉµÄÂß¼
return generator(context)
}).then(context => {
console.log('´´½¨³É¹¦:)')
}).catch(err => {
console.error(`´´½¨Ê§°Ü£º${err.message}`)
})
}
|
ÖÁ´Ë£¬Ò»¸ö´ø½»»¥£¬¿É¶¯Ì¬¸øÄ£°å²åÖµµÄ½ÅÊÖ¼ÜËãÊÇ»ù±¾Íê³ÉÁË¡£
tips£ºÇ½ÁÑÍÆ¼öÒ»ÏÂtjµÄÁíÒ»¸ö¹¤¾ß°ü£ºconsolidate.js£¬ÔÚvue-cliÖз¢Ïֵ쬏ÐÐËȤµÄ»°¿ÉÒÔÈ¥Á˽âһϡ£
ÃÀ»¯ÎÒÃǵĽÅÊÖ¼Ü
ͨ¹ýһЩ¹¤¾ß°ü£¬ÈýÅÊּܸü¼ÓÈËÐÔ»¯¡£ÕâÀï½éÉÜÁ½¸öÔÚvue-cliÖз¢ÏֵŤ¾ß°ü£º
ora - ÏÔʾspinner
chalk - ¸ø¿ÝÔïµÄÖն˽çÃæÌí¼ÓһЩɫ²Ê
ÕâÁ½¸ö¹¤¾ß°üÓÃÆðÀ´²»¸´ÔÓ£¬ÓúÃÁË»áÈýÅÊּܿ´ÆðÀ´¸ü¼Ó¸ß´óÉÏ
ÓÃoraÓÅ»¯¼ÓÔØµÈ´ýµÄ½»»¥
ora¿ÉÒÔÓÃÔÚ¼ÓÔØµÈ´ýµÄ³¡¾°ÖУ¬±ÈÈç½ÅÊÖ¼ÜÖÐÏÂÔØÏîĿģ°åµÄʱºò¿ÉÒÔʹÓã¬Èç¹û¸øÄ£°å²åÖµÉú³ÉÏîÄ¿µÄ¹ý³ÌÒ²ÓÐÃ÷ÏԵȴýµÄ»°£¬Ò²¿ÉÒÔʹÓá£
ÒÔÏÂÔØÎªÀý£¬¶Ôdownload.js×öһЩ¸ÄÁ¼£º
npm i ora -D
const
download = require('download-git-repo')
const ora = require('ora')
module.exports = function (target) {
target = path.join(target || '.', '.download-temp')
return new Promise(resolve, reject) {
const url = 'https://github.com:username/templates-repo.git#master'
const spinner = ora(`ÕýÔÚÏÂÔØÏîĿģ°å£¬Ô´µØÖ·£º${url}`)
spinner.start()
download(url, target, { clone: true }, (err)
=> {
if (err) {
spinner.fail() // wrong :(
reject(err)
} else {
spinner.succeed() // ok :)
resolve(target)
}
})
}
}
|
ÓÃchalkÓÅ»¯ÖÕ¶ËÐÅÏ¢µÄÏÔʾЧ¹û
chalk¿ÉÒÔ¸øÖÕ¶ËÎÄ×ÖÉèÖÃÑÕÉ«¡£
//
...
const chalk = require('chalk')
const logSymbols = require('log-symbols')
// ...
function go () {
// ...
next.then(/* ... */)
/* ... */
.then(context => {
// ³É¹¦ÓÃÂÌÉ«ÏÔʾ£¬¸ø³ö»ý¼«µÄ·´À¡
console.log(logSymbols.success, chalk.green('´´½¨³É¹¦:)'))
console.log()
console.log(chalk.green('cd ' + context.root
+ '\nnpm install\nnpm run dev'))
}).catch(err => {
// ʧ°ÜÁËÓúìÉ«£¬ÔöÇ¿Ìáʾ
console.error(logSymbols.error, chalk.red(`´´½¨Ê§°Ü£º${error.message}`))
})
}
|

¸ù¾ÝÊäÈëÏîÒÆ³ýÄ£°åÖв»ÐèÒªµÄÎļþ
ÓÐʱºò£¬ÏîĿģ°åÖв¢²»ÊÇËùÓÐÎļþ¶¼ÊÇÐèÒªµÄ¡£ÎªÁ˱£Ö¤ÐÂÉú³ÉµÄÏîÄ¿Öо¡¿ÉÄܵIJ»´æÔÚÔà´úÂ룬ÎÒÃÇ¿ÉÄÜÐèÒª¸ù¾Ý½ÅÊּܵÄÊäÈëÏîÀ´È·ÈÏ×îÖÕÉú³ÉµÄÏîÄ¿½á¹¹£¬½«Ã»ÓõÄÎļþ»òÕßÄ¿Â¼ÒÆ³ý¡£±ÈÈçvue-cli£¬´´½¨ÏîĿʱ»áѯÎÊÎÒÃÇÊÇ·ñÐèÒª¼ÓÈë²âÊÔÄ£¿é£¬Èç¹û²»ÐèÒª£¬×îÖÕÉú³ÉµÄÏîÄ¿´úÂëÖÐÊDz»°üº¬²âÊÔÏà¹ØµÄ´úÂëµÄ¡£Õâ¸ö¹¦ÄÜÈçºÎʵÏÖÄØ£¿
ʵÏÖµÄ˼·
ÎҲο¼ÁËgitµÄ˼·£¬¶¨Òå¸öignoreÎļþ£¬½«ÐèÒª±»ºöÂÔµÄÎļþÃûÁÐÔÚÕâ¸öignoreÎļþÀÅäÉÏÄ£°åÓï·¨¡£½ÅÊÖ¼ÜÔÚÉú³ÉÏîÄ¿µÄʱºò£¬¸ù¾ÝÊäÈëÏîÏÈäÖȾÕâ¸öignoreÎļþ£¬È»ºó¸ù¾ÝignoreÎļþµÄÄÚÈÝÒÆ³ý²»ÐèÒªµÄÄ£°åÎļþ£¬È»ºóÔÙäÖÈ¾ÕæÕý»áÓõ½µÄÏîĿģ°å£¬×îÖÕÉú³ÉÏîÄ¿¡£

ʵÏÖ·½°¸
¸ù¾ÝÒÔÉÏ˼·£¬ÎÒÏȶ¨ÒåÁËÊôÓÚÎÒÃÇÏîÄ¿×Ô¼ºµÄignoreÎļþ£¬È¡ÃûΪtemplates.ignore¡£
È»ºóÔÚÕâ¸öignoreÎļþÖÐÌí¼ÓÐèÒª±»ºöÂÔµÄÎļþÃû¡£
{{#unless
supportMacawAdmin}}
# Èç¹û²»¿ªÆôadminºǫ́£¬µÇÂ¼Ò³ÃæºÍÃÜÂëÐÞ¸ÄÒ³ÃæÊDz»ÐèÒªµÄ
src/entry/login.js
src/entry/password.js
{{/unless}}
# ×îÖÕÉú³ÉµÄÏîÄ¿Öв»ÐèÒªignoreÎÄ×Ö×ÔÉí
templates.ignore
|
È»ºóÔÚlib/generator.jsÖÐÌí¼Ó¶Ôtemplates.ignoreµÄ´¦ÀíÂß¼
//
...
const minimatch = require('minimatch') // https://github.com/isaacs/minimatch
module.exports = function (metadata = {},
src, dest = '.')
{if (!src) {
return Promise.reject(new Error(`ÎÞЧµÄsource£º${src}`))
}
return new Promise((resolve, reject) => {
const metalsmith = Metalsmith(process.cwd())
.metadata(metadata)
.clean(false)
.source(src)
.destination(dest)
// ÅжÏÏÂÔØµÄÏîĿģ°åÖÐÊÇ·ñÓÐtemplates.ignore
const ignoreFile = path.join(src, 'templates.ignore')
if (fs.existsSync(ignoreFile)) {
// ¶¨ÒåÒ»¸öÓÃÓÚÒÆ³ýÄ£°åÖб»ºöÂÔÎļþµÄmetalsmith²å¼þ
metalsmith.use((files, metalsmith, done) =>
{
const meta = metalsmith.metadata()
// ÏȶÔignoreÎļþ½øÐÐäÖȾ£¬È»ºó°´ÐÐÇиîignore
ÎļþµÄÄÚÈÝ£¬Äõ½±»ºöÂÔÇåµ¥
const ignores = Handlebars.compile(fs.readFile
Sync(ignoreFile).
toString())(meta)
.split('\n').filter(item => !!item.length)
Object.keys(files).forEach(fileName => {
// ÒÆ³ý±»ºöÂÔµÄÎļþ
ignores.forEach(ignorePattern => {
if (minimatch(fileName, ignorePattern)) {
delete files[fileName]
}
})
})
done()
})
}
metalsmith.use((files, metalsmith, done) =>
{
const meta = metalsmith.metadata()
Object.keys(files).forEach(fileName => {
const t = files[fileName].contents.toString()
files[fileName].contents = new Buffer(Handlebars.compile(t)(meta))
})
done()
}).build(err => {
rm(src)
err ? reject(err) : resolve()
})
})
} |
»ùÓÚ²å¼þ˼ÏëµÄmetalsmithºÜºÃÀ©Õ¹£¬ÊµÏÖÒ²²»¸´ÔÓ£¬¾ßÌå¹ý³Ì¿É²Î¼û´úÂëÖеÄ×¢ÊÍ¡£
×ܽá
¾¹ý¶Ôvue-cliµÄÕûÀí£¬½èÖúÁ˺ܶànodeÄ£¿é£¬Õû¸ö½ÅÊּܵÄʵÏÖ²¢²»¸´ÔÓ¡£
1.½«ÏîĿģ°åÓë½ÅÊּܹ¤¾ß·ÖÀ룬¿ÉÒÔ¸üºÃµÄά»¤Ä£°åºÍ½ÅÊּܹ¤¾ß¡£
2.ͨ¹ýcommander.js´¦ÀíÃüÁîÐÐ
3.ͨ¹ýdownload-git-repo´¦ÀíÏÂÔØ
4.ͨ¹ýinquirer.js´¦ÀíÖն˽»»¥
5.ͨ¹ýmetalsmithºÍÄ£°åÒýÇæ½«½»»¥ÊäÈëÏî²åÈëµ½ÏîĿģ°åÖÐ
²Î¿¼ÁËgitµÄignoreµÄ˼·£¬ÀûÓÃ×Ô¶¨ÒåµÄtemplates.ignore¶¯Ì¬»¯µÄÒÆ³ý²»±ØÒªµÄÎļþºÍĿ¼
ÒÔÉϾÍÊÇÎÒ¿ª·¢½ÅÊּܵÄÖ÷Òª¾Àú£¬Öм仹Óкܶ಻×ãµÄµØ·½£¬½ñºóÔÙÂýÂýÍêÉÆ°É¡£
×îºó˵һÏ£¬Æäʵvue-cliÄÜ×öµÄÊÂÇ黹Óкܶ࣬¾ßÌåµÄ¿ÉÒÔ¿´¿´ÏîÄ¿µÄREADMEºÍÔ´Âë¡£¹ØÓÚ½ÅÊּܵĿª·¢£¬²»Ò»¶¨ÒªÍêÈ«Ôì¸öÂÖ×Ó£¬¿ÉÒÔ¿´¿´ÁíÍâÒ»¸öºÜÇ¿´óµÄÄ£¿éYEOMAN£¬½èÖúÕâ¸öÄ£¿éÒ²¿ÉÒԺܿìµÄʵÏÖ×Ô¼ºµÄ½ÅÊּܹ¤¾ß¡£
|