This article explores the migration of CSDNSynchexo to denO implementation step by step.

Csdnsynchexo is a simple tool that crawls CSDN blog content to generate hexo source file content. The normal version is implemented using NodeJS. Deno has recently released 1.0, so I want to try it out and upgrade from Node to deno. This article focuses on what it takes to migrate a NodeJS application to deno and covers some very basic denO concepts. If you are familiar with NodeJS, this article is almost zero difficulty to read

Github address of the project after migration

The installationdeno

Installation documentation

There are many ways in the document, and we can choose as needed. I’ll go straight to the MAC script installation. Execute a script and set the environment variables as prompted

curl -fsSL https://deno.land/x/install/install.sh | sh
Set environment variables as prompted
# add the directory to your $HOME/.zshrc (or similar)
export DENO_INSTALL="/Users/name/.deno"
export PATH="$DENO_INSTALL/bin:$PATH"
Copy the code

The installationdenoVscode plug-in

This plugin does the following:

Unlike ts in Node, imported files in deno must end with a. Ts suffix, which is not required in Node. This plugin solves this problem by prompting you to add a suffix

Deno can introduce remote file paths, and the plug-in can automatically infer package types based on files downloaded from those paths (depending on the DENO_INSTALL and PATH environment variables)

Just search the vscode store for the installation. address

I have a problem here: after installing this plug-in, vscode still fails to find Deno error (issue many people also encounter this problem, if there is no problem, ignore the following), it should be the lack of the corresponding Deno declaration file. Install deno’s declaration file directly using NPM I typescript-deno-plugin (or manually copy the declaration file).

# node and NPM are still used...
npm install --save-dev typescript-deno-plugin typescript
Copy the code

Migration of third-party dependent modules

Since deno and Node are ts/ JS code, so in fact, as long as the third party package and API problems are solved, the logic is the same direct use, so the third party dependencies of this project are as follows, as long as these dependency problems are solved

{
    "dependencies": {
        "cheerio": 2 "" ^ 1.0.0 - rc.."commander": "^ 2.19.0"."filenamify": "^ 4.1.0." "."node-fetch": "^ 2.1.2"."sitdown": "^ 1.1.6." "}}Copy the code

(deno implements the W3C API standard and already has fetch built in, so our Node-FETCH is no longer needed)

Module migration guide reference

According to the official recommendation, it is suggested to use a deds. ts file in Deno project to manage all dependencies in a unified manner, while other parts are directly introduced from deds. ts. For example, deds. ts of this project is as follows

export { default as cheerio } from "https://dev.jspm.io/cheerio";
export { default as sitdown } from "https://dev.jspm.io/sitdown";
export { default as Command } from "https://deno.land/x/denomander/mod.ts";
export * as fs from "https://deno.land/std/node/fs.ts";
export * as path from "https://deno.land/std/node/path.ts";
export { default as filenamify } from "https://dev.jspm.io/filenamify";
Copy the code

So the question is, how do you find these modules? There is also a general introduction in the module migration guide, which is briefly described here

1. Firstly, it is recommended to find this module in PIKA. If it can be used directly, it will not be red, indicating that it can be perfectly used in denO. Pika has its own. D. ts type files, with the deno vscode plug-in can realize the type of inference

Cheerio, for example, is used directly in deno

2. If this module is not supported in PIKA (or piKA pumping.. 404 or 502), then use https://dev.jspm.io/ module name address to import, these imports generally do not have the TS declaration file, you may need to manually import the corresponding library declaration file or directly add @ts-ignore ignore the corresponding TS. Do modules in dev.jspm. IO use some API that deno does not support? . Need to judge)

// Cheerio is imported via dev.jspm. IO, with no type
// @ts-ignore
const $ = cheerio.load(html, {
    decodeEntities: true});Copy the code

3. If 1 and 2 cannot be found, Google the corresponding module name of denO to see if there is a suitable alternative. This project, for example, will replace Node commander with Denomander

Because deno comes with typescript support, you can execute TS files without the need for ts-Node, TSC, etc

Migration of Node’s native API

For node native modules, deno provides corresponding compatibility packages (they exist in the Deno standard library node package), such as FS, PATH, etc. However, compatibility is not complete, for example some apis are missing (streaming operations are not available in FS) and some Node native packages are not supported. So the best thing to do is to use the Denoapi as much as possible, and if not, use the Node package. My project migration basically meets the needs…

Csdnsynchexo has many file operations that call FS, mainly creating and writing files.

Deno puts all apis in the Deno namespace… Deno uses await for asynchrony, and the global top layer can use await directly

A simple example..

// Check whether the file exists in node
import fs from "fs";
export const fsExistsSync = (way: string) :boolean= > {
    try {
        fs.accessSync(way, fs.constants.W_OK);
    } catch (e) {
        return false;
    }
    return true;
};
// Corresponding deno API implementation
export const fsExistsSync = (way: string) :boolean= > {
    try {
        Deno.statSync(way);
    } catch (e) {
        return false;
    }
    return true;
};
Copy the code
// Generate file, write file operation
const writeStream = fs.createWriteStream(
    path.join(output, `. /${filenamify(title)}.md`),
    "utf8"
);
writeStream.write(`title: ${title}\n`);
writeStream.close();

// deno
const file = Deno.createSync(path.join(output, `. /${filenamify(title)}.md`));
const encoder = new TextEncoder();
Deno.writeSync(file.rid, encoder.encode(`title: ${title}\n`));
Deno.close(file.rid);
Copy the code

Path. join does not have a corresponding implementation, so we can use the path of STD node

It’s really not that difficult… Check deno documentation for similar apis

Execute a program

For Node, deno has strict permission management. For example, if we need network permission, we must add –allow-net to make network requests.

This project will use file read and write, network request permissions, Deno run –allow-read –allow-net –allow-write./ SRC /index.ts hsync –config=./config.json

Maybe you still miss NPM.. It’s nice to execute a bunch of arguments at a time, and we can use makefiles for scripting

# makefile
run:
	deno run --allow-read  --allow-net --allow-write ./src/index.ts hsync --config=./config.json

cache:
	deno cache ./src/index.ts
Copy the code

Create a new makefile in the root directory and execute the program by making run. So we’re done

packaging

Deno Bundle comes with packaging and Tree Shaking capabilities to package our code into single files

Deno Install can generate our code executable for direct use

You can create a corresponding make script

bundle:
	deno bundle ./src/index.ts ./hsync.js
install:
	deno install --allow-read  --allow-net --allow-write -n hsync ./src/index.ts
Copy the code

cli

The deno CLI is much more powerful than Node. With testing, packaging, running, formatting is equal to one

SUBCOMMANDS:
    bundle         Bundle module and dependencies into single file
    cache          Cache the dependencies
    completions    Generate shell completions
    doc            Show documentation for a module
    eval           Eval script
    fmt            Format source files
    help           Prints this message or the help of the given subcommand(s)
    info           Show info about cache or info related to source file
    install        Install script as an executable
    repl           Read Eval Print Loop
    run            Run a program given a filename or url to the module
    test           Run tests
    types          Print runtime TypeScript declarations
    upgrade        Upgrade deno executable to given version
Copy the code

After a series of operations, a simple Node project was migrated to a deno project, and today it has gone from installing deno to using deno. The intuition for deno is as follows

advantages

1, built-in TS support, don’t install TS-Node, Babel, etc

2, denO command has a test, packaging, running, formatting is equal to one, there is no need to follow an extra pile of things

disadvantages

1, the third-party library error message is not good, because it is a remote URL, need to click the past, not as intuitive as local

2, the current ecology is not very good