安装
使用
效果
1. 主要 package version
注意:文章重点在于打造 cli,不是 puppeteer
2. 项目目录结构 ├── bin | └── cli.js ├── LICENSE ├── package -lock.json ├── package .json ├── puppeteer.js └── README.md
2. package.json 中添加bin
字段
添加juejin-save
命令,指定运行文件为 bin 目录 cli.js
+ { + "bin": { + "juejin-save": "bin/cli.js" + } + }
3. 主要 package api 介绍 3.1 commander const { Command } = require ("commander" );const program = new Command (); program .command ("clone <source> [destination]" ) .description ("clone a repository into a newly created directory" ) .action ((source, destination ) => { console .log ("clone command called" ); }); program.parse ();
3.2 inquirer var inquirer = require ("inquirer" ); inquirer .prompt ([ ]) .then ((answers ) => { }) .catch ((error ) => { if (error.isTtyError ) { } else { } });
3.3 ora import ora from "ora" ;const spinner = ora ("Loading unicorns" ).start ();setTimeout (() => { spinner.color = "yellow" ; spinner.text = "Loading rainbows" ; }, 1000 );
3.4 puppeteer const puppeteer = require ("puppeteer" ); (async () => { const browser = await puppeteer.launch (); const page = await browser.newPage (); await page.goto ("https://example.com" ); await page.screenshot ({ path : "example.png" }); await browser.close (); })();
4. 主要逻辑代码
bin/cli.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 #!/usr/bin/env node const inquirer = require ("inquirer" );const ora = require ("ora" );const { Command } = require ("commander" );const { puppeteerInit, saveToHtml, saveToMd, saveToPdf } = require (path.resolve ( __dirname, "../puppeteer" ));const program = new Command ();const spinner = ora ();async function handlePrompt ( ) { return await inquirer.prompt ([ { name : "autoCreateFolder" , message : `Automatically create folders?` , type : "confirm" , }, ]); }async function AfterePrompt (articleUrl, answers ) { spinner.color = "yellow" ; spinner.start ("puppeteer intial..." ); const obj = await puppeteerInit (articleUrl, answers); spinner.stopAndPersist ({ symbol : chalk.green ("✓" ), text : chalk.green ("puppeteer init ok" ), }); return obj; }async function exportFile (arg ) { const { page, outMdFilePath, outPdfFilePath, outHtmlfFilePath } = arg; await saveToMd (page, outMdFilePath); await saveToPdf (page, outPdfFilePath); await saveToHtml (page, outHtmlfFilePath); } program .version (require (path.resolve (__dirname, "../package.json" )).version ) .command ("save <article-url>" ) .description ("save https://xxx" ) .action (async (articleUrl) => { const answers = await handlePrompt (articleUrl); const data = await AfterePrompt (articleUrl, answers); await exportFile (data); process.exit (1 ); }); program.parse ();
puppeteer.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 const puppeteer = require ("puppeteer" );async function saveToHtml (page, outHtmlfFilePath ) { }async function saveToMd (page, outMdFilePath ) { }async function saveToPdf (page, outPdfFilePath ) { }async function puppeteerInit (href ) { const browser = await puppeteer.launch (); const page = await browser.newPage (); page.setViewport ({ width : 1920 , height : 1080 , }); await page.goto (href, { waitUntil : "domcontentloaded" , referer : href, }); await page.waitForTimeout (3000 ); return { browser, page, }; }module .exports = { puppeteerInit, saveToHtml, saveToMd, saveToPdf, };
5. 本地测试
在项目根目录执行
执行完之后,成功提示:
added 1 package, and audited 3 packages in 1 sfound 0 vulnerabilities
也可以在本机的 npm 全局安装里找到一个软链接,如图:
在任意目录打开命令行,执行
juejin-save save https://juejin.cn/post/xxxx
不出意外,可以看到,多出了一个文件夹,文章被保存在文件夹里面了。
6. 参考资料
手写一个合格的前端脚手架
实现 CLI 常用工具包 - 终端交互相关