vue init webpackで作成したプロジェクトをwebpack4に移行する

今更ながらvue init webpackで作成したプロジェクトをwebpack4系に移行したのでメモ。

Vue CLI3系を利用すればwebpack4系のプロジェクトが生成されるけど、webpack.config自体は@vue/cli-serviceに内包されているため、全体像が掴みづらいので勉強の意味も込めて現状のものをアップデートした。
vue cli-serviceのコードを見ると、webpack-chainなどを利用して設定が生成され各種コマンドを実行している様子が伺える。

プロジェクト構成は大雑把に↓な感じ。(特に生成時から変えていない)

app
├── build
│   ├── utils.js
│   ├── webpack.base.conf.js
│   ├── webpack.dev.conf.js
│   ├── webpack.prod.conf.js
│   └── ...
├── config
│   ├── dev.env.js
│   ├── index.js
│   └── prod.env.js
├── dist
├── node_modules
├── src
├── static
├── .eslintrc.js
├── package.json
├── postcss.config.js
└── ...

依存関係アップデート

webpack-cliが必要になったのでこれも追加

// webpack関連
npm isntall --save-dev webpack@latest
npm isntall --save-dev webpack-bundle-analyzer@latest
npm isntall --save-dev webpack-cli@latest
npm isntall --save-dev webpack-merge@latest
npm isntall --save-dev html-webpack-plugin@latest
npm isntall --save-dev mini-css-extract-plugin@latest
npm uninstall extract-text-webpack-plugin

// vue関連
npm isntall vue@latest
npm isntall --save-dev vue-loader@latest
npm isntall --save-dev vue-style-loader@latest
npm isntall --save-dev vue-template-compiler@latest
   "dependencies": {
-    "vue": "^2.5.2"
+    "vue": "^2.5.17"
   },
"devDependencies": {
...
-    "extract-text-webpack-plugin": "^3.0.0",
     "file-loader": "^1.1.4",
     "friendly-errors-webpack-plugin": "^1.7.0",
-    "html-webpack-plugin": "^2.30.1",
+    "html-webpack-plugin": "^3.2.0",
+    "mini-css-extract-plugin": "^0.4.3",
-    "vue-loader": "^13.7.2",
-    "vue-style-loader": "^3.0.1",
-    "vue-template-compiler": "^2.5.2",
+    "vue-loader": "^15.4.2",
+    "vue-style-loader": "^4.1.2",
+    "vue-template-compiler": "^2.5.17",
-    "webpack": "^3.12.0",
-    "webpack-bundle-analyzer": "^2.13.1",
-    "webpack-dev-server": "^2.9.1",
-    "webpack-merge": "^4.1.3"
+    "webpack": "^4.20.2",
+    "webpack-bundle-analyzer": "^3.0.2",
+    "webpack-cli": "^3.1.1",
+    "webpack-dev-server": "^3.1.9",
+    "webpack-merge": "^4.1.4"

modeオプション追加

dev, prodのwebpack.confにmodeを追加し、mode設定により自動的にenableになるPluginを削除する。

  • build/webpack.dev.conf.js
    • mode: 'development' を追加
    • webpack.NamedModulesPluginを削除
    • webpack.NoEmitOnErrorsPluginを削除
  • build/webpack.prod.conf.js
    • mode: 'production' を追加
    • webpack.optimize.ModuleConcatenationPluginを削除
  • NODE_ENVの設定削除(modeで自動設定される)
    • config/dev.env.js
    • config/prod.env.js

https://webpack.js.org/concepts/mode/

mini-css-extract-plugin追加

build時にスタイルを.cssファイルに抽出するのにextract-text-webpack-pluginを利用しているが、

⚠️ Since webpack v4 the extract-text-webpack-plugin should not be used for css. Use mini-css-extract-plugin instead.

なので、mini-css-extract-pluginを代わりに使用する。

  • mini-css-extract-pluginを追加
npm isntall --save-dev mini-css-extract-plugin@latest
  • build/webpack.prod.conf.js
    • ExtractTextPluginをMiniCssExtractPluginに変更
-    new ExtractTextPlugin({
+    new MiniCssExtractPlugin({
       filename: utils.assetsPath('css/[name].[contenthash].css'),
-      // Setting the following option to `false` will not extract CSS from codesplit chunks.
-      // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
-      // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, 
-      // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
-      allChunks: true,
-    }),
  • build/utils.js
    • loader生成している、generateLoaders関数内のExtractTextPluginをMiniCssExtractPluginに変更(vue-style-loaderを最初にもってくること)
     // Extract CSS when that option is specified
     // (which is the case during production build)
     if (options.extract) {
-      return ExtractTextPlugin.extract({
-        use: loaders,
-        fallback: 'vue-style-loader'
-      })
+      return ['vue-style-loader', MiniCssExtractPlugin.loader].concat(loaders)
     } else {
       return ['vue-style-loader'].concat(loaders)
     }

github.com

optimization.minimizerの設定

production modeの場合はデフォルトでminifyされるが、UglifyJsPluginのオプションを利用していしてるためoptimization.minimizerに移す。同時にOptimizeCSSPluginも。

  • build/webpack.prod.conf.js
+  optimization: {
+    minimizer: [
+      new UglifyJsPlugin({
+        uglifyOptions: {
+          compress: {
+            warnings: false
+          }
+        },
+        sourceMap: config.build.productionSourceMap,
+        parallel: true
+      }),
+      new OptimizeCSSPlugin({
+        cssProcessorOptions: config.build.productionSourceMap
+          ? { safe: true, map: { inline: false } }
+          : { safe: true }
+      })
+    ],
....
   plugins: [
-    new UglifyJsPlugin({
-      uglifyOptions: {
-        compress: {
-          warnings: false
-        }
-      },
-      sourceMap: config.build.productionSourceMap,
-      parallel: true
-    }),
-    // Compress extracted CSS. We are using this plugin so that possible
-    // duplicated CSS from different components can be deduped.
-    new OptimizeCSSPlugin({
-      cssProcessorOptions: config.build.productionSourceMap
-        ? { safe: true, map: { inline: false } }
-        : { safe: true }
     }),

https://webpack.js.org/configuration/optimization/#optimization-minimizer

optimization. splitChunksの設定

v4からCommonsChunkPluginは削除され、SplitChunksPluginになったので移行する。 どのように分割するかはプロジェクトによって異なるので、各自で設定する。

  • build/webpack.prod.conf.js
+  optimization: {
...
+    splitChunks: {
+      cacheGroups: {
+        vendors: {
+          test: /[\\/]node_modules[\\/]/,
+          name: 'vendors',
+          chunks: 'all'
+        }
+      }
+    }
+  },

...
   plugins: [
-    // split vendor js into its own file
-    new webpack.optimize.CommonsChunkPlugin({
-      name: 'vendor',
-      minChunks (module) {
-        // any required modules inside node_modules are extracted to vendor
-        return (
-          module.resource &&
-          /\.js$/.test(module.resource) &&
-          module.resource.indexOf(
-            path.join(__dirname, '../node_modules')
-          ) === 0
-        )
-      }
-    }),
-    // This instance extracts shared chunks from code splitted chunks and bundles them
-    // in a separate chunk, similar to the vendor chunk
-    // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
-    new webpack.optimize.CommonsChunkPlugin({
-      name: 'app',
-      async: 'vendor-async',
-      children: true,
-      minChunks: 3
-    }),

意図通りに分割できているかは、webpack-bundle-analyzerで確認する。

npm run build --report

https://webpack.js.org/plugins/split-chunks-plugin/ medium.com

optimization. runtimeChunkの設定

webpackは、モジュール管理のためruntimeとmanifestのコードを生成するのでそれらをmanifest.jsとして出力させる。

  • build/webpack.prod.conf.js
+  optimization: {
...
+    runtimeChunk: {
+      name: 'manifest'
+    },
...
   plugins: [
-    // extract webpack runtime and module manifest to its own file in order to
-    // prevent vendor hash from being updated whenever app bundle is updated
-    new webpack.optimize.CommonsChunkPlugin({
-      name: 'manifest',
-      minChunks: Infinity
-    }),

こちらも、意図通りに分割できているかは、webpack-bundle-analyzerで確認する。

npm run build --report

https://webpack.js.org/concepts/manifest/ survivejs.com

VueLoaderPlugin追加

  • build/webpack.base.conf.js
 const config = require('../config')
+const VueLoaderPlugin = require('vue-loader/lib/plugin')
 const vueLoaderConfig = require('./vue-loader.conf')
...
+  plugins: [
+    new VueLoaderPlugin()
+  ],
   module: {

postcss.config.js追加

対象ブラウザの設定は各自行う。

  • postcss.config.js
+module.exports = {
+  plugins: {
+    autoprefixer: {},
+  },
+};

雑ですがこんなイメージ。 あ、babelも上げないと。

生ウニ丼を食べる

ウニが大好きなワタクシはたまに贅沢をします。
それがこちら...

f:id:uu_ka:20180830205017j:plain

ジャーン!
岩手県産生ウニ 牛乳瓶入り!!
4年ぶり2回目の出場。いや、登場。

今回もヤマコー片桐鮮魚店さんで購入しました。
(しかもサービスで割引きやワカメまでつけてくれました。感謝。)

気合が入ってしまい、本わさびを用意しすりおろし、手抜き味噌汁まで準備し、しれっと一緒に注文してしまったいくらと併せて丼ぶりに盛り付けました。

f:id:uu_ka:20180901160357j:plain

美味しい....!!
でも食べ過ぎは要注意、気持ち悪くなりますからね。

偶然にも前日もウニをいただきました。
こちらも美味しかったですが、瓶入りウニのほうが別格。

f:id:uu_ka:20180831202907j:plain

こちらは....
9年前にも似たような行動をとっていたようで、初めて握ったまぐろのお寿司🍣
見た目が大事だということが、とてもよく分かる例ですね。

f:id:uu_ka:20090129184422j:plain

みなさんもお試しあれ。

www.yamakou-katagiri.jp

Dagger2を理解するのに参考にしたページ

正直、一度断念しました。なめてました。

2度目のtryで全体像はつかめたと思うので、とても参考になったページをメモしておきます。 分かりやすく解説してくれていて、ホント感謝ですね。

Android開発の振り返り

年末なので、今年Android開発でやったことを振り返ります。

今年は初めて仕事でAndroid開発をやった重要な年でした。

昨年スタートアップに転職したのですが、ほどなくしてiOS版アプリをリリースし、Android版も出したいよねって話になりました。 アプリ開発も経験したいなと思っていたのでタイミング的にバッチリだったんですが、未経験かつ短期間でクオリティ高いアプリ出すのが難しいので、初回は外注することに。納品後に本格スタートしたって感じです。 無念なところもありつつ、動くコードを見れたのはラッキーでした。感謝!

アプリならではの悩みどころは、iOS担当の子に多大なサポートを頂きつつ、時に一緒に作りつつ乗り切りました。 まぁ基本的には、細かな修正や機能追加がメインなわけですが、それとは別にやったこともあります。

  • kotlin導入(まずは1機能書換え)
  • RxJava 1系から2系に移行
  • AS3へ移行
  • targetSdkVersionを27げ諸々対応
  • vectorDrawable使ってみる
  • カードがchoreographyちっくにぐわっと広がるモーション
  • circleCI2.0 対応

やったと言うより、直近1ヶ月位でやっている未リリースのものと言うのが正しい表現ですが、年明けたらリリースします。 何やるにしても分からないから始まるので大変なんですけど、やればやるほど、なるほど!なるほど!っとなるのが楽しいところでも有りますよね。 まだまだ知識が追いついていないので、もっと勉強して来年は完全なAndroidの人になる予定です。

ずっと1人でやっているので、一緒に開発できる人がいたらなぁと思う日々ですが頑張ります!

FFコンサートに行ってきた - Distant Worlds: music from FINAL FANTASY

有楽町の東京国際フォーラムで行われた、「FINAL FANTASY 30th Anniversary Distant Worlds: music from FINAL FANTASY 而立 / JIRITSU」に参加してきました。

www.square-enix.co.jp

思い返すと2002年に開催されたコンサートに初めて参加してから、およそ6回目?の参加です。

感想:

  • 開場時間でなく、開演時間に合わせて行動した
  • 仕事柄ブラボーという言葉に過剰に反応した 笑
  • 天野喜孝さんを初めて見た
  • 海外から来ている人がそれなりにいた
  • 星降る峡谷を聞けた
  • 鈴木瑛美子さんの歌声がとても良く引き込まれた

タイトルにもありますが、今年でFF30周年でした。
同じ年に生まれて、FF5で初めて出会い、FF7で"どうやって作ってるんだろう、作ってみたい"という思いからコンピューターに興味を持ち、社会人でエンジニアとして働いています。

ゲームはあまりやらなくなってしまいましたが、こうして30歳になっても音楽やイベントで楽しませてもらっています。

また、楽天時代には鈴木尚さん担当事業の開発メンバーとしてご一緒する機会がありました。
何やら只ならぬ縁を感じます。

沢山のきっかけをくれたFFに感謝しつつ、今後も応援していきます!

f:id:uu_ka:20171210200100j:plain


www.youtube.com

android studio起動時のプロジェクト一覧にアイコンを表示する

ある時
いつも開きっぱのandroid studioのプロジェクトを誤って閉じてしまいました。
すると、welcome to android studio画面が表示されたのですが、感じる違和感・・・

参考用に眺めていたDroidKaigi2017のプロジェクトだけアイコンが表示されている!!

f:id:uu_ka:20170930015230j:plain

どうググったら良いか分からず、プロジェクト設定の差分を確認すると、

.idea/logo.png

を発見。
同様に設定したら無事表示されました😆

f:id:uu_ka:20170930020244j:plain

参考
github.com

ブービーバードのこけし

f:id:uu_ka:20170709112239j:plain

CHUMSx土湯系こけしのコラボ品の、ブービーバードのこけしを買いました。
しかも大小2つです。こういった伝統工芸品は中々買う機会が無いので大事にしたいですね。

ちなみにペンギンとよく間違われますが、こいつは鳥です笑
ペンギンじゃないよ! | BLOG | CHUMS (チャムス)

このこけしを買うまで知らなかったのですが、伝統こけしは東北地方の温泉地が産地で、なんと11系統もあります。
その中でも、土湯系、遠刈田系、鳴子系は3大発祥地とよばれているようです。

各系統ごとに、様々な特徴があって、用途や発祥となる歴史、素材など様々な視点で見ると色々なことが想像できます。
温泉地が産地ということなので、こけし温泉地を巡る旅をしても面白そうですね。

こけし系統覚え唄というのがありました笑
覚えやすい?かはわかりませんが、乗りやすい曲調で聞いて楽しくなります。


■ 参考
kokemin.com