JavaScriptで名前空間を使ってみたら、ファイル結合の順序で困ったことに

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,679

usugita_san

score 229

JavaScriptの名前空間について興味があって、以下のサイトを参考にして、簡単な名前空間を使ったJavaScriptの実装を行ってみました。

http://qiita.com/kenju/items/0d8f85df205ea4978508

定義した名前空間はこんな感じです。

var HOGEAPP = {
    VIEW:{},
    MODEL:{},
    CONF{}
};

こんな感じでファイルを分割して書いてます。
init.js

var HOGEAPP = {
    VIEW:{},
    MODEL:{},
    CONF{}
};

HOGEAPP.init = function(){
    //アプリの初期化処理
};

view.js

HOGEAPP.VIEW.addEvent = function(){
    //viewに関する処理
};

model.js

HOGEAPP.MODEL.getData = function(){
   //modelに関する処理
};

conf.js

HOGEAPP.CONF.getConfig = function(){
    //confに関する処理
};

これらのファイルを、grantのconcatというのを使って1つのファイルにしています。
chromeで読み込んで実行したら、なぜかHOGEAPP.CONF.getConfig = function(){ の箇所でエラーになっていました。

どうも、先に名前空間の定義をしていないため、「HOGEAPP.CONF」が見つからないよって言われているんです。

先に名前空間の定義をしちゃえばいいんですが、ファイルを結合しているため、ファイルの先頭に名前空間の定義を持ってくる事が出来ません。

このような場合、どうやって先に名前空間の定義を持ってくるのでしょうか?
HTMLソースに書いておけば一応可能かもしれませんが、綺麗な方法とも思えません。
別のJavaScriptファイルを先に読み込んでおくのでしょうか?それだとせっかくファイルを結合して1つにしているのに無駄になる気がします。
皆様はどうやっているのでしょうか?

追記です。
Gruntfile.jsの記述は以下の通りです。

module.exports = function (grunt) {
    var pkg = grunt.file.readJSON('package.json');
    grunt.initConfig({
        concat: {
            files: {
                // 元ファイルの指定。
                src : 'src/*.js',
                // 出力ファイルの名前・パス指定
                dest: 'test/lib/hogeapp.js'
            }
        }
    });
    // プラグインのロードやタスクの登録
    grunt.loadNpmTasks('grunt-contrib-concat');

};
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+2

「grunt で結合したコード」と「コンソールに出力されたエラーログ」を開示した方が良いと思います。
何となく、名前空間とか関係なしにコロン、セミコロン漏れが原因が気がするのですが…。

以下、単純結合したコード。

var HOGEAPP = {
    VIEW:{},
    MODEL:{},
    CONF{}  // SyntaxError: Unexpected token {
}

HOGEAPP.init = function(){
    //アプリの初期化処理
};HOGEAPP.VIEW.addEvent = function(){
    //viewに関する処理
};HOGEAPP.MODEL.getData = function(){
   //modelに関する処理
}HOGEAPP.CONF.getConfig = function(){ // SyntaxError: Unexpected identifier
    //confに関する処理
}

修正後のコード。

var HOGEAPP = {
    VIEW:{},
    MODEL:{},
    CONF:{}  // コロンを入れる
}; // セミコロンを入れる

HOGEAPP.init = function(){
    //アプリの初期化処理
};HOGEAPP.VIEW.addEvent = function(){
    //viewに関する処理
};HOGEAPP.MODEL.getData = function(){
   //modelに関する処理
};HOGEAPP.CONF.getConfig = function(){ // セミコロンを入れる
    //confに関する処理
}

Re: usugita_san さん

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/14 12:51

    すみません、どうもgruntのconcatの順番指定をすればいい話らしく、今試しているところです。これでダメでしたら、仰る通り結合後のJavaScriptファイルとか、追記したいと思います。

    大変申し訳ありませんでした・・・。

    キャンセル

  • 2016/09/14 13:12

    すみませんでした。セミコロンは、私が投稿するときに間違えて消してしまっていました。先ほど編集しました。失礼しました。

    キャンセル

check解決した方法

0

自己解決しましたー

gruntの設定ファイルをいじって、concatの順序を変更する事で解決しました。

module.exports = function (grunt) {
    var pkg = grunt.file.readJSON('package.json');
    var BUILD_ORDERED_LIST = ["src/init.js","src/*.js"];
    grunt.initConfig({
        concat: {
            dist:{
                src: BUILD_ORDERED_LIST,
                dest: 'test/lib/hogeapp.js'
            }
        }
    });
    // プラグインのロードやタスクの登録
    grunt.loadNpmTasks('grunt-contrib-concat');
};

要するに、名前空間とか宣言する前に、名前空間の中身を使おうとしちゃってエラーになってたみたいです。
concatってただ結合するだけじゃないんですね。順番とか指定できるんですね。・・・そりゃそうか。
ちなみに、"src/init.js","src/*.js"っていう指定方法だと、init.jsが重複するんじゃないかと思ってたんですが、重複したものは省いてくれるみたいです。良かった良かった。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.21%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる