npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

gulp-diamond-princess-zoning

v0.10.0

Published

レガシーなゾーニングによって、js パッケージの変数定義に関する品質を担保します。またモジュール毎に無名関数でラップすることで実行時のルックアップを高速化します。

Downloads

11

Readme

gulp-diamond-princess-zoning

zoning


js ファイルを一本化しつつ、ファイル名やディレクトリを元に (function(){ ... })() でラップする gulp プラグインです。

  1. レガシーなゾーニングによって、js パッケージの変数と関数の宣言に制約を設けます
  2. モジュール毎にスコープを作ることで、変数と関数へのアクセスを高速化します、多分

僕が推奨する命名ルールについて「僕のWeb開発の、変数と関数、ファイル名とフォルダ名の命名ルール 」を併せて確認ください。

背景

アプリケーションを構成する各モジュール間の通信には、イベントやメッセージを使って、見通し良く、再利用性の高いコーディングをすることが一般的です。しかし、これはコストとトレードオフです。

最もローコストなモジュール間通信は、グローバル変数やグローバル関数を介したものです。しかしこの手法は前出のメリットを失い、スパゲッティなコード塊となる危険と隣り合わせです。

とはいえ Web プログラミングに於いてはクライアントのマシンリソースが不明である点から、可能な限りローコストな手法を採用したいところです。

このプラグインでは、ファイル名やフォルダ名と変数と関数の宣言場所の制約によって危険を退け、コードの堅牢性の維持を狙います。

用語

| Name | description | |:--------------|:------------| | package | フレームワークやライブラリ集、ゲームエンジン、アプリケーションといった粒度の単位 | | global | パッケージの外に公開する、グローバル変数とグローバル関数 | | packageGlobal | パッケージに所属するモジュール群で共有するグローバル変数とグローバル関数(*1) | | module | パッケージに所属する、コードブロック群の単位 | | moduleGlobal | モジュールに所属するコード群で共有するグローバル変数とグローバル関数(*1) |

  1. Closure Compiler にはよく似た方向性の @packege 指定がありました。「パッケージプライベート」という名称でしたので、こちらに寄せるか?迷っています。

コード例

gulp.task( 'precompile',
    function( cb ){
        return gulp.src( 'myUtilProject/**/*.js' )
            .pipe(
                gulpDPZ(
                    {
                        labelGlobal        : 'global',
                        labelPackageGlobal : 'packageGlobal',
                        labelModuleGlobal  : 'moduleGlobal',
                        packageGlobalArgs  : 'window,document',
                        basePath           : 'myUtilProject'
                    }
                )
            )
            .pipe(gulp.dest( 'R:/d' ));
    }
);

プロパティ

| Name | default value | description | |:-------------------|:------------------|:------------| | labelGlobal | 'global' | Path.relative(Path.resolve(basePath),vinyl.path) に match する文字列。Since version 0.9.8 : "*" を指定すると全てが global になるけどこれでは gulp-concat と変わらない。 | | labelPackageGlobal | 'packageGlobal' | Path.relative(Path.resolve(basePath),vinyl.path) に match する文字列。Since version 0.9.8 : "*" を指定すると global 以外は packageGlobal になる。小さいプロジェクトで、(function(){ ... })() のオーバーヘッドを忌避する場合に。 | | labelModuleGlobal | 'moduleGlobal' | Path.relative(Path.resolve(basePath),vinyl.path) に match する文字列。 | | toEndOfScript | 'toEndOfScript' | スクリプトの最後に配置したいファイルPath.relative(Path.resolve(basePath),vinyl.path) に match する文字列。 | | packageGlobalArgs | '' | packageGlobal に渡す引数。ブラウザ提供のグローバルメンバーをローカル化することでアクセスが早くなったり、圧縮時に名前が短くなる。配列 ['window, nameSpace, emptyFunction', 'this, {}, new Function()'] も可能です。 | | esModuleExports | '' | package をエクスポート(module.exports=function(){/* package */};)する。その際に親モジュールから受け取る引数を記述する。配列の場合、[0] に拡張コメント [1] に引数をかく。例: [ '@param {VSCode} vscode\n@param {ExtentionContext} context' ] (Since version 0.10.0) | | outputFilename | 'output.js' | | | basePath | '' | 内部では Path.resolve(basePath) した値が使われます。配列 ['projectA/src','projectB/src'] も可能です。 | | wrapAll | false | wrapAll について |

各ファイルの内容

// myUtilProject/global.js
var Util = {};

// myUtilProject/packageGlobal.js
var TEMP = {};

// myUtilProject/ajaxModule/modulebGlobal.js
var ajaxCommon;

// myUtilProject/ajaxModule/XHR.js
if( window.XMLHttpRequest ){}

// myUtilProject/ajaxModule/Fetch.js
if( window.fetch ){}

// myUtilProject/toEndOfScript.js
function finalize(){}

output

// myUtilProject/global.js
var Util = {};

(function(window,document){
    // myUtilProject/packageGlobal.js
    var TEMP = {};

    (function(){
        // myUtilProject/ajaxModule/modulebGlobal.js
        var ajaxCommon;

        // myUtilProject/ajaxModule/XHR.js
        if( window.XMLHttpRequest ){}

        // myUtilProject/ajaxModule/Fetch.js
        if( window.fetch ){}
    })();
    // myUtilProject/toEndOfScript.js
    function finalize(){}
})(window,document);

wrapAll

モジュール下の各ファイルを (function(){})() でラップするのは、テスト用途です。共用の変数や関数を適切に moduleGlobal に記述していない場合、例えば Clodure Compiler 等でエラーが出ます。

深すぎる function の入れ子は、Presto Opera で不具合に遭遇した(*1)ことがある為、避けます。

  1. Opera 9 ~ 11 で動かない問題.
// myUtilProject/global.js
var Util = {};

(function(){
    // myUtilProject/packageGlobal.js
    var TEMP = {};

    (function(){
        // myUtilProject/ajaxModule/modulebGlobal.js
        var ajaxCommon;

        (function(){
            // myUtilProject/ajaxModule/XHR.js
            if( window.XMLHttpRequest ){}
        })();
        (function(){
            // myUtilProject/ajaxModule/Fetch.js
            if( window.fetch ){}
        })();
    })();
    // myUtilProject/toEndOfScript.js
    function finalize(){}
})();

toEndOfScript (Since version 0.9.9)

全てのモジュールが読み込まれてから実行したいコードの記述されたファイルのパスには toEndOfScript に指定した文字列を含むようにします。ファイルは packageGlobal の最期に出現します。

packageGlobalArgs に配列を指定する (Since version 0.9.9)

配列の長さは2です。1番目の配列には packageGlobal を囲む (funciton(){})() の引数名。2番目の配列には (funciton(){})() を呼び出す値です。こちらには関数を書くことも出来ます。

指定例: [ "window,emptyFunction,undefined", "this,new Function,void 0" ]

出力例: (funciton(window,emptyFunction,undefined){...})(this,new Function,void 0);

複数の package で packageGlobal を共有する(Since version 0.9.8)

異なるディレクトリで開発している package 間で、packageGlobal を共有できます。この為には、basePath に配列を与えます。

MyProjects/packageB/gulpfile.js

gulp.src( [ 'D:/MyProjects/packageA/src/js/**/*.js', './src/js/**/*.js' ] )
    .pipe(
        gulpDPZ(
            {
                basePath : [ 'MyProjects/packageA/src/js/', 'MyProjects/packageB/src/js/' ]
            }
        )
    )

output

'packageA/src/js/''packageB/src/js/' が同一ディレクトリに存在するように扱われます。

// file:MyProjects/projectA/src/js/global.js
var g_Util = {};

// file:MyProjects/projectB/src/js/global.js
var g_Framework = {};

(function(window,document){
    // file:MyProjects/projectA/src/js/packageGlobal.js
    var p_projectA_TEMP = {};

    (function(){
        // file:MyProjects/projectA/src/js/domModule/moduleGlobal.js
        var m_domCommon;

        // file:MyProjects/projectA/src/js/domModule/DOM0.js
        if( document.all ){}

        // file:MyProjects/projectA/src/js/domModule/DOM1.js
        if( document.getElementsByTagName ){}
    })();

    (function(){
        // file:MyProjects/projectA/src/js/ajaxModule/moduleGlobal.js
        var m_ajaxCommon;

        // file:MyProjects/projectA/src/js/ajaxModule/XHR.js
        if( window.XMLHttpRequest ){}

        // file:MyProjects/projectA/src/js/ajaxModule/fetch.js
        if( window.fetch ){}
    })();

    // file:MyProjects/projectB/src/js/packageGlobal.js
    var p_projectB_CACHE = {};

    (function(){
        // file:MyProjects/projectB/src/js/modalWindow/moduleGlobal.js
        var m_modalWindowCommon;

        // file:MyProjects/projectB/src/js/modalWindow/manager.js
        var modalWindowManager;

        // file:MyProjects/projectB/src/js/modalWindow/modalWindowClass.js
        var ModalWindowClass;
    })();
})(window,document);