66956


Webサービスを個人的に開発しております。  
npm, browserifyを利用し、フロントエンドで利用するいくつかの外部ライブラリを1つにビルドし、  
HTMLにはjsファイル1行書けば済むように運用したいのですがエラーが出てしまい、解決できずに悩んでおります。  
LaravelMix+webpackを用いて同じことをしようとそちらでも試行錯誤したのですが後述する同様のエラーで解決に至らずといった経緯です。

## 環境

Docker Desktop  
Docker 19.03  
Laravel 7.12  
npm 6.14.5  
browserify 16.5.1

## 主なエラー内容

`Uncaught ReferenceError: muuri is not defined`

## ソースファイル

package.json

[code]

        "private": true,
        "scripts": {
            "dev": "npm run development",
            "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
            "watch": "npm run development -- --watch",
            "watch-poll": "npm run watch -- --watch-poll",
            "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --config=node_modules/laravel-mix/setup/webpack.config.js",
            "prod": "npm run production",
            "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
            "build": "browserify resources/js/main.js -o public/js/bundle.js"
        },
        "devDependencies": {
            "@fortawesome/fontawesome-free": "^5.13.0",
            "axios": "^0.19",
            "bootstrap": "^4.0.0",
            "cross-env": "^7.0",
            "font-awesome-scss": "^1.0.0",
            "jquery": "^3.2",
            "laravel-mix": "^5.0.1",
            "lodash": "^4.17.13",
            "popper.js": "^1.12",
            "resolve-url-loader": "^3.1.0",
            "sass": "^1.15.2",
            "sass-loader": "^8.0.0",
            "vue-template-compiler": "^2.6.11"
        },
        "dependencies": {
            "browser-sync": "^2.26.7",
            "browser-sync-webpack-plugin": "^2.2.2",
            "browserify": "^16.5.1",
            "muuri": "^0.8.0",
            "web-animations-js": "^2.3.2"
        }
    }
    
[/code]

head.blade.php

[code]

    @section('head')
    
    ~~~
    
    <script src="{{ mix('js/manifest.js') }}"></script>
    <script src="{{ mix('js/vendor.js') }}"></script>
    <script src="{{ mix('js/app.js') }}"></script>
    <script type="text/javascript" src="js/bundle.js"></script> ビルド後のjs読み込み
    
    <script type="text/javascript">
         var grid = new muuri('.grid'); 実際のエラー場所
    </script>
    ~~~
    
    @endsection
    
[/code]

## やったこと

  1. npm経由で各種パッケージをインストール  
・今回は Muuri というグリッドレイアウトjQueryプラグインを導入します  
・モジュール管理としてbrowserifyを導入  
`npm install muuri`  
`npm install browserify`  
`npm run dev`

npm listコマンド、およびpackage.jsonにて、npmでインストールしたパッケージが導入されているのを確認。  
node_modulesディレクトリにもインストールしたディレクトリがあることを確認。

  2. ビルド・コンパイル実行コマンドをpackage.jsonに追記する

[code]

    "build": "browserify resources/js/main.js -o public/js/bundle.js"
    
[/code]

  3. main.js の記載  
`var muuri = require('muuri');`

  4. ビルド実行  
`npm run build`

他、必要な情報等ございましたらご指摘いただきたく思います。  
同様のことをするならLaravelMixを用いた方がもう少しスッキリするのでしょうか？

よろしくお願いいたします。


CC BY-SA 4.0
2020-05-25T01:22:31.363
66955
2020-05-25T02:08:20.963
40319
question
docker laravel npm webpack browserify
npm, browsefiryを利用し複数の外部ライブラリを１つにビルドする運用をしたいが、フロント側でクラス名のnot definedエラーが出力されてしまう


コードを見る限り、browserifyでビルドした成果物がグローバルに`muuri`を提供していると考えているようですが、これは間違っています。  
`browserify`などのビルドツールは設定しない限り、ファイル内(bundle.js)のスコープでしか`muuri`という変数にアクセスすることができないようになっています。

[code]

    <script type="text/javascript" src="js/bundle.js"></script> ビルド後のjs読み込み
    
    <script type="text/javascript">
         var grid = new muuri('.grid'); // ここは budnle.jsのスコープ外なので、参照エラーになる
    </script>
    
[/code]

したがって、正しく動かしたいのであれば、`main.js`を次のように書きます。

[code]

    // main.js
    var muuri = require("muuri");
    
    // HTMLが読み込まれた後に`muuri`を利用しなければエラーが出ます。
    document.addEventListener("DOMContentLoaded", () => {
      var grid = new muuri(".grid");
    });
    
[/code]

これでビルドを行ってみてください。HTML側は`bundle.js`のみ読み込めば良いです。上記のコードは`<head>`タグ内にscriptを埋め込む前提で作成しているため`DOMContentLoaded`のイベントにフックさせていますが、`</body>`の手前でscriptを動かす場合は不要です。


CC BY-SA 4.0
2020-05-25T02:08:20.963
66956
2020-05-25T02:08:20.963
7997
66955
answer