ホームページ >ウェブフロントエンド >jsチュートリアル >Node.js + imgcook が依存関係を自動的に生成する方法の簡単な分析

Node.js + imgcook が依存関係を自動的に生成する方法の簡単な分析

青灯夜游
青灯夜游転載
2021-12-01 19:33:442525ブラウズ

Node.js imgcook を使用して依存関係を自動的に生成する方法を教えてください。生成方法については以下の記事で紹介していますが、ある程度参考になるので参考になれば幸いです!

Node.js + imgcook が依存関係を自動的に生成する方法の簡単な分析

imgcook は、淘宝網の内部バージョンで依存関係管理のような機能を提供します。これは、imgcook エディターで axios などの関数を作成するときに、他の依存関係パッケージを導入するために使用されます。アンダースコア、@rax/video など。

Node.js + imgcook が依存関係を自動的に生成する方法の簡単な分析

ただし、ユーザー エクスペリエンスという点では、エディターでは誰でも package.json で依存関係を宣言する習慣を身に付けることができないため、まだ比較的面倒です。エディターは GUI インターフェイスであるため、各関数からコードを開いて依存関係を確認するのは比較的面倒ですが、imgcook モジュールを開発した後、それが他のパッケージに依存している場合 (ほとんどの場合必要)、毎回、一つ一つ開いて、機能してバージョン番号を確認して依存関係管理に追加するのですが、使っていると面倒な作業が多いです。

解決方法

imgcook は、Schema ソースコード開発モードを提供しており、エディタ上でモジュールのプロトコル (Schema) を直接変更することで、GUI の操作手順を置き換えることができます。そして、依存関係の検索を通じて、依存関係管理関数がプロトコルの

imgcook.dependency を通じて実装されていることがわかりました。

{
  "alias": "Axios",   
  "packageRax1": "axios",
  "versionRax1": "^0.24.0",
  "packageRaxEagle": "axios",   
  "versionRaxEagle": "^0.24.0",   
  "checkDepence": true 
}

関数のコードもプロトコルに存在するため、元のプロトコル ドキュメントを処理し、対応する依存関係をスキャンしてノードに保存し、[保存] をクリックして依存関係管理のパッケージ リストが更新されたことを確認するだけです。

実装関数

このために、モジュールのプロトコルコンテンツをプルする関数を

@imgcook/cli に実装しました。具体的なプルリクエストは次のとおりです。 : imgcook/imgcook-cli#12 および imgcook/imgcook-cli#15 では、コマンド ライン ツールを使用して、次のように対応するモジュールのプロトコル (スキーマ) をプルできます。

$ imgcook pull <id> -o json

実行後、モジュール プロトコルの内容がコマンド ラインの stdout に出力されます。

この機能を使用すると、imgcook-cli のデータ ソースと連携するために、Unix パイプライン プログラムに基づいていくつかのコマンド ライン ツールを実装できます。たとえば、imgcook pull による JSON 出力は読みにくくなります。

#!/usr/bin/env node 
let originJson = &#39;&#39;; 
process.stdin.on(&#39;data&#39;, (buf) => {   
  originJson += buf.toString(&#39;utf8&#39;);   
}); 
process.stdin.on(&#39;end&#39;, () => {   
  const origin = JSON.parse(originJson);   
  console.log(JSON.stringify(origin, null, 2)); 
});

上記のプログラムは、

process を通じてパイプライン (Pipeline) の上流データを受け取ります。 stdin (imgcook モジュール プロトコルのコンテンツです)。次に、end イベントの出力を解析して整形します。コマンド

$ imgcook pull <id> -o json | imgcook-prettyprint

を実行して、整形された出力を確認します。これは、 Unix パイプライン プログラムの簡単な例。

次に、この方法で依存関係の自動生成を完了する方法を見てみましょう。上の例と同様に、別のファイル ckdeps を作成します。

#!/usr/bin/env node 
let originJson = &#39;&#39;; 
process.stdin.on(&#39;data&#39;, (buf) => {   
  originJson += buf.toString(&#39;utf8&#39;);   
}); 
process.stdin.on(&#39;end&#39;, () => {   
  transform(); 
}); 

async function transform() {   
  const origin = JSON.parse(originJson);   
  const funcs = origin.imgcook?.functions || [];   
  if (funcs.length === 0) {     
    process.stdout.write(originJson);     
    return;   
  }   
  console.log(JSON.stringify(origin)); 
}

origin.imgcook.functions を通じて、次のような関数のコード コンテンツを取得できます。

{   
  "content": "export default function mounted() {\n\n}",   
  "name": "mounted",   
  "type": "lifeCycles" 
}

次に、次のステップでは、

content を解析してコード内の import ステートメントを取得し、対応する依存関係オブジェクトを origin.imgcook.dependency に生成します。その後、参照する必要があります。 @swc/core JavaScript コードの解析:

const swc = require(&#39;@swc/core&#39;); 

await Promise.all(funcs.map(async ({ content }) => {   
  const ast = await swc.parse(content);   
	// the module AST(Abstract Syntax Tree) 
}));

ast を取得した後、コードを通じてインポート ステートメント情報を取得できますが、ast はより複雑であるため、@swc/core は次のような専用のトラバーサル メカニズムを提供します。

const { Visitor } = require(&#39;@swc/core/visitor&#39;); 

/**  
 * 用于保存通过函数解析, 获得的依赖对象列表  
 */ 
const liveDependencies = []; 

/**  * 定义访问器  */ 
class ImportsExtractor extends Visitor {   
  visitImportDeclaration(node) {     
    let alias = &#39;Default&#39;;     
    liveDependencies.push({       
      alias,       
      packageRax1: node.source.value,       
      versionRax1: &#39;&#39;,       
      packageRaxEagle: node.source.value,       
      versionRaxEagle: &#39;&#39;,       
      checkDepence: true,     
    });     
    return node;   
  } 
} 

// 使用方式 
const importsExtractor = new ImportsExtractor(); 
importsExtractor.visitModule(ast);

Class

ImportsExtractor は @swc/core/visitor の Visitor を継承しており、インポート宣言文をトラバースするため、構文型名は となります。 ImportDeclaration なので、visitImportDeclaration(node) メソッドを実装するだけで、メソッド内のすべての import ステートメントを取得し、対応するノードの構造に従って依存オブジェクトに変換して更新できます。 。エクストラクターを定義した後は、後続の依存関係生成のためにモジュールのすべての依存関係を収集できるように、エクストラクターに ast を供給するだけです。

上記のコードからわかるように、バージョン番号には現在空の文字列が使用されており、プロトコルの内容を更新すると依存するバージョン情報が失われるため、取得するメソッドを定義する必要があります。バージョン。

フロントエンドの依存関係はすべて NPM レジストリに保存されるため、次のような HTTP インターフェイスを通じてバージョンを取得できます。
const axios = require(&#39;axios&#39;); 
async function fillVersions(dep) {   
  const pkgJson = await axios.get(`https://registry.npmjs.org/${dep.packageRax1}`, { type: &#39;json&#39; });   
  if (pkgJson.data[&#39;dist-tags&#39;]) {     
    const latestVersion = pkgJson.data[&#39;dist-tags&#39;].latest;     
    dep.versionRax1 = `^${latestVersion}`;     
    dep.versionRaxEagle = `^${latestVersion}`;  
  }  
  return dep; 
}

我们按照 https://registry.npmjs.org/${packageName} 的规则,就能拿到存储在 Registry 中的包信息,然后 data['dist-tags'].latest 代表的是 latest 标签对应的版本,简单来说就是当前包的最新版本,然后再基于这个版本号增加一个 ^ 版本前缀即可(你也可以按照自己的诉求修改最终的版本以及 NPM Registry)。

最后一步,就是把我们从函数代码中抓取的依赖信息更新,并输出出来:

async function transform() {   
  // ...   
  origin.imgcook.dependencies = newDeps;   
  console.log(JSON.stringify(origin)); 
}

然后通过运行:

$ imgcook pull <id> -o json | ckdeps 
> { ..., "dependencies": [{ ... }] }

然后,开发者只需要把输出的 JSON 拷贝到编辑器中保存。哦,等等,在编辑器中并不能直接使用 JSON 保存,而是需要使用 ECMAScript Module 的方式(export default { ... }),那这样是不是意味着每次都需要手动编辑一下呢,答案是否,Unix Pipeline 的思路非常利于解决这种流程问题,我们只需要再新建一个节点脚本 imgcook-save 即可:

#!/usr/bin/env node 
let originJson = &#39;&#39;; 
process.stdin.on(&#39;data&#39;, (buf) => {  
  originJson += buf.toString(&#39;utf8&#39;);  
}); 
process.stdin.on(&#39;end&#39;, () => {  
  transform(); 
}); 

async function transform() {   
  const origin = JSON.parse(originJson);  
  console.log(`export default ${JSON.stringify(origin, null, 2)}`);
}

最后完整的命令是:

$ imgcook pull <id> -o json | ckdeps | imgcook-save 
> export default {   ... }

这样,我们就可以直接拷贝内容到编辑器。

效果体验

Node.js + imgcook が依存関係を自動的に生成する方法の簡単な分析

比如,我在喔其中一个项目的 created 函数中增加了 axios 的依赖,关闭窗口后点击保存(确保 Schema 保存),然后通过命令:

$ imgcook pull <id> -o json | ckdeps -f | imgcook-save

然后在编辑器中打开 Schema 编辑,复制生成的内容并保存,然后打开“依赖管理”可以看到:

Node.js + imgcook が依存関係を自動的に生成する方法の簡単な分析

通过解析生成的代码已经更新到依赖面板了,这下终于可以解放双手,去做其他的事情了。

One more thing?

是不是这样就结束了呢?在 macOS 中,提供了 pbcopy 命令,可以复制 stdin 到剪贴板,那么跟 imgcook 的例子结合一下:

$ imgcook pull <id> -o json | ckdeps | imgcook-save | pbcopy

这样就省掉了自己拷贝的工作,命令执行完直接打开编辑器 ⌘V 即可。

最后的最后,我要升华一下主题,在 @imgcook/cli 支持了输出 JSON 文本的功能后,就意味着 imgcook 接入了 Unix Pipeline 的生态,通过这种方式,我们可以在这个过程中构建很多有趣实用的工具,并与很多 Unix 工具协作使用(比如 bpcopy、grep、cat、sort 等)。

本文只是通过依赖的自动生成为例,使用 Unix Pipeline 的方式,验证了其可行性以及和 imgcook 编辑器配合使用的体验,目前来说,我可以通过这种方式,弥补不少编辑器上的体验缺失,让我更方便地使用 imgcook 的核心功能。

更多node相关知识,请访问:nodejs 教程!!

以上がNode.js + imgcook が依存関係を自動的に生成する方法の簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。