はじめに
今回は私が体験したwebpackのハマった点を紹介していきます。
PromiseとIE11
jsで非同期処理を実装する際、axiosを利用するシーンは多いのでないでしょうか。
ただそのままこのaxiosIE11で使用することはできません。
IE11以下では、非同期処理を可能にするPromiseにサポートしていないため。
(IEは見事に真っ赤ですねw)
本題
とある日私は、既存プロジェクトに追加の実装を担当することに
そのプロジェクトでは既にwebpackの設定がされており、私は実際のjsにだけ意識をして開発を進めていました。
そして無事リリース。(この時はスマホサイトのみ実装)
数週間後、新規機能をPCにも実装が決まり、スマホで実装したソースを流用して開発することに。
ですが開発の途中、IE11でテストをしているとエラーが発生。
調査していると疑問が、「既存の機能では、どう対処しているのだろう」と。
ソースを見てみても特段変わった記述は見つかりませんでした。
ソース比較
下記は実際のソースから一部抜粋したものになります。
パッと見大まかな処理は変わりません。
ですがパターンBではIE11でエラーが起きてしまいました。
パターンA(既存コード)
IE11: ○
let Vue = require('vue');
let axios = require('axios');
new Vue({
data: {},
methods: {
getData: function() {
return axios({
method: 'post',
url: '/XXX/',
data: params,
});
}
}
});
パターンB(新規コード)
IE11: ×
<template>...</template>
<script>
import axios from 'axios';
export default {
data: function() {
...
},
methods: {
getData: function() {
return axios({
method: 'post',
url: '/XXX/',
data: params,
});
}
}
}
</script>
import Vue from 'vue';
import App from './App.vue';
new Vue({
...
});
なぜ
webpackの設定とjsの記述に問題がありそうだと推測。
既存コードはrequire構文でaxiosを読み込んでいる。
require構文はwebpackが直接コンパイルできるので、依存関係はwebpack側でシンプルに解決できていました。
一方新規のコードはimport構文を使用しており、webpackでコンパイルする前にbabelがトランスコンパイルが行われていました。
またwebpackの設定を見てみると、babelが.jsにのみ適応されていました。
新規コードでは.vueファイル側でaxiosを読み込んでおり、上手く依存関係を解決出来なくなっていました。
...
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
'presets': ['@babel/preset-env']
}
}
},
...
解決策
nodeモジュールのes6-promise
を読み込み、Promiseのトランスコンパイルさせることで取り急ぎは解決。
<script>
import axios from 'axios';
require('es6-promise').polyfill();
...
</script>
※とりあえず解決したが、今度はwebpackの設定から根本解決できるようにしていきたいです。
最後に
今回の件が無かったらwebpackに対する理解を深める機会が無かったかもしれない。
そう言う意味ではIEに感謝(?)