7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

LaravelでVueコンポーネントの動的import(遅延ローディング)をする

Last updated at Posted at 2018-01-11

poi上で作ったvueコンポーネントをLaravelプロジェクトに載っけようとしたらエラーが出る

Vueはコンポーネントの遅延ローディングをサポートしていますが、poiでは何もしなくても動いた構文がLaravel5.5ではビルドエラーになってしまいます

コンポーネントの動的読み込み部分で以下の様なエラーが出ます

console
ERROR in ./node_modules/babel-loader/lib?{"cacheDirectory":true,"presets":[["env",{"modules":false,"targets":{"browsers":["> 2%"],"uglify":true}}]],"plugins":["transform-object-rest-spread",["transform-runtime",{"polyfill":false,"helpers":false}]]}!./node_modules/vue-loader/lib/selector.js?type=script&index=0&bustCache!./resources/assets/js/components/sample_switch_smoothly/SwitchSmoothly.vue
Module build failed: SyntaxError: Unexpected token (38:20)

> 38 | const CompB = () => import('./CompB.vue')
     |                     ^

えー何で?Laravelって何もしなくてもES6イケるんじゃないの?
ぐぐってみたら、babelにdynamic import対応プラグインを追加せにゃならんらしい。エーめんどくせ

ここで解決されてたので、それを丸パク参考にしてみる
Vue.js Async Components #1249

console
% yarn add babel-plugin-syntax-dynamic-import --dev

.babelrc ファイルをプロジェクトrootに作成する。内容は以下の通り

.babelrc
{
    "presets": [
        [
            "env",
            {
                "targets": {
                    "browsers": [
                        "last 2 versions"
                    ]
                }
            }
        ]
    ],
    "plugins": ["syntax-dynamic-import"]
}

webpack.mix.js に以下の設定を追加

webpack.mix.js
mix.webpackConfig({
    output: {
        chunkFilename: 'js/[name].js',
    },
});

これでコンパイルエラーも無くなって、ちゃんと2.jsみたいのが出来るのだが、
実行時にそれを読み込もうとする所でエラーになる

エラーは以下

console
GET http://localhost:8080/[現在の画面のURL]/2.js net::ERR_ABORTED

[Vue warn]: Failed to resolve async component: function compB() {
            return __webpack_require__.e/* import() */(2).then(__webpack_require__.bind(null, 115));
        }
Reason: Error: Loading chunk 2 failed.

何故相対パスでアクセスするのか・・・馬鹿なの?

webpack.mix.js にpublicPathの設定を追加

webpack.mix.js
mix.webpackConfig({
    output: {
        chunkFilename: 'js/[name].js',
        publicPath: '/',
    },
});

やっと動いたー

なんか古いchunkファイルが残るんですけど!

無事に動的importを使ったvueが動作したんですが、# yarn run watch とか使って開発してると、hot reload関係なのかチャンクファイルがダブります。
0.js, 1.js, 2.js のある状態でvueファイルを編集すると、3.js, 4.js, 5.js が出来ちゃいます。
まあ、デプロイ時には関係ないし開発中も大して実害は無いけども、キモチワルイので対処します。

laravel-mix や babel に出力ファイルを削除してから作る様な設定は無い様子
しょうがないのでnpm scriptに削除タスクを追加(最初の2つ)
jsフォルダには他のファイルもあったりするのでchunksフォルダ以下にチャンクファイルを出力する様に変更

package.json
{
    "scripts": {
        "predevelopment": "npm run clean",
        "clean": "rimraf public/js/chunks",
        
        "dev": "npm run development",
        "development": "cross-env NODE_ENV=development (略)"
    },
}
webpack.mix.js
mix.webpackConfig({
    output: {
        chunkFilename: 'js/chunks/[name].js', <-- ここを変更
        publicPath: '/',
    },
});

最後に

poi便利

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?