XXとしてる
2019年4月11日木曜日
Webpackで開発中に複数のページを確認したいとき
Reactを触ってみて、`create-react-app`コマンドでお手軽にかつService Workerとかのテンプレートも含まれて簡単に開発できるなぁと思っていたところ、 複数ページを作ったらときはどのように確認したらいいのかわからないことに気がついた。 <div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtR9ntWQ125x-Zi_27VDmBwSGteuZV75rp0LSCRAIpn89XDmMiAlJXtc5QqtscXxD-nlgX0jUx8j9U1UzuPjDf5mvDUJt90aO9BNSf2UO58sNqYy364i1nSm4cSQahmnAnUDZkueuKsMA/s1600/wait.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtR9ntWQ125x-Zi_27VDmBwSGteuZV75rp0LSCRAIpn89XDmMiAlJXtc5QqtscXxD-nlgX0jUx8j9U1UzuPjDf5mvDUJt90aO9BNSf2UO58sNqYy364i1nSm4cSQahmnAnUDZkueuKsMA/s1600/wait.png" data-original-width="60" data-original-height="105" /></a></div> <div style="text-align: center;">ちょっとわからないです・・・</div> `create-react-app`で作ると中でWebpack的なことが行われているから、拡張できない? そもそもReactってSingle Page Application向けのライブラリなんだから、ページを複数作ることを考えていない感じなのか? React Routerもあるしなぁ・・・。 けどな〜一つのページで作っていくと後々困りそうだし、検索してみたらMultiple Page Applicationの中にSPAを組み込むことができるってあるから、 出来るならそうしたいな〜。 てな感じで結構な時間悩んでいたので、とりあえずWebpackを使って複数のページの開発を試してみようと思ったら、`webpack-dev-server`が一つのページにしか対応していないことにわかった。 <div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhSIgaNs_Gn2upPJ_2hpeKX8ipWv72bwDS9l0xc3NLABbm_V82BalMiEjLc6T5zC5VYcbYttjeLGoNSN9QVQk601b4seu2UjkVtLW94BlZODZ-eh91ufY2ezTagRAHq6XR3Nc-xvrNgiA/s1600/adapt_to_comics.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhSIgaNs_Gn2upPJ_2hpeKX8ipWv72bwDS9l0xc3NLABbm_V82BalMiEjLc6T5zC5VYcbYttjeLGoNSN9QVQk601b4seu2UjkVtLW94BlZODZ-eh91ufY2ezTagRAHq6XR3Nc-xvrNgiA/s1600/adapt_to_comics.png" data-original-width="210" data-original-height="135" /></a></div> <div style="text-align: center;">これは困ったぞ!</div> <div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNjdJsEn2_m1C6LYf6OpMuaGjVZHg0jWHYW0UdsW8HgAxHY0k0tpw85zg6d58EgIkQ_zsdtNh9RMmYs_g0yv4JncEbcbbzBhS03HWvPgtlwhyxFTVskmVTF1emi8PJy1cFME7NY35Rmb0/s1600/be_tampered.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNjdJsEn2_m1C6LYf6OpMuaGjVZHg0jWHYW0UdsW8HgAxHY0k0tpw85zg6d58EgIkQ_zsdtNh9RMmYs_g0yv4JncEbcbbzBhS03HWvPgtlwhyxFTVskmVTF1emi8PJy1cFME7NY35Rmb0/s1600/be_tampered.png" data-original-width="224" data-original-height="152" /></a></div> <div style="text-align: center;">これを使うんだ!</div> <div style="text-align: center; font-size: 24px;"><b><i>'''webpack-dev-middleware'''</i></b></div> ## 問題解決! <a href="https://webpack.js.org/guides/development/#using-webpack-dev-middleware">Webpackの公式ガイドのwebpack-dev-serverの下に書いてあったwebpack-dev-middleware</a>を使えば複数ページでも確認が出来るぞ! 使うときは自前のサーバーを建てる必要があるけど、nodejsならexpressがあるし、なによりドキュメントにサンプルコードがあるのであっさりと準備が終わる。 ```js // 開発時の確認用サーバーを起動するためのプログラム const express = require('express'); const webpack = require('webpack'); const webpackDevMiddleware = require('webpack-dev-middleware'); const app = express(); const config = require('./webpack.config.js'); const compiler = webpack(config); // Tell express to use the webpack-dev-middleware and use the webpack.config.js // configuration file as a base. app.use(webpackDevMiddleware(compiler, { publicPath: config.output.publicPath })); // Serve the files on port 3000. app.listen(3000, function () { console.log('Example app listening on port 3000!\n'); }); ``` 必要になるパッケージのインストールこんな感じ。 ```bash yarn add -D express webpack webpack-cli webpack-dev-middleware ``` あと、webpackの設定もHTMLを複数出力するように修正すればOK! `webpack-dev-middleware`も内部で`webpack-dev-server`を使っているのでその設定も必要になる。 後、HtmlWebpackPluginの`chunks`オプションに使いたいパックされたものを指定すれば、ページに必要なリソースだけを読み込むことが出来る。 ```js const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); module.exports = { mode: 'development', entry: { //必要な分だけ書く。 index: './src/index.js', about: './src/about.js' }, devtool: 'inline-source-map', devServer: { contentBase: './dist' }, plugins: [ new HtmlWebpackPlugin({ chunks: ['index'], //使用するチャンク名を指定する。 template: './src/index.html', filename: './index.html' }), new HtmlWebpackPlugin({ chunks: ['about'], template: './src/about.html', filename: './about.html' }) ], output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist'), publicPath: '/' } }; ``` ## 余談 より本番環境に近づけるために (URLから'.html'を省く) 少し使ってみて、ページ遷移をするときに'.html'を付けないといけないのってよくよく考えてみると本番環境と違うよねと気がついたので、省略する方法を考えてみた。 あくまで開発用でページ遷移ができるだけでいいので、細かな動作の違いは考えないことにする。 ```js // 開発時の確認用サーバーを起動するためのプログラム const express = require('express'); const webpack = require('webpack'); const webpackDevMiddleware = require('webpack-dev-middleware'); const path = require('path') const app = express(); const config = require('./webpack.config.js'); const compiler = webpack(config); //開発用にhtmlファイルにリダイレクトするコード app.all('*', function (req, res, next) { if (path.extname(req.url) === '' && req.url !== '/') { const redirectURL = req.url+'.html' console.log(`!!Development Mode!! Redirect to ${redirectURL} from ${req.url}`) res.status(303).redirect(redirectURL) } else { next() } }) // Tell express to use the webpack-dev-middleware and use the webpack.config.js // configuration file as a base. app.use(webpackDevMiddleware(compiler, { publicPath: config.output.publicPath })); // Serve the files on port 3000. app.listen(3000, function () { console.log('Example app listening on port 3000!\n'); }); ``` 拡張子がないURLに対して`.html`を付けたものでリダイレクトするだけのコードを追加した。 動作確認のためなので、これで十分だと思う。
(画像は以下のものを使用させていただきました。)
0 件のコメント:
コメントを投稿
次の投稿
前の投稿
ホーム
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿