wordpressのローカル作業をwebpack(proxyとかHMR?)でやる
ここ何年かやってるwordpressの更新案件で、手つけ始めた時から使ってたgulpでずっと作業してたんだけども、
無駄にgulp使ってるとそろそろおじさん扱いされそうな風潮なので
ローカル作業の環境周りをnpm scriptとwebpackベースに乗り換えてみた。
・css/jsの出力とか監視はwebpack
・ローカルサーバーとその他のphpファイルとか画像の監視はbrowserSyncで
って感じになってます。
できるとこは全部webpackでまとめた方がいいかなーと思って色々頑張ったんだけども
結果で言うとwordpressの場合webpack dev serverだとproxy周りで少し不便な気がするので
browserSyncも使った方がいいような気がする、
なんか方法あるかもだけど、
ってなると別にgulpでもいいんじゃないのって気もするけど
まぁ折角頑張って何となく落ち着いたので記事にしてみます。
config.js
configです。適宜環境に合わせてください。
module.exports = {
public: "public/",
proxy: "http://×××.×××.×××.×××:8000",
assets: "public/wp/wp-content/themes/themename/assets/",
publicPath: "/wp/wp-content/themes/themename/assets/"
};
proxyにmampなりdockerなりのurl入れます
webpack.config.js
webpack.configです。
const config = require("./config");
const webpack = require("webpack");
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const FixStyleOnlyEntriesPlugin = require("webpack-fix-style-only-entries");
module.exports = {
mode: "development",
entry: {
main: [
"webpack/hot/dev-server",
"webpack-hot-middleware/client?reload=true",
"jquery",
"./src/js/main.js"
]
},
output: {
path: path.join(__dirname, config.assets),
filename: "js/[name].js",
publicPath: config.publicPath
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"]
}
}
]
},
{
test: /\.(sa|sc|c)ss$/,
use: [
"css-hot-loader",
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
url: false
}
},
"sass-loader"
]
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loader: "url-loader"
}
]
},
devtool: "inline-source-map",
plugins: [
new MiniCssExtractPlugin({
filename: "css/style.css"
}),
new FixStyleOnlyEntriesPlugin(),
new webpack.HotModuleReplacementPlugin(),
// これもwebpackdevServerだといらない?かも
new webpack.ProvidePlugin({
jQuery: "jquery",
$: "jquery",
jquery: "jquery",
"window.jQuery": "jquery"
})
]
};
entry周りとかHMR
entry: {
main: [
"webpack/hot/dev-server",
"webpack-hot-middleware/client?reload=true",
"jquery",
"./src/js/main.js"
];
// "css/style": [
// "webpack/hot/dev-server",
// "webpack-hot-middleware/client",
// "./src/css/style.scss"
// ]
// cssはエントリ分けてもいいかなと思ったけど
// webpackdevServerだとrealod効くけど
// browserSync経由するとcss-hot-loaderとかの動作が微妙かも、
// のでmain.js側からimportする
}
webpack/hot/dev-server
webpack-hot-middleware/client?reload=true
webpackdevServer使う時は上2つは勝手に読まれる?のか不要っぽい。
けどbrowserSyncとかでwebpack-dev-middleware使う場合はいる、と思う。多分
ちなみにclient?reload=trueを外すと
The following modules couldn’t be hot updated: (Full reload needed)
js変更した際にこんなエラーがでる。
で何となく気づいたけど、
ブラウザのログに
[HMR] connectedとかってでてたから
HMRってimportしてるjsファイル別に勝手にreplaceしてくれる物かと思ってたけど、
どうも違うっぽいかも、
対応してるモジュールがある場合は(react-hot-loaderとか)使えばいいけど、
素のjsとかjqueryの場合は、
if (module.hot) {
module.hot.dispose(() => {});
module.hot.accept(() => {});
}
とかってそれに対応した書き方しないと動作しない様子かも、
でもわざわざ対応するのは面倒なので
今回はclient?reload=true
で落ち着きました。
って事はただのオートリロードなのかな?
HMRよくわかってない
ちなみにhotにするとdevelopmentとかの場合
実ファイルが出力されない。
ので初見だとハマる気がする。
メモリ上のファイルを参照するようになる。
CSSは個別で出力
wordpressでjquery使ってるいわゆる普通のサイトで
個別にcss読み込む(js in cssとかで無く)ため
別出ししたいなと調べてたら
エントリーで分けてoutputしてもいいのかなと思ったけども、
browserSync中継するとauto relaodが効かなかったりしたりして
色々試して結果としてMiniCssExtractPlugin使ってます。
webpack dev serverでWPのProxy
あとwebpack dev serverで下記みたいな感じなんとか
ならんかなと思ったけども
devServer: {
open: true,
hotOnly: true,
contentBase: "public",
watchContentBase: true,
publicPath: config.assets,
proxy: {
"/": {
target: config.proxy,
changeOrigin: true,
autoRewrite: true
}
}
}
普通のWordpressみたいなMPA(って最近は言うの?)だと微妙な気がした。
一応起動した時点では問題ないけど、
なんて呼べばいいのか不明だけど、siteurlとかhome等の
ページ内のリンクとをproxyのIPとかPORTに適宜書き換えてくれる処理
(多分browserSyncのproxyの処理?)、というか何というかが
webpack dev serverには無い(のかな?多分。)
のが非常に不便に感じた。
server.js
のでserver.jsでbrowserSync使う事にしました。
const config = require("./config");
const webpack = require("webpack");
const bundler = webpack(require("./webpack.config"));
const webpackDevMiddleware = require("webpack-dev-middleware");
const webpackHotMiddleware = require("webpack-hot-middleware");
const browserSync = require("browser-sync");
browserSync.use({
plugin: function() {},
hooks: {
"client:js":
'(function (bs) {bs.socket.on("disconnect", function (client) { window.close(); });})(___browserSync___);'
}
});
browserSync({
proxy: {
target: config.proxy
},
middleware: [
webpackDevMiddleware(bundler, {
publicPath: config.publicPath
}),
webpackHotMiddleware(bundler, {
log: () => {}
})
],
files: [
`${config.public}**/*.{php,html,twig}`,
`${config.public}**/*.{jpg,png,gif,svg}`
],
open: "external"
});
publicPath
なんとなくWP側のcss/jsのパスをローカル用にwebpackのpublicPathに合わせないとなーと思ってたけど
<script src="<?php echo get_template_directory_uri(); ?>/assets/js/main.js" defer></script>
なんか普通にそのまま上記のような感じでリロード動いた。
browserSyncがうまい事やってくれてるのかも
npm script
で、あとは
package.jsonにscripts書いて
yarn serve
とかで、起動する感じで一応無事に
gulpからnpm scriptへの乗り換え完了できました。
まとめ
webpack自体がもしかしたらSPA向きのモジュールなのかな?
と言う印象もあるかもな感じですがこんな感じで落ち着きました。
時間かかった割に
別にgulpに比べて何かが便利になったとかは特に無いので
特におすすめはしませんが、参考になりましたら幸いでございます。
ディスカッション
コメント一覧
まだ、コメントがありません