- npm package
- Github source repository
The installation
npm i juejin-save -g
Copy the code
use
juejin-save save https://xxx
Copy the code
The effect
1. Main Package version
Note: This article focuses on building the CLI, not puppeteer
package | version | function |
---|---|---|
commander | ^ 9.0.0 | Create processing command |
inquirer | ^ 8.2.0 | Process interactions |
ora | ^ 5.4.1 | Dealing with loading |
puppeteer | ^ 13.3.2 | Control Chromium or Chrome via apis |
2. Project directory structure
├ ─ ─ bin | └ ─ ─ cli. Js / / entry documents ├ ─ ─ LICENSE ├ ─ ─ package - lock. Json ├ ─ ─ package. The json ├ ─ ─ puppeteer. Js / / puppeteer save article file └ ─ ─ README.mdCopy the code
2. Add in package.jsonbin
field
Add the juejin-save command to specify the run file as the bin directory cli.js
+ {
+ "bin": {
+ "juejin-save": "bin/cli.js"
+}
+}
Copy the code
3. Main Package API introduction
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();
Copy the code
3.2 inquirer
var inquirer = require("inquirer");
inquirer
.prompt([
/* Pass your questions in here */
])
.then((answers) = > {
// Use user feedback for... whatever!!
})
.catch((error) = > {
if (error.isTtyError) {
// Prompt couldn't be rendered in the current environment
} else {
// Something else went wrong}});Copy the code
3.3 ora
import ora from "ora";
const spinner = ora("Loading unicorns").start();
setTimeout(() = > {
spinner.color = "yellow";
spinner.text = "Loading rainbows";
}, 1000);
Copy the code
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" });
awaitbrowser.close(); }) ();Copy the code
4. Main logic code
- bin/cli.js
#! /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();
// Interactive query
async function handlePrompt() {
return await inquirer.prompt([
{
name: "autoCreateFolder".message: `Automatically create folders? `.type: "confirm",},/ /...
]);
}
// Puppeteer initialization begins
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;
}
// Export the file
async function exportFile(arg) {
const { page, outMdFilePath, outPdfFilePath, outHtmlfFilePath } = arg;
await saveToMd(page, outMdFilePath);
await saveToPdf(page, outPdfFilePath);
await saveToHtml(page, outHtmlfFilePath);
}
// Step 1: create a command
program
.version(require(path.resolve(__dirname, ".. /package.json")).version)
.command("save
"
)
.description("save https://xxx")
.action(async (articleUrl) => {
// Step 2: Interactive query
const answers = await handlePrompt(articleUrl);
// Step 3: Get the interaction result
const data = await AfterePrompt(articleUrl, answers);
// Step 4: Export the file
await exportFile(data);
process.exit(1);
});
program.parse();
Copy the code
- puppeteer.js
const puppeteer = require("puppeteer");
/ / save the HTML
async function saveToHtml(page, outHtmlfFilePath) {
// ...
}
/ / save the markdown
async function saveToMd(page, outMdFilePath) {
// ...
}
/ / save the PDF
async function saveToPdf(page, outPdfFilePath) {
// ...
}
// Puppeteer is initialized
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); // Make sure the page loads
return {
browser,
page,
};
}
module.exports = {
puppeteerInit,
saveToHtml,
saveToMd,
saveToPdf,
};
Copy the code
5. Local tests
- Execute in the project root directory
npm link
Copy the code
After execution, success message:
added 1 package, and audited 3 packages in 1s
found 0 vulnerabilities
Copy the code
You can also find a soft link in the NPM global installation on your machine, as shown in the following figure:
- Open the cli in any directory and run
juejin-save save https://juejin.cn/post/xxxx
Copy the code
Unsurprisingly, you can see that there is an extra folder where the article is saved.
6. Reference materials
-
Hand-write a qualified front end scaffold
-
CLI common tool kit – terminal interaction