VueCLIで作ったアプリで、VuexのヘルパーmapState
をスプレット演算子にして使おうとしたらエラーになったので試行錯誤した上、webpackのversionを3から4に変えてbabelのversionをアップグレードしたりエラー処理をした手順を書きます。
"vue": "^2.5.22",
"vuex": "^3.1.0"
実行したかったこと
import { mapState } from 'vuex';
export default {
computed: {
...mapState(['admin']),
currentRouteName() {
return this.$route.name;
},
},
}
このように書くと、「スプレット演算子使えませんよ」と怒られる。
Syntax Error: Unexpected token (74:4)
72 | export default {
73 | computed: {
> 74 | ...mapState(['admin']),
| ^
75 | currentRouteName() {
76 | return this.$route.name;
77 | },
「ま、スプレット演算子使えるようにVueCLIで設定したファイルをいじれば大丈夫でしょ。」
と安易な気持ちで直そうと思ったら意外にハマったのでその直し方を共有します。
まず始めにやったこと(直せなかった)
ググっていったらやはりスプレット演算子できなくて困ってる人がいました。
- スプレッド演算子の導入
- Vue-loader: Unexpected token error for using spread operator on my vue component
- Error spread operator when using Bublé
対応策
対応策を2つ見つけました。
が、どれもエラーは直らず。。
- plugin「transform-object-rest-spread」を使う
- bubleを使って対応
"plugins": ["transform-object-rest-spread"]
module.exports = {
...
buble: {
objectAssign: 'Object.assign',
},
}
次にしたこと(エラーを解消)
次に考えたのはWebpackのversionをBabelのversionを上げてスプレット演算子を使えるようにするしかないかなって思いました。
なので下記のことをしました。
実行したこと
- webpackを3から4にする
- babelを最新「@」に変更
-
Tapable.plugin is deprecated. Use new API on .hooks instead
エラー解消 -
Error: Cannot find module 'babel-core'
エラー解消 -
Module build failed (from ./node_modules/eslint-loader/index.js): TypeError: Cannot read property 'eslint' of undefined
エラー解消
webpackを3から4にする
これはそんな難しいことじゃないですね。
それぞれを最新にしました。
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3",
"webpack-dev-server": "^3.2.1",
babelを最新「@」に変更
これはなかなか自力でできないのでググりました。
- 最新版で学ぶwebpack 4入門 – Babel 7でES2018環境の構築(React, Vue, Three.js, jQueryのサンプル付き)
- Webpack 4:babel-loader のアップデートで起きたエラーを解決
これらを参考にパッケージを最新にしたりwebpack.base.conf.js
を書き換えました
// add
"@babel/core": "^7.3.4",
"@babel/preset-env": "^7.3.4",
// remove
"babel-core": "^6.22.1",
"babel-loader": "^7.1.1",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-plugin-transform-vue-jsx": "^3.5.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: [
[
"@babel/preset-env",
{
"useBuiltIns": "usage"
}
]
],
},
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
Tapable.plugin is deprecated. Use new API on .hooks instead
エラー解消
yarn dev
をすると上記のエラーで怒られたのでそれを直します。
ここに書いてあるようにhtml-webpack-plugin
とextract-text-webpack-plugin
をupgradeすると書いてあるのでそれを実行
I'm still getting:
DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead
DeprecationWarning: Tapable.apply is deprecated. Call apply on the plugin directly instead
with:
"html-webpack-plugin": "^3.0.4"
"extract-text-webpack-plugin": "^4.0.0-beta.0"
same with or without "extract-text-webpack-plugin": "^4.0.0-beta.0"
"html-webpack-plugin": "^3.2.0",
"extract-text-webpack-plugin": "4.0.0-beta.0",
Error: Cannot find module 'babel-core'
エラー解消
上記のエラーを解消するためにbabel-loader
を最新にして、ついでにcss-loader
も最新にしました。
"css-loader": "^2.1.1",
"babel-loader": "^8.0.5",
Module build failed (from ./node_modules/eslint-loader/index.js):TypeError: Cannot read property 'eslint' of undefined
エラー解消
これが時間かかりました。
まずはes-lint
を最新にしました。
// upgrade
"eslint": "^5.15.1",
"eslint-config-airbnb-base": "^13.1.0",
"eslint-friendly-formatter": "^4.0.1",
"eslint-loader": "^2.1.2",
"eslint-plugin-import": "^2.16.0",
"eslint-plugin-vue": "^5.2.2",
"eslint-import-resolver-webpack": "^0.11.0",
で、エラーの内容がeslint-loader
が機能していないということなので、es-loader
が書かれているところを見ると
const createLintingRule = () => ({
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: !config.dev.showEslintErrorsInOverlay
}
});
・
・
・
module: {
rules: [
...(config.dev.useEslint ? [createLintingRule()] : []),
js、vueファイルがcompileされる前にlintチェックをする処理なんですね。
で、その処理がWebpack4になってから書くところが変わったとのことで。
webpack.config.js
でLoaderOptionsPlugin
pluginを読み込んでそこで定義しました。
new webpack.LoaderOptionsPlugin({ options: {
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: !config.dev.showEslintErrorsInOverlay
}
}
}),
include: [resolve('src'), resolve('test')],
これでlocalを立ち上げることができました。
$ yarn dev
無事に...mapState(['admin'])
も機能してリファクタリングできました。
3時間くらい要しました。。
※webpack.config,jsのproduction対応もしないとyarn build
でerrorになります。