webpack v1 から webpack v3 へ移行

npmモジュールの更新


まずはパッケージの更新から行きましょう。ついでに一緒に使用している他のモジュールも上げておくと吉です。
webpackのバージョンに依存していたりするのでね。
一括更新をするための便利なツールがあります。コマンドラインで使うのでグローバルにインストールしておきましょう。

npm install -g npm-check-updates

package.jsonがあるディレクトリまで移動して、ncuと打てばアップデートをチェック、一括ncu -aで、アップデートできます。
部分的に上げたければ、ncu [モジュール]でアップデートしてください。

私はこんな感じでした。

 babel-loader   ^6.2.10  →  ^7.1.1
riotjs-loader ^3.0.0 → ^4.0.0
webpack ^1.14.0 → ^3.4.1
riot ^3.0.7 → ^3.6.1
riot-route ^3.0.2 → ^3.1.2
babel ^6.5.2 → ^6.23.0
babel-core ^6.21.0 → ^6.25.0
concurrently ^3.1.0 → ^3.5.0
lite-server ^2.2.2 → ^2.3.0

その後、npm-check-updatesはpackage.jsonの変更しか行ってくれないので、npm updateを行ってください。

ちなみに、babel-loaderは、以下の通りwebpackに依存しているので注意です。最新に上げておけば問題ありません。

webpack 1.x | babel-loader <= 6.x
webpack 2.x | babel-loader >= 7.x (recommended) (^6.2.10 will also work, but with deprecation warnings)
webpack 3.x | babel-loader >= 7.1

https://github.com/babel/babel-loader
 
 

webpack.config.jsonの更新


モジュールのアップデートが終わったら、とりあえずそのまま起動してみてください。
エラーになるのが正解ですが、普通にwebpack出来てしまった方は、ログをよく見てください。
[0] [BS] File changed: app\scripts\bundle.js
[0] 17.08.07 02:16:13 304 GET /index.html
[1] Hash: dfe23fb8effda57760a2
[1] Version: webpack 1.14.0
[1] Time: 4458ms
[1] Asset Size Chunks Chunk Names
[1] bundle.js 293 kB 0 [emitted] main
[1] bundle.js.map 1.52 MB 0 [emitted] main
[1] + 35 hidden modules

上の例みたいに、Version: webpack 1.14.0 なんて古いものになっていませんか?
もしかしたらローカルじゃなくてグローバルにwebpackを入れていたら、そっちをアップデートするなり消すなりしてみてください。

さて、webpackがエラーになっていると思います。
理由はwebpack.config.jsの記載方法が変更になった為です。(v1->v2)
私はこんな感じに変更になりました。
 
・変更前(webpack.config.js)


const webpack = require('webpack');

module.exports = {
entry: './src/scripts/index.js',
output: {
path: __dirname + '/app/scripts',
filename: 'bundle.js',
publicPath: '/app/',
},
module: {
preLoaders: [
{
test: /\.tag$/,
exclude: /node_modules/,
loader: 'riotjs-loader',
query: {
type: 'babel'
}
}
],
loaders: [
{
test: /\.js$|\.tag$/,
exclude: /node_modules/,
loader: 'babel-loader'
}
]
},
devtool: 'source-map',
resolve: {
extensions: ['', '.js', '.tag']
},
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new webpack.ProvidePlugin({
riot: 'riot'
})
]
};


 
・変更後(webpack.config.babel.js)
import webpack from 'webpack';

export default {
entry: './src/scripts/index.js',
output: {
path: __dirname + '/app/scripts',
filename: 'bundle.js',
publicPath: '/app/',
},
module: {
rules: [
{
enforce: "pre",
test: /\.tag$/,
exclude: /node_modules/,
use: [
{
loader: 'riotjs-loader',
options: {
type: 'none'
}
}
],
},
{
test: /\.(tag|js)$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {}
}
]
}
]
},
devtool: 'source-map',
resolve: {
extensions: ['*', '.js', '.tag']
},
plugins: [
new webpack.optimize.UglifyJsPlugin({sourceMap: true}),
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.AggressiveMergingPlugin(),
new webpack.ProvidePlugin({
riot: 'riot'
})
]
};


 
ガラリと変わっていますね。ついでに、ES6な書き方に変更しています。
そのため、ファイル名もwebpack.config.jsからwebpack.config.babel.jsに変更しています。
さて、細かいところは公式サイト https://webpack.js.org/guides/migrating/ に任せるとして、
注意すべき点としては、extensionsの'''*'になったことと、
ソースマップを出すなら、UglifyJsPluginにも指定が必要になったことです。両方指定しないとソースマップは出ませんでした。

 
 

うまくいかない場合


ちゃんと設定しているにもかかわらず、エラーになる人は、一度node_modulesフォルダを消してから
npm i
で再度最新版のみをインストールしなおしてみましょう。

Riot.jsで真偽値属性(disabledなど)が「__disabled」になる問題

Riot.jsについて


最近のフロントエンド開発ではReactを使うことが多いですが、私は少数派ですので、「Riot.js」をよく使っています。
検索から来た人は、Riot.jsのことはよく知っているはずなので良いですが、そうでない人はぜひ使ってみてください。
 
 

__disabled問題


Riot.jsでは、disabled=”{ !data.reference[0] }”のように判定式でdisabledが出来る。と公式ガイドに書いてある。

真偽値属性 (checked, selected など) はテンプレート変数がfalse的であれば無視されます。
<input checked={ null }><input> になります。

http://riotjs.com/ja/guide/#真偽値属性

しかし、いざ使おうとすると、何故か「__disabled」になってしまい、全然機能してくれなかった。
どこで「__disabled」になっているかというと、コンパイル時に変換されているのだが、それでも普通はDOM評価時には「disabled」になるはずが、DOM評価されても、「__disabled」となっていた。
 
 

解決策


仕方がないのでdomReady後に無理やり「__disabled」を自前で置き換えて回避してましたが、別件でnpmモジュールを更新していたら、この問題が解決。
riotjs-loaderを3.0.0から4.0.0にしたら、ちゃんと「disabled」になりました。
単純な解決方法だけど、調べた限り全然情報が無かったので、同じようにハマっている人の救いになればと思います。

 
 

余談


これは私だけかもしれませんが、riotjs-loaderを4.0.0にしたら、webpack.config.jsの書き換えが必要でした。
type: 'babel'type: 'none' に変更。

{
enforce: "pre",
test: /\.tag$/,
exclude: /node_modules/,
use: [
{
loader: 'riotjs-loader',
options: {
type: 'none'
}
}
],
}