ホームページ > 記事 > ウェブフロントエンド > Node.js + imgcook が依存関係を自動的に生成する方法の簡単な分析
Node.js imgcook を使用して依存関係を自動的に生成する方法を教えてください。生成方法については以下の記事で紹介していますが、ある程度参考になるので参考になれば幸いです!
imgcook は、淘宝網の内部バージョンで依存関係管理のような機能を提供します。これは、imgcook エディターで axios などの関数を作成するときに、他の依存関係パッケージを導入するために使用されます。アンダースコア、@rax/video など。 ただし、ユーザー エクスペリエンスという点では、エディターでは誰でも package.json で依存関係を宣言する習慣を身に付けることができないため、まだ比較的面倒です。エディターは GUI インターフェイスであるため、各関数からコードを開いて依存関係を確認するのは比較的面倒ですが、imgcook モジュールを開発した後、それが他のパッケージに依存している場合 (ほとんどの場合必要)、毎回、一つ一つ開いて、機能してバージョン番号を確認して依存関係管理に追加するのですが、使っていると面倒な作業が多いです。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 = ''; process.stdin.on('data', (buf) => { originJson += buf.toString('utf8'); }); process.stdin.on('end', () => { 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 = ''; process.stdin.on('data', (buf) => { originJson += buf.toString('utf8'); }); process.stdin.on('end', () => { 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('@swc/core'); 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('@swc/core/visitor'); /** * 用于保存通过函数解析, 获得的依赖对象列表 */ const liveDependencies = []; /** * 定义访问器 */ class ImportsExtractor extends Visitor { visitImportDeclaration(node) { let alias = 'Default'; liveDependencies.push({ alias, packageRax1: node.source.value, versionRax1: '', packageRaxEagle: node.source.value, versionRaxEagle: '', checkDepence: true, }); return node; } } // 使用方式 const importsExtractor = new ImportsExtractor(); importsExtractor.visitModule(ast);Class
ImportsExtractor は @swc/core/visitor の
Visitor を継承しており、インポート宣言文をトラバースするため、構文型名は
となります。 ImportDeclaration なので、
visitImportDeclaration(node) メソッドを実装するだけで、メソッド内のすべての import ステートメントを取得し、対応するノードの構造に従って依存オブジェクトに変換して更新できます。 。エクストラクターを定義した後は、後続の依存関係生成のためにモジュールのすべての依存関係を収集できるように、エクストラクターに ast を供給するだけです。
const axios = require('axios'); async function fillVersions(dep) { const pkgJson = await axios.get(`https://registry.npmjs.org/${dep.packageRax1}`, { type: 'json' }); if (pkgJson.data['dist-tags']) { const latestVersion = pkgJson.data['dist-tags'].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 = ''; process.stdin.on('data', (buf) => { originJson += buf.toString('utf8'); }); process.stdin.on('end', () => { 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 { ... }
这样,我们就可以直接拷贝内容到编辑器。
比如,我在喔其中一个项目的 created 函数中增加了 axios 的依赖,关闭窗口后点击保存(确保 Schema 保存),然后通过命令:
$ imgcook pull <id> -o json | ckdeps -f | imgcook-save
然后在编辑器中打开 Schema 编辑,复制生成的内容并保存,然后打开“依赖管理”可以看到:
通过解析生成的代码已经更新到依赖面板了,这下终于可以解放双手,去做其他的事情了。
是不是这样就结束了呢?在 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 サイトの他の関連記事を参照してください。