DeprecationWarning: Tapable.plugin is deprecated. Use new API on .hooks instead
↑
こんなエラーが出て困ってる人のヒントになれば幸い。
結果
↓こうしたら動きました。
const fs = require('fs');
const RawSource = require('webpack-sources').RawSource;
const SourceMapSource = require('webpack-sources').SourceMapSource;
const iconv = require('iconv-lite');
let ModuleFilenameHelpers = require('webpack').ModuleFilenameHelpers;
if (!ModuleFilenameHelpers) {
ModuleFilenameHelpers = require('webpack/lib/ModuleFilenameHelpers')
}
class EncodingPlugin {
constructor(options) {
if (typeof options === 'string') {
this.options = {
encoding: options
}
} else {
this.options = options || {}
}
}
apply(compiler) {
let options = this.options;
options.test = options.test || /(\.js|\.css)($|\?)/i;
let matchFileName = ModuleFilenameHelpers.matchObject.bind(undefined, options);
compiler.hooks.emit.tapPromise('EncodingPlugin', compilation => {
return new Promise((resolve, reject) => {
let files = Object.keys(compilation.assets).filter(matchFileName);
files.forEach(function (file) {
let asset = compilation.assets[file];
try {
let source, map;
if (asset.sourceAndMap) {
let sourceAndMap = asset.sourceAndMap();
source = sourceAndMap.source;
map = sourceAndMap.map
} else {
source = asset.source();
map = typeof asset.map === 'function'
? asset.map()
: null
}
let encodedSource = iconv.encode(source, options.encoding, options.config);
if (asset.existsAt && fs.existsSync(asset.existsAt)) {
fs.writeFileSync(asset.existsAt, encodedSource)
}
compilation.assets[file] = map
? new SourceMapSource(encodedSource, file, map)
: new RawSource(encodedSource)
} catch (e) {
compilation.errors.push(new Error(file + ' from EncodingPlugin: ' + e.message))
}
});
console.log('Assets converted to ' + options.encoding);
resolve();
});
});
}
}
module.exports = EncodingPlugin;
経緯
今開発しているサイトの文字コードが EUC-JP
限定だったので、
JavaScriptの文字コードを EUC-JP
にしたく、
webpack-encode-plugin
というプラグインを実装してみたところ、
↓こんなエラーが出て怒られた。
DeprecationWarning: Tapable.plugin is deprecated. Use new API on .hooks instead
webpack-encode-plugin
https://www.npmjs.com/package/webpack-encode-plugin
ググってみたけどこのプラグインのissuが見つからず。。
DeprecationWarning: Tapable.plugin is deprecated. Use new API on .hooks instead
でググってみたけど解決策が見つからなかった。
よし、とりあえず直訳だ!
英語も得意じゃないので、とりあえず Google翻訳 にかけてみた。
結果が↓こちら
DeprecationWarning:Tapable.pluginは非推奨です。代わりに.hooksに新しいAPIを使用してください
ふむ。
まあ要は Plugin 内の記述方法を新しいAPIに変えろと言っているっぽい。
Tapable.plugin
とはなんぞや?
「非推奨です。」って言われている Tapable.plugin
がなんのか分からなかったので、
「site:webpack.js.org Tapable.plugin」でググってみたら、
Plugin API のページがヒットした。
Plugin API
https://webpack.js.org/api/plugins/
そこに Tapable
class という記述を発見。
Tapable | Plugin API
https://webpack.js.org/api/plugins/#tapable
ドキュメントへのリンクも発見。
webpack/tapable | GitHub
https://github.com/webpack/tapable
「この辺を読み解いて、ソースコードいじればなんとかなるかも?」 と思った。
ひとまずプラグインの中身を見てみた
GitHub に上がっていたソースコードが↓こちら
https://github.com/ricosmall/webpack-encode-plugin/blob/master/index.js
う〜ん、どの辺が Tapable
クラスか分からず。。。
Tapable.plugin webpack
でもググってみた
↓こんなページを発見
Extending with Plugins
https://survivejs.com/webpack/extending/plugins/
webpackプラグインの書き方ページっぽいけど、
今回エラーの出た webpack-encode-plugin
の記述方法がこれによく似てた。
この書き方がもう古いってことなんだろうな。。。と推測。
Plugin API のページを再度確認
Plugin Types の箇所に
compiler.hooks...
という記述を発見。
以前は、 compiler.plugin
としていた書き方が、
compiler.hooks
というメソッドに変わったんだなと推測。
Plugin Types
https://webpack.js.org/api/plugins/#plugin-types
さて、
compiler.hooks.
のあとはどうする?
Compiler Hooks というページがあったので、
見てみたがいっぱいあった。。。
でもなんとなく、 emit
を選択。
文字コード変換は output ディレクトリへの出力直前がよい気がしたので。
compiler.hooks.emit.
のあとはどうする?
Hook types に色々あった。
https://github.com/webpack/tapable#hook-types
非同期の Promise
ベースで resolve()
返せれば無難かなと思い、
.tapPromise()
を選択
組み直した結果うまく機能して文字コード変換されました。
だいぶ大雑把な修正のしかたをしたけど、
まあ動いたのでよし。
時間に余裕ができたらもっとちゃんと調べて理解してみよう。
なんとかなったけども
記述に問題があったりする可能性大だと思っているので、
大元の webpack-encode-plugin
へはこの内容は送ってません。
おかしな点などありましたらご指摘いただけると嬉しいです(>人<)