Set up webpack and webpack-dev-server.
							parent
							
								
									202c35b517
								
							
						
					
					
						commit
						c45be9a476
					
				|  | @ -0,0 +1,25 @@ | |||
| { | ||||
|   "presets": [ | ||||
|     ["babel-preset-env", { | ||||
|       "loose": false, | ||||
|       "modules": false | ||||
|     }], | ||||
|     "babel-preset-react" | ||||
|   ], | ||||
|   "plugins": [ | ||||
|     "react-hot-loader/babel", | ||||
|     "babel-plugin-transform-react-constant-elements", [ | ||||
|       "babel-plugin-transform-react-remove-prop-types", {} | ||||
|     ], | ||||
|     "babel-plugin-transform-decorators-legacy", | ||||
|     "babel-plugin-transform-class-properties", [ | ||||
|       "babel-plugin-transform-runtime", { | ||||
|         "helpers": false, | ||||
|         "polyfill": false, | ||||
|         "regenerator": true, | ||||
|         "moduleName": "nwb" | ||||
|       } | ||||
|     ], | ||||
|     "babel-plugin-syntax-dynamic-import" | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										38
									
								
								index.js
								
								
								
								
							
							
						
						
									
										38
									
								
								index.js
								
								
								
								
							|  | @ -33,22 +33,28 @@ const app = express(); | |||
| 
 | ||||
| app.set('port', (process.env.PORT || 3000)); | ||||
| 
 | ||||
| fs.stat(frontendDir, (err) => { | ||||
|   if (!err) { | ||||
|     console.log(`Serving static build from ${frontendDir}`); | ||||
|     console.log('Run `npm run clean` to return to development mode'); | ||||
|     app.use('/', express.static(frontendDir)); | ||||
|   } else { | ||||
|     console.log('Serving development build with nwb middleware'); | ||||
|     console.log('Run `npm run build` to create a production build'); | ||||
| if (process.NODE_ENV !== 'production') { | ||||
|   console.log('Serving development build with webpack dev middleware'); | ||||
| 
 | ||||
|     // eslint-disable-next-line import/no-extraneous-dependencies
 | ||||
|     app.use(require('nwb/express')(express, { | ||||
|       entry: 'src/index.jsx', | ||||
|       reload: true, | ||||
|     })); | ||||
|   } | ||||
| }); | ||||
|   // eslint-disable-next-line import/no-extraneous-dependencies
 | ||||
|   require('babel-register'); | ||||
|   const webpackConfig = require('./webpack.config.babel.js').default({ | ||||
|     server: true, | ||||
|   }); | ||||
|   const compiler = require('webpack')(webpackConfig); | ||||
|   app.use(require('webpack-dev-middleware')(compiler, webpackConfig.devServer)); | ||||
|   app.use(require('webpack-hot-middleware')(compiler, { | ||||
|     log: false, | ||||
|   })); | ||||
| 
 | ||||
|   app.get('/api/dev/webpackConfig', (req, res) => { | ||||
|     res.setHeader('content-type', 'text/plain'); | ||||
|     res.send(require('util').inspect(webpackConfig, { depth: null, colors: false })); | ||||
|   }); | ||||
| } else { | ||||
|   console.log(`Serving static build from ${frontendDir}`); | ||||
|   app.use('/', express.static(frontendDir)); | ||||
| } | ||||
| 
 | ||||
| app.use(bodyParser.json()); | ||||
| app.use(bodyParser.urlencoded({ extended: true })); | ||||
|  | @ -60,7 +66,7 @@ app.use((req, res, next) => { | |||
|   next(); | ||||
| }); | ||||
| 
 | ||||
| function calculateRankings(id: Number) { | ||||
| function calculateRankings(id) { | ||||
|   db.query('SELECT * FROM `vizon_web_rankings` WHERE `vizon_drawings_id`=?', [id], (err, results, fields) => { | ||||
|     if (err) { | ||||
|       console.error('Failed to query rankings from database:', err); | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										36
									
								
								package.json
								
								
								
								
							
							
						
						
									
										36
									
								
								package.json
								
								
								
								
							|  | @ -5,7 +5,9 @@ | |||
|   "private": true, | ||||
|   "main": "./index.js", | ||||
|   "scripts": { | ||||
|     "build": "nwb build-react-app ./src --preact", | ||||
|     "build": "webpack", | ||||
|     "build:production": "npm run -s build -- --env production", | ||||
|     "build:development": "npm run -s build -- --env development", | ||||
|     "clean": "nwb clean-app", | ||||
|     "docker-compose": "docker-compose -f docker-compose.local.yml", | ||||
|     "docker:down:clean": "npm run -s docker:down -- --rmi all -v", | ||||
|  | @ -17,8 +19,9 @@ | |||
|     "docker:up": "npm run -s docker-compose -- up --build", | ||||
|     "docker": "npm run -s docker:up", | ||||
|     "lint": "eslint .", | ||||
|     "prepare": "npm run -s build", | ||||
|     "prepublish": "npm run -s build:production", | ||||
|     "start": "node .", | ||||
|     "start:development": "webpack-dev-server --env development --env server", | ||||
|     "test:coverage": "nwb test-react --coverage", | ||||
|     "test:watch": "nwb test-react --server", | ||||
|     "test": "nwb test-react" | ||||
|  | @ -43,30 +46,49 @@ | |||
|   "author": "Carl Kittelberger <icedream@icedream.pw>", | ||||
|   "license": "UNLICENSED", | ||||
|   "devDependencies": { | ||||
|     "autoprefixer": "^7.1.2", | ||||
|     "babel-eslint": "^7.2.3", | ||||
|     "babel-loader": "^7.1.2", | ||||
|     "babel-plugin-transform-class-properties": "^6.24.1", | ||||
|     "babel-preset-env": "^1.6.0", | ||||
|     "case-sensitive-paths-webpack-plugin": "^2.1.1", | ||||
|     "chalk": "^2.1.0", | ||||
|     "css-loader": "^0.28.5", | ||||
|     "eslint": "^4.5.0", | ||||
|     "eslint-config-airbnb": "^15.1.0", | ||||
|     "eslint-plugin-babel": "^4.1.2", | ||||
|     "eslint-plugin-import": "^2.7.0", | ||||
|     "eslint-plugin-json": "^1.2.0", | ||||
|     "eslint-plugin-jsx-a11y": "^5.1.1", | ||||
|     "eslint-plugin-react": "^7.2.1", | ||||
|     "eslint": "^4.5.0", | ||||
|     "extract-text-webpack-plugin": "^3.0.0", | ||||
|     "file-loader": "^0.11.2", | ||||
|     "html-webpack-plugin": "^2.30.1", | ||||
|     "node-sass": "^4.5.3", | ||||
|     "normalize-scss": "^7.0.0", | ||||
|     "nwb-sass": "^0.8.1", | ||||
|     "nwb": "^0.18.10", | ||||
|     "preact-compat": "^3.17.0", | ||||
|     "nwb-sass": "^0.8.1", | ||||
|     "postcss-loader": "^2.0.6", | ||||
|     "preact": "^8.2.1", | ||||
|     "preact-compat": "^3.17.0", | ||||
|     "progress-bar-webpack-plugin": "^1.10.0", | ||||
|     "prop-types": "^15.5.10", | ||||
|     "react": "^15.6.1", | ||||
|     "react-dom": "^15.6.1", | ||||
|     "react-fontawesome": "^1.6.1", | ||||
|     "react-helmet": "^5.1.3", | ||||
|     "react-hot-loader": "^3.0.0-beta.7", | ||||
|     "react-router": "^4.1.2", | ||||
|     "react": "^15.6.1", | ||||
|     "resolve-url-loader": "^2.1.0", | ||||
|     "webfontloader": "^1.6.28" | ||||
|     "sass-loader": "^6.0.6", | ||||
|     "slash": "^1.0.0", | ||||
|     "style-loader": "^0.18.2", | ||||
|     "url-loader": "^0.5.9", | ||||
|     "webfontloader": "^1.6.28", | ||||
|     "webpack": "^3.5.5", | ||||
|     "webpack-dev-middleware": "^1.12.0", | ||||
|     "webpack-hot-middleware": "^2.18.2", | ||||
|     "webpack-merge": "^4.1.0" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "body-parser": "^1.17.2", | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| import React from 'react'; | ||||
| import { render } from 'react-dom'; | ||||
| import { AppContainer } from 'react-hot-loader'; | ||||
| 
 | ||||
| import './index.sass'; | ||||
| import App from './App'; | ||||
|  | @ -8,4 +9,15 @@ import App from './App'; | |||
| const rootContainer = document.createElement('div'); | ||||
| document.body.appendChild(rootContainer); | ||||
| 
 | ||||
| render(<App />, rootContainer); | ||||
| const runRender = (Component) => { | ||||
|   console.log('Rendering app...'); | ||||
|   render(<AppContainer> | ||||
|     <Component /> | ||||
|   </AppContainer>, rootContainer); | ||||
| }; | ||||
| 
 | ||||
| runRender(App); | ||||
| 
 | ||||
| if (module.hot) { | ||||
|   module.hot.accept('./App', () => { runRender(App); }); | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,381 @@ | |||
| import { | ||||
|   DefinePlugin, | ||||
|   NamedModulesPlugin, | ||||
|   HashedModuleIdsPlugin, | ||||
|   LoaderOptionsPlugin, | ||||
|   ContextReplacementPlugin, | ||||
|   HotModuleReplacementPlugin, | ||||
|   NoEmitOnErrorsPlugin, | ||||
| 
 | ||||
|   optimize, | ||||
| } from 'webpack'; | ||||
| 
 | ||||
| import path from 'path'; | ||||
| import { isatty } from 'tty'; | ||||
| import chalk from 'chalk'; | ||||
| import slash from 'slash'; | ||||
| import autoprefixer from 'autoprefixer'; | ||||
| import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin'; | ||||
| import ExtractTextPlugin from 'extract-text-webpack-plugin'; | ||||
| import HtmlPlugin from 'html-webpack-plugin'; | ||||
| import ProgressBarPlugin from 'progress-bar-webpack-plugin'; | ||||
| 
 | ||||
| const { | ||||
|   CommonsChunkPlugin, | ||||
|   UglifyJsPlugin, | ||||
|   ModuleConcatenationPlugin, | ||||
| } = optimize; | ||||
| 
 | ||||
| const locales = ['en']; | ||||
| 
 | ||||
| /** | ||||
|  * Plugin for HtmlPlugin which inlines content for an extracted Webpack manifest | ||||
|  * into the HTML in a <script> tag before other emitted asssets are injected by | ||||
|  * HtmlPlugin itself. | ||||
|  */ | ||||
| function injectManifestPlugin() { | ||||
|   this.plugin('compilation', (compilation) => { | ||||
|     compilation.plugin('html-webpack-plugin-before-html-processing', (data, cb) => { | ||||
|       Object.keys(compilation.assets).forEach((key) => { | ||||
|         if (!key.startsWith('manifest.')) { return; } | ||||
|         const { children } = compilation.assets[key]; | ||||
|         if (children && children[0]) { | ||||
|           // eslint-disable-next-line no-param-reassign
 | ||||
|           data.html = data.html.replace(/^(\s*)<\/body>/m, `$1<script>${children[0]._value}</script>\n$1</body>`); | ||||
|           // Remove the manifest from HtmlPlugin's assets to prevent a <script>
 | ||||
|           // tag being created for it.
 | ||||
|           const manifestIndex = data.assets.js.indexOf(data.assets.publicPath + key); | ||||
|           data.assets.js.splice(manifestIndex, 1); | ||||
|           // eslint-disable-next-line no-param-reassign
 | ||||
|           delete data.assets.chunks.manifest; | ||||
|         } | ||||
|       }); | ||||
|       cb(null, data); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| export default (options) => { | ||||
|   const environment = { | ||||
|     development: true, | ||||
|     production: false, | ||||
|     server: false, | ||||
|   }; | ||||
| 
 | ||||
|   function processEnvironmentString(env) { | ||||
|     switch (env.toLowerCase()) { | ||||
|       case 'development': | ||||
|         environment.development = true; | ||||
|         environment.production = false; | ||||
|         break; | ||||
|       case 'production': | ||||
|         environment.development = false; | ||||
|         environment.production = true; | ||||
|         break; | ||||
|       case 'server': | ||||
|         environment.server = true; | ||||
|         break; | ||||
|       default: | ||||
|         console.warn('Unknown environment:', env); | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   if (options) { | ||||
|     switch (true) { | ||||
|       case typeof (options) === 'string': // string
 | ||||
|         processEnvironmentString(options); | ||||
|         break; | ||||
| 
 | ||||
|       case Array.isArray(options): // array
 | ||||
|         options.forEach(processEnvironmentString); | ||||
|         break; | ||||
| 
 | ||||
|       default: // object
 | ||||
|         Object.keys(options).forEach((k) => { | ||||
|           environment[k] = options[k] || environment[k]; | ||||
|         }); | ||||
|         break; | ||||
|     } | ||||
|   } else if (process.env.NODE_ENV) { | ||||
|     processEnvironmentString(process.env.NODE_ENV); | ||||
|   } | ||||
| 
 | ||||
|   const { | ||||
|     development, | ||||
|     production, | ||||
|     server, | ||||
|   } = environment; | ||||
| 
 | ||||
|   const baseOutputFilename = development | ||||
|     ? 'assets/dev/[name].dev.[ext]' | ||||
|     // Always use a hash (in production) to prevent files with the same name causing issues
 | ||||
|     : 'assets/prod/[chunkhash:2]/[name].[chunkhash:8].[ext]'; | ||||
| 
 | ||||
|   const webpackChunkFilename = baseOutputFilename | ||||
|     .replace(/\[ext(.*?)\]/g, 'js'); | ||||
|   const webpackOutputFilename = webpackChunkFilename; | ||||
| 
 | ||||
|   const assetOutputFilename = baseOutputFilename | ||||
|     .replace(/\[chunkhash(.*?)\]/g, '[hash$1]'); | ||||
| 
 | ||||
|   const cssOutputFileName = baseOutputFilename | ||||
|     .replace(/\[ext(.*?)\]/g, 'css') | ||||
|     .replace(/\[chunkhash(.*?)\]/g, '[contenthash$1]'); | ||||
|   const cssOutputRebasePath = `${slash(path.relative(path.dirname(cssOutputFileName), ''))}/`; | ||||
| 
 | ||||
|   // Default options for url-loader
 | ||||
|   const urlLoaderOptions = { | ||||
|     limit: 1, // Don't inline anything (but empty files) by default
 | ||||
|     name: assetOutputFilename, | ||||
|     publicPath: cssOutputRebasePath, | ||||
|   }; | ||||
| 
 | ||||
|   function styleLoaders(...preprocessingLoaders) { | ||||
|     let cssLoaders = [ | ||||
|       { | ||||
|         loader: 'style-loader', | ||||
|       }, | ||||
|       { | ||||
|         loader: 'css-loader', | ||||
|         options: { | ||||
|           importLoaders: 1, | ||||
|           sourceMap: true, | ||||
|           modules: true, | ||||
|         }, | ||||
|       }, | ||||
|       { | ||||
|         loader: 'postcss-loader', | ||||
|         options: { | ||||
|           ident: 'postcss', | ||||
|           plugins: [ | ||||
|             autoprefixer({ | ||||
|               browsers: '> 1%, last 4 versions, Firefox ESR, ios >= 8', | ||||
|               grid: false, | ||||
|             }), | ||||
|           ], | ||||
|           sourceMap: true, | ||||
|         }, | ||||
|       }, | ||||
|     ].filter(loader => loader !== false); | ||||
| 
 | ||||
|     if (preprocessingLoaders && preprocessingLoaders.length > 0) { | ||||
|       cssLoaders.push( | ||||
|         { | ||||
|           loader: 'resolve-url-loader', | ||||
|           options: { | ||||
|             fail: true, | ||||
|             silent: false, | ||||
|           }, | ||||
|         }, | ||||
|         ...preprocessingLoaders.map(loader => Object.assign({}, loader, { | ||||
|           options: Object.assign({}, loader.options || {}, { | ||||
|             sourceMap: true, | ||||
|           }), | ||||
|         })), | ||||
|       ); | ||||
|     } | ||||
| 
 | ||||
|     if (!server) { | ||||
|       const fallback = cssLoaders.shift(); | ||||
|       cssLoaders = ExtractTextPlugin.extract({ | ||||
|         fallback, | ||||
|         use: cssLoaders, | ||||
|       }); | ||||
|     } | ||||
| 
 | ||||
|     return cssLoaders; | ||||
|   } | ||||
| 
 | ||||
|   return { | ||||
|     devServer: { | ||||
|       // inline: true,
 | ||||
|       headers: { | ||||
|         'Access-Control-Allow-Origin': '*', | ||||
|       }, | ||||
|       historyApiFallback: true, | ||||
|       hot: true, | ||||
|       noInfo: true, | ||||
|       overlay: true, | ||||
|       publicPath: '', | ||||
|       quiet: true, | ||||
|       watchOptions: { | ||||
|         ignored: /node_modules/, | ||||
|       }, | ||||
|     }, | ||||
|     module: { | ||||
|       rules: [ | ||||
|         { | ||||
|           test: /\.jsx?/, | ||||
|           loader: 'babel-loader', | ||||
|           exclude: /node_modules/, | ||||
|           options: { | ||||
|           // Look for babel configuration in project directory
 | ||||
|             babelrc: true, | ||||
|             // Cache transformations to the filesystem (in default temp dir)
 | ||||
|             cacheDirectory: true, | ||||
|           }, | ||||
|         }, | ||||
|         ...[ | ||||
|           /\.(gif|png|webp)$/i, // graphics
 | ||||
|           /\.svg$/i, // svg
 | ||||
|           /\.jpe?g$/i, // jpeg
 | ||||
|           /\.(mp4|ogg|webm)$/i, // video
 | ||||
|           /\.(eot|otf|ttf|woff|woff2)$/i, // fonts
 | ||||
|           /\.(wav|mp3|m4a|aac|oga)$/i, // audio
 | ||||
|         ].map(test => ({ | ||||
|           test, | ||||
|           loader: 'url-loader', | ||||
|           options: urlLoaderOptions, | ||||
|         })), | ||||
|         { | ||||
|           test: /\.css$/, | ||||
|           use: styleLoaders(), | ||||
|         }, | ||||
|         { | ||||
|           test: /\.s[ac]ss$/, | ||||
|           use: styleLoaders( | ||||
|             { | ||||
|               loader: 'sass-loader', | ||||
|             }, | ||||
|           ), | ||||
|         }, | ||||
|       ], | ||||
|       strictExportPresence: true, | ||||
|     }, | ||||
|     output: { | ||||
|       filename: webpackOutputFilename, | ||||
|       chunkFilename: webpackChunkFilename, | ||||
|       path: path.join(__dirname, 'dist'), | ||||
|       publicPath: '', | ||||
|     }, | ||||
|     plugins: [ | ||||
|     // Show progress as a bar during build
 | ||||
|       isatty(1) && new ProgressBarPlugin({ | ||||
|         complete: chalk.white('\u2588'), | ||||
|         incomplete: chalk.grey('\u2591'), | ||||
|         format: `:bar ${chalk.cyan.bold(':percent')} Webpack build: ${chalk.grey(':msg')}`, | ||||
|       }), | ||||
| 
 | ||||
|       // Enforce case-sensitive import paths
 | ||||
|       new CaseSensitivePathsPlugin(), | ||||
|       // Replace specified expressions with values
 | ||||
|       new DefinePlugin({ | ||||
|         'process.env.__DEV__': JSON.stringify(development), | ||||
|         'process.env.__PROD__': JSON.stringify(production), | ||||
|         'process.env.__SERVER__': JSON.stringify(server), | ||||
|         'process.env.NODE_ENV': JSON.stringify(production ? 'production' : 'development'), | ||||
|       }), | ||||
| 
 | ||||
|       // Dev server build
 | ||||
|       ...[ | ||||
|       // Hot module reloading
 | ||||
|         new HotModuleReplacementPlugin(), | ||||
|         new NoEmitOnErrorsPlugin(), | ||||
| 
 | ||||
|         // Use paths as names when serving
 | ||||
|         new NamedModulesPlugin(), | ||||
|       ].filter(() => server), | ||||
| 
 | ||||
|       // If we're not serving, we're creating a static build
 | ||||
|       ...[// Extract imported stylesheets out into .css files
 | ||||
|         new ExtractTextPlugin({ | ||||
|           allChunks: true, | ||||
|           filename: cssOutputFileName, | ||||
|         }), | ||||
|       ].filter(() => !server), | ||||
| 
 | ||||
|       // Move modules imported from node_modules/ into a vendor chunk when enabled
 | ||||
|       new CommonsChunkPlugin({ | ||||
|         name: 'vendor', | ||||
|         minChunks(module) { | ||||
|           return (module.resource && module.resource.includes('node_modules')); | ||||
|         }, | ||||
|       }), | ||||
| 
 | ||||
|       // If we're generating an HTML file, we must be building a web app, so
 | ||||
|       // configure deterministic hashing for long-term caching.
 | ||||
| 
 | ||||
|       // Generate stable module ids instead of having Webpack assign integers.
 | ||||
|       // NamedModulesPlugin allows for easier debugging and
 | ||||
|       // HashedModuleIdsPlugin does this without adding too much to bundle
 | ||||
|       // size.
 | ||||
|       development | ||||
|         ? new NamedModulesPlugin() | ||||
|         : new HashedModuleIdsPlugin(), | ||||
| 
 | ||||
|       // The Webpack manifest is normally folded into the last chunk, changing
 | ||||
|       // its hash - prevent this by extracting the manifest into its own
 | ||||
|       // chunk - also essential for deterministic hashing.
 | ||||
|       new CommonsChunkPlugin({ name: 'manifest' }), | ||||
| 
 | ||||
|       // Inject the Webpack manifest into the generated HTML as a <script>
 | ||||
|       injectManifestPlugin, | ||||
| 
 | ||||
|       // Production builds
 | ||||
|       ...[ | ||||
|       // JavaScript minification
 | ||||
|         new LoaderOptionsPlugin({ debug: false, minimize: true }), | ||||
|         new UglifyJsPlugin({ | ||||
|           compress: { | ||||
|             warnings: false, | ||||
|           }, | ||||
|           output: { | ||||
|             comments: false, | ||||
|           }, | ||||
|           sourceMap: true, | ||||
|         }), | ||||
| 
 | ||||
|         // Hoisting
 | ||||
|         new ModuleConcatenationPlugin(), | ||||
|       ].filter(() => production), | ||||
| 
 | ||||
|       new HtmlPlugin({ | ||||
|         template: 'src/index.html', | ||||
|         filename: 'index.html', | ||||
|         hash: false, | ||||
|         inject: true, | ||||
|         compile: true, | ||||
|         favicon: false, | ||||
|         minify: false, | ||||
|         cache: true, | ||||
|         showErrors: true, | ||||
|         chunks: 'all', | ||||
|         excludeChunks: [], | ||||
|         title: 'Webpack App', | ||||
|         xhtml: false, | ||||
|         chunksSortMode: 'dependency', | ||||
|       }), | ||||
| 
 | ||||
|       // Only include selected locales for moment.js
 | ||||
|       new ContextReplacementPlugin(/moment[/\\]locale$/, new RegExp(`^\\.\\/(${locales.join('|')})$`)), | ||||
|     ].filter(plugin => plugin !== false), | ||||
|     resolve: { | ||||
|       extensions: [ | ||||
|         '.js', '.json', '.jsx', | ||||
|       ], | ||||
|       alias: { | ||||
|         // Use preact instead of react
 | ||||
|         /* react: 'preact-compat\\dist\\preact-compat', | ||||
|         'react-dom': 'preact-compat\\dist\\preact-compat', | ||||
|         'create-react-class': 'preact-compat/lib/create-react-class', */ | ||||
| 
 | ||||
|         'moment-timezone': 'moment-timezone/builds/moment-timezone-with-data-2012-2022.js', | ||||
|       }, | ||||
|     }, | ||||
|     resolveLoader: { | ||||
|       modules: ['node_modules', 'nwb'], | ||||
|     }, | ||||
|     devtool: server ? 'cheap-module-source-map' : 'source-map', | ||||
|     entry: { | ||||
|       app: [ | ||||
|         ...[ | ||||
|           'eventsource-polyfill', | ||||
|           'react-hot-loader/patch', | ||||
|           'webpack-hot-middleware/client', | ||||
|         ].filter(() => server), | ||||
|         './src', | ||||
|       ], | ||||
|     }, | ||||
|   }; | ||||
| }; | ||||
		Loading…
	
		Reference in New Issue