脚手架
2020-04-16 11:08:53 0 举报
AI智能生成
前端脚手架开发
作者其他创作
大纲/内容
必备模块
commander
参数解析
inquirer
交互式命令行工具
download-git-repo
在 git 中下载模板
chalk
命令行中画颜色
metalsmith
读取所有文件,实现模板渲染
consolidate
统一了所有的模版引擎
将命令链接到全局
创建执行文件<br>
建立 bin 文件夹,<br>一般新增名为 www 的可执行文件<br>
<font color="#c41230"><b>#! /usr/bin/env node</b></font><br><br>require('./src/main.js')
shebang line
<b>Shebang line 指定脚本的解释程序<br><br>#!/usr/bin/env node is an instance of a shebang line: the very first line in an executable plain-text file</b> on Unix-like platforms that<b> tells the system what interpreter to pass that file to for execution</b>, via the command line following the magic #! prefix (called shebang).<br>
Note: <b>Windows does not support shebang lines</b>, so they're effectively ignored there; on Windows it is solely a given file's filename extension that determines what executable will interpret it. <b>However, you still need them in the context of npm</b>.<br>
注册执行命令
package.json 中新增 bin 属性
{<br>...<div>"bin":{<br> "zhu-cli":"./bin/www"<br>}<br>}</div><br>
<b>install one or more executable files into the PATH. </b><br><br>A bin field is a map of command name to local file name. <b>On install, npm will symlink that file into prefix/bin for global installs, or ./node_modules/.bin/ for local installs.</b><br>
symlink a package folder
在当前文件夹命令行中执行 npm link
npm link
用法
npm link (in package dir)
描述
npm link in a package folder will create a symlink in the global folder {prefix}/lib/node_modules/<package> that links to the package where the npm link command was executed. (see npm-config for the value of prefix). It will also link any bins in the package to {prefix}/bin/{name}.
安装 eslint 并初始化 eslint 配置文件
初始化配置文件
npx eslint --init
解析用户传递的参数
commander
src/main.js:<br><br>const program = require('commander')<br><br><b>program.parse(process.argv)</b><br>
Reflect.ownKeys(mapActions).forEach(action => {<br> program<br> .command(action)<br> .alias(mapActions[action].alias)<br> .description(mapActions[action].description)<br> .action(() => {<br> console.log(action);<br> if (action === "*") {<br> console.log(mapActions[action].description);<br> } else {<br> console.log(action);<br> // zhu-cli create xxx<br> // => process.argv 为 [node,zhu-cli,create,xxx]<br><b> require(path.resolve(__dirname,action))(...process.argv.slice(3))</b><br> }<br> });<br>});<br><br><b>program.on("--help"</b>, () => {<br> console.log("\nExamples:");<br> Reflect.ownKeys(mapActions).forEach(action => {<br> mapActions[action].examples.forEach(example => {<br> console.log(` ${example}`);<br> });<br> });<br>});<br>
拉取 github 数据
github api 文档
请求接口时 loading 状态
ora 包
让用户选择分支
inquirer 包
const { repo } = await Inquirer.prompt({<br> name:'repo',<br> type:'list',<br> message:'please choose a template to create project',<br> choices:repos<br>})<br>
存储模板
获取存储模板的位置
const downloadDirectory = `${process.env[process.platform === 'darwin' ? 'HOME' : 'USERPROFILE']}/.template`
下载 git 模板
download-git-repo
将回调方式转换成 promise 方式
<b>const { promisify } = require('util')<br></b>let downloadGitRepo = require('download-git-repo');<br><br>downloadGitRepo = promisify(downloadGitRepo)
把模板放在 /usr/xxx/.template 里存好,以备后期使用
const download = async (repo, tag) => {<br> let api = `zhu-cli/${repo}`;<br> if (tag) {<br> api += `#${tag}`;<br> }<br> const dest = `${downloadDirectory}/${repo}`;<br> await downloadGitRepo(api, dest);<br> return dest;<br>};<br>
将下载好的模板拷贝到当前执行命令下的目录
ncp 包
// 返回的 result 是下载的目录<br>const result = await waitFnloading(download, 'download template')(repo, tag);<br><br>await ncp(result, <b>path.resolve(projectName)</b>)<br>
path.resolve 如果在处理完所有给定的 path 片段之后还未生成绝对路径,则再加上当前工作目录。
渲染复杂的模板
根据是否有 ask.js 文件来判断是否是复杂模板<br><br>if(!<b>fs.existsSync(path.join(result,'ask.js'))</b>){<br> await ncp(result,path.resolve(projectName))<br>}else{<br><br>}<br>
简单
复杂
const Metalsmith = require("metalsmith");<br>let { render } = require("consolidate").ejs;<br><br>render = promisify(render)<br><br>if(!fs.existSync(path.join(result,'ask.js'))){<br> await ncp(result,path.resolve(projectName))<br>}else{<br> await new Promise((resolve,reject)=>{<br> Metalsmith(__dirname) // 传入路径会默认遍历当前路径下的 src 文件夹<br> .source(result)<br> .destination(path.resolve(projectName))<br> .use((files, metal, done) => {<br> const args = require(path.join(result,'ask.js'))<br> const obj = await Inquirer.prompt(args)<br> const meta =metal.metadata()<br> Object.assign(meta,obj)<br> delete files['ask.js']<br> done();<br> })<br> .use((files, metal, done) => {<br> const obj= metal.metadata()<br> Reflect.ownKeys(files).forEach(async (file)=>{<br> if(file.includes('js')||file.includes('json')){<br> let content= files[file].contents.toString()<br> if(content.includes('<%')){<br> content=await render(content,obj)<br> files[file].contents=Buffer.from(content)<br> }<br> }<br> })<br> done()<br> })<br> .build((err)=>{<br> if(err){<br> reject()<br> }else{<br> resolve()<br> }<br> })<br> })<br>}<br>
发包
nrm use npm
nrm can help you easy and fast switch between different npm registries, now include: npm, cnpm, taobao, nj(nodejitsu)
npm addUser
npm publish
npm unpublish --force
卸载包
0 条评论
下一页