start.js (3173B)
1 /** 2 * React Starter Kit (https://www.reactstarterkit.com/) 3 * 4 * Copyright © 2014-present Kriasoft, LLC. All rights reserved. 5 * 6 * This source code is licensed under the MIT license found in the 7 * LICENSE.txt file in the root directory of this source tree. 8 */ 9 10 import browserSync from 'browser-sync'; 11 import webpack from 'webpack'; 12 import webpackDevMiddleware from 'webpack-dev-middleware'; 13 import webpackHotMiddleware from 'webpack-hot-middleware'; 14 import WriteFilePlugin from 'write-file-webpack-plugin'; 15 import run from './run'; 16 import runServer from './runServer'; 17 import webpackConfig from './webpack.config'; 18 import clean from './clean'; 19 import copy from './copy'; 20 21 const isDebug = !process.argv.includes('--release'); 22 process.argv.push('--watch'); 23 24 const [clientConfig, serverConfig] = webpackConfig; 25 26 /** 27 * Launches a development web server with "live reload" functionality - 28 * synchronizing URLs, interactions and code changes across multiple devices. 29 */ 30 async function start() { 31 await run(clean); 32 await run(copy); 33 await new Promise((resolve) => { 34 // Save the server-side bundle files to the file system after compilation 35 // https://github.com/webpack/webpack-dev-server/issues/62 36 serverConfig.plugins.push(new WriteFilePlugin({ log: false })); 37 38 // Hot Module Replacement (HMR) + React Hot Reload 39 if (isDebug) { 40 clientConfig.entry.client = [...new Set([ 41 'babel-polyfill', 42 'react-hot-loader/patch', 43 'webpack-hot-middleware/client', 44 ].concat(clientConfig.entry.client))]; 45 clientConfig.output.filename = clientConfig.output.filename.replace('[chunkhash', '[hash'); 46 clientConfig.output.chunkFilename = clientConfig.output.chunkFilename.replace('[chunkhash', '[hash'); 47 const { query } = clientConfig.module.rules.find(x => x.loader === 'babel-loader'); 48 query.plugins = ['react-hot-loader/babel'].concat(query.plugins || []); 49 clientConfig.plugins.push(new webpack.HotModuleReplacementPlugin()); 50 clientConfig.plugins.push(new webpack.NoEmitOnErrorsPlugin()); 51 } 52 53 const bundler = webpack(webpackConfig); 54 const wpMiddleware = webpackDevMiddleware(bundler, { 55 // IMPORTANT: webpack middleware can't access config, 56 // so we should provide publicPath by ourselves 57 publicPath: clientConfig.output.publicPath, 58 59 // Pretty colored output 60 stats: clientConfig.stats, 61 62 // For other settings see 63 // https://webpack.github.io/docs/webpack-dev-middleware 64 }); 65 const hotMiddleware = webpackHotMiddleware(bundler.compilers[0]); 66 67 let handleBundleComplete = async () => { 68 handleBundleComplete = stats => !stats.stats[1].compilation.errors.length && runServer(); 69 70 const server = await runServer(); 71 const bs = browserSync.create(); 72 73 bs.init({ 74 ...isDebug ? {} : { notify: false, ui: false }, 75 76 proxy: { 77 target: server.host, 78 middleware: [wpMiddleware, hotMiddleware], 79 proxyOptions: { 80 xfwd: true, 81 }, 82 }, 83 }, resolve); 84 }; 85 86 bundler.plugin('done', stats => handleBundleComplete(stats)); 87 }); 88 } 89 90 export default start;