ホームページ  >  記事  >  ウェブフロントエンド  >  独自の JavaScript コードベースを設計して構築する: ヒントとテクニック

独自の JavaScript コードベースを設計して構築する: ヒントとテクニック

黄舟
黄舟オリジナル
2017-02-22 13:48:531339ブラウズ

コードベース: 私たちは常にコードベースを使用します。コード ライブラリは、開発者がプロ​​ジェクトで使用するコードをパッケージ化する場所であり、常に時間を節約し、車輪の再発明を回避します。オープンソースかクローズドソースかに関係なく、再利用可能なパッケージを持つことは、同じ機能を持つパッケージを何度もビルドしたり、過去のプロジェクトから手動でコピーして貼り付けたりするよりも優れています。

著者のその他の記事

  • Stop Maiming Body: The Perils of Pixel Font-Size

  • ES2016: JavaScript の将来は開発者主導であるべきですか?

パッケージ化されたコードに加えて、コードベースをもっと正確に説明できますか?いくつかの例外を除き、コードベースは通常 1 つのファイルだけ、または同じフォルダー内の複数のファイルです。そのコードは個別に保存して、プロジェクトで通常どおり使用できる必要があります。ライブラリ ファイルを使用すると、プロジェクトに応じて構造や動作を調整できます。 USB インターフェイス経由でのみ通信する USB デバイスを想像してください。マウスやキーボードなどの一部のデバイスは、デバイスが提供するインターフェイスを通じて設定できます。

今回はライブラリファイルのビルド方法を説明します。ほとんどのメソッドは他の言語にも適用できますが、この記事では JavaScript ライブラリの構築に焦点を当てます。

独自の Javascript ライブラリを構築する理由は何ですか?

まず最も重要なことは、ライブラリ ファイルを使用すると、既存のコードを簡単に再利用できるということです。ファイルをコピーするために古いプロジェクトを掘り出す必要はなく、ライブラリ ファイルを取り込むだけで済みます。これにより、アプリケーションをコンポーネント化することもでき、アプリケーションのコード ベースが小さくなり、保守が容易になります。

设计和构建你自己的JavaScript代码库:提示与技巧

Christ Church Library (source)

特定の関数の実装を容易にする、または再利用できる抽象コードは、ライブラリ ファイルにパッケージ化できます。 jQuery は興味深い例です。 jQuery の API には簡略化された DOM API が多数ありますが、ブラウザ間での DOM 操作が難しかった過去においては、これは非常に重要な意味を持ちました。

オープンソース プロジェクトが人気になり、多くの開発者がそれを使用すると、人々は質問したりコードを提供したりして開発に参加する可能性があります。いずれにせよ、それはライブラリとそれに依存するプロジェクトを助けます。

人気のオープンソース ライブラリも大きなチャンスをもたらします。企業があなたの仕事の質を認めてオファーをくれるかもしれません。もしかしたら、会社はあなたのプロジェクトを自社のアプリケーションに統合するようあなたに依頼するかもしれません。結局のところ、あなた以上にあなたのプロジェクトを知っている人はいません。

もちろん、それは単なる習慣かもしれません。タイピングを楽しみ、他の人を助け、その過程で学び、成長してください。自分の限界を超えて、新しいことに挑戦することができます。

範囲と目標

コードの最初の行を記述する前に、ライブラリが何を行うかを決定し、目標を設定する必要があります。この目標を達成することで、このライブラリを使用して解決したい問題に集中できます。コードベースの元の形式は、問題を解決するときに使いやすく、覚えやすいことに留意してください。 API が単純であればあるほど、ユーザーがコード ベースを学習するのが容易になります。 Unix の設計哲学を紹介します:

ただ 1 つのことを実行し、それをうまく実行してください

自問してください: コード ベースはどのような問題を解決しますか?どうやって解決するつもりですか?すべて自分で行いますか、それとも他の人のコードベースを持ち込みますか?

コードベースがどれほど大きくても、ロードマップを作成するようにしてください。必要な機能をすべてリストアップし、最小限の実行可能な製品のような、小さいながらも問題を解決できるコード ベースが完成するまで、それらをできるだけ多くの部分に分割します。これが最初のバージョンになります。ここから、各新機能のマイルストーンを確立できます。基本的に、プロジェクトをビットレベルのコードの塊に変換し、各機能の動作をより良く、より興味深いものにします。信じてください、これであなたの健康状態は保てます。

API 設計

私の意見では、ユーザーの視点からコードベースを開発したいと考えています。ユーザー中心のデザインと言えるかもしれません。本質的には、コードベースのアウトラインを作成し、コードベースをさらに検討して、コードベースを選択する人が使いやすくすることです。同時に、どこをカスタマイズする必要があるかを考える必要があります。これについては、この記事で後ほど説明します。

究極の API テストは、独自のテクニックを試し、プロジェクトでコード ベースを使用することです。以前のコードを自分のコードに置き換えて、必要な機能を満たしているかどうかを確認してください。コード ベースをできるだけ直感的にし、境界条件でより柔軟に使用でき、カスタマイズできるようにしてください (これについては後の記事で詳しく説明します)。

ユーザー エージェント文字列のコード ベースの概要は次のとおりです:

// Start with empty UserAgent string var userAgent = new UserAgent; 
// Create and add first product: EvilCorpBrowser/1.2 (X11; Linux; en-us) var application = new UserAgent.Product('EvilCorpBrowser', '1.2');
application.setComment('X11', 'Linux', 'en-us');
userAgent.addProduct(application); // Create and add second product: Blink/20420101 var engine = new UserAgent.Product('Blink', '20420101');
userAgent.addProduct(engine); // EvilCorpBrowser/1.2 (X11; Linux; en-us) Blink/20420101 userAgent.toString(); 
// Make some more changes to engine product engine.setComment('Hello World'); // EvilCorpBrowser/1.2 (X11; Linux; en-us) Blink/20420101 (Hello World) userAgent.toString();

コードの複雑さによっては、整理に時間がかかる場合があります。デザイン パターンの利用は、コード ベースを整理するための優れた方法であり、一部の技術的な問題も解決できます。これにより、新しい機能を追加するための大規模なリファクタリングも回避されます。

柔軟性とカスタマイズ

柔軟性はコードベースを強力にしますが、カスタマイズできるものとできないものの境界を判断するのは困難です。 chart.js と D3.js が良い例です。どちらのコード ライブラリもデータの視覚化に使用されます。 Chart.js を使用すると、さまざまな形式の組み込みグラフを簡単に作成できます。ただし、画像をさらに制御したい場合は、D3.js が必要です。

ユーザーに制御を与えるには、構成、パブリック メソッドの公開、コールバックやイベントによる方法など、いくつかの方法があります。

コードベースの構成は通常、初期化の前に行われます。ただし、一部のコード ライブラリでは、実行時に構成を変更できます。通常、構成は小さな部分に制限されており、後で使用するために値を変更することのみが許可されます。

// Configure at initialization var userAgent = new UserAgent({
  commentSeparator: ';' }); // Run-time configuration using a public method userAgent.setOption('commentSeparator', '-'); 
  // Run-time configuration using a public property userAgent.commentSeparator = '-';

方法通常是暴露给实例使用的,比如说从实例中获取数据,或者设置实例的数据和执行操作。

var userAgent = new UserAgent; // A getter to retrieve comments from all products userAgent.getComments(); 
// An action to shuffle the order of all products userAgent.shuffleProducts();

回调通常是在公共的方法中被传递的,通常在异步操作后执行用户的代码。

var userAgent = new UserAgent;

userAgent.doAsyncThing(function asyncThingDone() { // Run code after async thing is done });

事件有很多种可能。有点像回调,除了增加事件句柄是不应该触发操作的。事件通常用于监听,你可能会猜到,这可是事件!更像回调的是,你可以提供更多的信息和返回一个数值给代码库去进行操作。

var userAgent = new UserAgent; // Validate a product on addition userAgent.on('product.add', function onProductAdd(e, product) { 
var shouldAddProduct = product.toString().length < 5; // Tell the library to add the product or not return shouldAddProduct;
});

在一些例子中,你可能允许用户对你的代码库进行扩展。因此,你需要暴露一些公共方法或者属性来让用户填充,像Angular的模块 (angular.module('myModule'))和Jquery的 fn(jQuery.fn.myPlugin)或者什么都不做,只是简单的让用户获取你的代码库的命名空间:

// AngryUserAgent module // Has access to UserAgent namespace (function AngryUserAgent(UserAgent) { 
// Create new method .toAngryString() UserAgent.prototype.toAngryString = function() { return this.toString().toUpperCase();
  };

})(UserAgent); // Application code var userAgent = new UserAgent; // ... // EVILCORPBROWSER/1.2 (X11; LINUX; EN-US) BLINK/20420101 userAgent.toAngryString();

类似的,这允许你重写方法。

// AngryUserAgent module (function AngryUserAgent(UserAgent) { // Store old .toString() method for later use var _toString = UserAgent.prototype.toString; 
// Overwrite .toString() UserAgent.prototype.toString = function() { return _toString.call(this).toUpperCase();

  };

})(UserAgent); var userAgent = new UserAgent; // ... // EVILCORPBROWSER/1.2 (X11; LINUX; EN-US) BLINK/20420101 userAgent.toString();

在后面的例子中,允许你的用户获取代码库的命名空间,让你在对扩展和插件的定义方面上的控制变小了。为了让插件遵循一些约定,你可以(或者是应该)写下文档。

测试

对测试驱动开发(test-driven development)来 说,写下大纲是良好的开始。简单来说,指的是在你写实际的代码库之前,在你写下测试准则的时候。如果测试检查的是你的代码特性是否跟期待的一样,以及你在 写代码库之前写测试,这就是行为驱动开发。不管怎样,如果你的测试覆盖了你的代码库的每一个特性,而且你的代码通过了所有的测试。你可以确定你的代码是可 以正常工作的。

Jani Hartikainen讲述了如何利用Mocha来进行单元测试 Unit Test Your JavaScript Using Mocha and Chai。在使用Jsmine,Travis,Karma测试JavaScript (Testing JavaScript with Jasmine, Travis, and Karma)这篇文章中,Tim Evko展示了怎么通过另一个叫做Jasmine的框架来设置良好的测试流程。这两个测试框架都是非常流行的,但还有适应别的需求的其他框架。

我在这篇文章前面撰写的大纲,已经讲述了它期待怎样的输出。这是一切测试的开始:从期望出发。关于我的代码库的一个Jasmine测试像是这样:

describe(&#39;Basic usage&#39;, function () {
  it(&#39;should generate a single product&#39;, function () { // Create a single product var product = new UserAgent.Product(&#39;EvilCorpBrowser&#39;, &#39;1.2&#39;);
    product.setComment(&#39;X11&#39;, &#39;Linux&#39;, &#39;en-us&#39;);

    expect(product.toString())
      .toBe(&#39;EvilCorpBrowser/1.2 (X11; Linux; en-us)&#39;);
  });

  it(&#39;should combine several products&#39;, function () { var userAgent = new UserAgent; 
  // Create and add first product var application = new UserAgent.Product(&#39;EvilCorpBrowser&#39;, &#39;1.2&#39;);
    application.setComment(&#39;X11&#39;, &#39;Linux&#39;, &#39;en-us&#39;);
    userAgent.addProduct(application); // Create and add second product var engine = new UserAgent.Product(&#39;Blink&#39;, &#39;20420101&#39;);
    userAgent.addProduct(engine);

    expect(userAgent.toString())
      .toBe(&#39;EvilCorpBrowser/1.2 (X11; Linux; en-us) Blink/20420101&#39;);
  });

  it(&#39;should update products correctly&#39;, function () { var userAgent = new UserAgent; 
  // Create and add first product var application = new UserAgent.Product(&#39;EvilCorpBrowser&#39;, &#39;1.2&#39;);
    application.setComment(&#39;X11&#39;, &#39;Linux&#39;, &#39;en-us&#39;);
    userAgent.addProduct(application); // Update first product application.setComment(&#39;X11&#39;, &#39;Linux&#39;, &#39;nl-nl&#39;);

    expect(userAgent.toString())
      .toBe(&#39;EvilCorpBrowser/1.2 (X11; Linux; nl-nl)&#39;);
  });
});

一旦你对你的API设计的第一个版本完全满意,是时候开始思考结构和你的代码库应该如何被使用。

模块加载器兼容性

你或许使用过模块加载器。使用你的代码库的开发者有可能使用加载器,所以你会希望自己的代码库与模块加载器是兼容的。但兼容哪一个呢?应该怎么从CommonJS,RequireJS,AMD和其他加载器中挑选呢?

実は、選ぶ必要はありません! Universal Module Definition (UMD) は、複数のローダーをサポートすることを目的としたルールです。さまざまなスタイルのスニペットをオンラインで見つけることも、UMD GitHub リポジトリから学習してコードベースと互換性を持たせることもできます。これらのテンプレートのいずれかを使用して開始するか、お気に入りのビルド ツールを使用して UMD を追加すると、モジュール ローダーについて心配する必要がなくなります。

ES2015 のインポート/エクスポート構文を使用したい場合は、Babel と Babel の UMD プラグインを使用してコードを ES5 に変換することをお勧めします。こうすることで、互換性のあるコード ベースを生成しながら、プロジェクトで ES2015 を使用できます。

ドキュメント

私はすべてのプロジェクトでドキュメントを使用することに大賛成です。しかし、これには多大な労力がかかることが多く、その結果、文書化が後回しにされ、最終的には忘れられてしまうことになります。

基本情報

ドキュメントの作成は、プロジェクトの名前や説明などの基本情報から始める必要があります。これは、他の人があなたのコードベースが何をするのか、そしてそれが彼らにとって役立つかどうかを理解するのに役立ちます。

範囲や目標などの情報を提供してユーザーに適切な情報を提供したり、将来どのような新しい変更があり、それがどのように役立つかをユーザーが理解できるようにロードマップを提供したりできます。

API、チュートリアル、例

もちろん、コードベースの使用方法をユーザーに確実に理解してもらう必要があります。これは API ドキュメントから始まります。チュートリアルやサンプルは優れた追加機能ですが、それらを作成するのは大変な作業になる可能性があります。ただし、インライン ドキュメントの場合はこの限りではありません。以下に、JSDoc を使用して解析してドキュメント ページに変換できるコメントをいくつか示します。

メタタスク

一部のユーザーは、コード ベースを改善したいと考えています。ほとんどの場合、これは提供されたコードですが、個人的に使用するためにカスタム バージョンを作成する場合もあります。このようなユーザーにとって、コード ベースの構築、テストの実行、データの生成、変換、ダウンロードなどのメタタスクに関するドキュメントを提供すると役立ちます。

貢献

コード ベースをオープンソースにする場合、コードの貢献を得ることが役立ちます。貢献者をガイドするために、コードを貢献する手順と満たす必要のある基準に関するドキュメントを追加できます。これは、提供されたコードとその正しい提供コードを確認して受け入れるのに役立ちます。

ライセンス

最後のポイントは、ライセンスを使用することです。技術的には、テクノロジー ライセンスを選択しなかったとしても、コード ベースは著作権で保護されますが、誰もがこれを知っているわけではありません。

ChooseALicense.com は、法律の専門家でなくてもライセンスを選択できる Web サイトであることを発見しました。ライセンスを選択したら、LICENSE.txt ファイルをプロジェクトのルート ディレクトリに追加するだけです。

将它打包和发布到包管理器

对一个好的代码库来说,版本是很重要的。如果你想要加入重大的变化,用户可能需要保留他们现在正在使用的版本。

Semantic Versioning是流行的版本命名标准,或者叫它SemVer。SemVer版本包括三个数字,每一个代表不同程度的改变:重大改变,微小的改变和补丁

在你的Git仓库加入版本和发布

如果你有一个git仓库,你可以在你的仓库添加版本数字。你可以把它想象成你的仓库的快照。我们也叫它标签 Tags。可以通过开启终端和输入下面的文字来创造标签:

# git tag -a [version] -m [version message]
git tag -a v1.2.0 -m "Awesome Library v1.2.0"

很多类似GitHub的服务会提供关于所有版本的概览和提供它们的下载链接。

发布一个通用仓库

npm

许多编程语言自带有包管理器,或者是第三方包管理器。这可以允许我们下载关于这些语言的特定代码库。比如PHP的Composer 和Ruby的RubyGems

Node.js,一种独立的JavaScript引擎,拥有 npm,如果你对npm不熟悉,我们有一个很好的教程beginner’s guide。

默认情况下,你的npm包会发布为公共包。不要害怕,你也可以发布私有包 private packages, 设置一个私有的注册private registry, 或者根本不发布avoid publishing.

为了发布你的包,你的项目需要有一个 package.json 文件。你可以手动或者交互问答的方式来创建。通过输入下面的代码来开始问答:

`npm init`

这个版本属性需要跟你的git标签吻合。另外,请确定有README.md 文件。像是GitHub,npm在你的包的展示页使用它。

之后,你可以通过输入下面的代码来发布你的包:

`npm publish`

就是这样!你已经成功发布了你的npm包。

Bower

几年前,有另一个叫做Bower的包管理器。这个包管理器,实际上不是为了特定的语言准备的,而是为了互联网准备的。你可以发现大部分是前端资源。在Bower发布你的包的关键一点是你的代码库是否跟它兼容。

如果你对Bower不熟悉,我们也有一个教程beginner’s guide 。

跟npm一样,你也可以设置一个私有仓库private repository。你可以通过问答的方式避免发布。

有趣的是,在最近的一两年,很多人转为使用npm管理前端资源。近段npm包主要是跟JavaScript相关,大部分的前端资源也发布在了npm上。不管怎样,Bower仍然流行。我明确的推荐你在Bower上发布你的包。

我有提到Bower实际上是npm的一种模块,并最初是得到它的启发吗?它们的命令是很相似的,通过输入下面的代码产生bower.json文件:

`bower init`

跟npm init类似,指令是很直白的,最后,发布你的包:

`bower register awesomelib http://www.php.cn/`

像是把你的代码库放到了野外,任何人可以在他们的Node项目或者网络上使用它!

总结

核心的产品是库文件。确定它解决了问题,容易和适合使用,你会使得你的团队或者许多开发者变得高兴。

我提到的很多任务都是自动化的,比如:运行测试,创建标签,在package.json升级版本或者在npm或者bower重发布你的包。 这是你像Travis CI 或 Jenkins一样踏入持续集成和使用工具的开始。我之前提到的文章 article by Tim Evko 也讲述到了这点。

你构建和发布代码库了吗?请在下面的评论区分享!

 

以上就是设计和构建你自己的JavaScript代码库:提示与技巧的内容,更多相关内容请关注PHP中文网(www.php.cn)!


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。