'use strict'; process.env.NODE_ENV = 'production'; const autoprefixer = require('autoprefixer'); const path = require('path'); const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); const ManifestPlugin = require('webpack-manifest-plugin'); const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin'); const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin'); const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); // const WriteFilePlugin = require('write-file-webpack-plugin'); const getClientEnvironment = require('./env'); const paths = require('./paths'); // Webpack uses `publicPath` to determine where the app is being served from. // It requires a trailing slash, or the file assets will get an incorrect path. // const publicPath = 'http://localhost:3000/'; const publicPath = paths.servedPath; // Some apps do not use client-side routing with pushState. // For these, "homepage" can be set to "." to enable relative asset paths. const shouldUseRelativeAssetPaths = publicPath === './'; // `publicUrl` is just like `publicPath`, but we will provide it to our app // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript. // Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz. const publicUrl = publicPath.slice(0, -1); // Get environment variables to inject into our app. const env = getClientEnvironment(publicUrl); // Assert this just to be safe. // Development builds of React are slow and not intended for production. if (env.stringified['process.env'].NODE_ENV !== '"production"') { throw new Error('Production builds must have NODE_ENV=production.'); } // Note: defined here because it will be used more than once. const cssFilename = 'static/css/[name].[contenthash:8].css'; // ExtractTextPlugin expects the build output to be flat. // (See https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/27) // However, our output is structured with css, js and media folders. // To have this structure working with relative paths, we have to use custom options. const extractTextPluginOptions = shouldUseRelativeAssetPaths ? // Making sure that the publicPath goes back to to build folder. { publicPath: Array(cssFilename.split('/').length).join('../') } : {}; module.exports = { // Don't attempt to continue if there are any errors. bail: true, // You may want 'eval' instead if you prefer to see the compiled output in DevTools. // See the discussion in https://github.com/facebookincubator/create-react-app/issues/343. devtool: 'cheap-module-source-map', // These are the "entry points" to our application. // This means they will be the "root" imports that are included in JS bundle. // The first two entry points enable "hot" CSS and auto-refreshes for JS. entry: [ // Include an alternative client for WebpackDevServer. A client's job is to // connect to WebpackDevServer by a socket and get notified about changes. // When you save a file, the client will either apply hot updates (in case // of CSS changes), or refresh the page (in case of JS changes). When you // make a syntax error, this client will display a syntax error overlay. // Note: instead of the default WebpackDevServer client, we use a custom one // to bring better experience for Create React App users. You can replace // the line below with these two lines if you prefer the stock client: // require.resolve('webpack-dev-server/client') + '?/', // require.resolve('webpack/hot/dev-server'), require.resolve('react-dev-utils/webpackHotDevClient'), // We ship a few polyfills by default: require.resolve('./polyfills'), // Errors should be considered fatal in development require.resolve('react-error-overlay'), // Finally, this is your app's code: paths.appIndexJs, // We include the app code last so that if there is a runtime error during // initialization, it doesn't blow up the WebpackDevServer client, and // changing JS code would still trigger a refresh. ], output: { // The build folder. path: paths.appBuild, // Generated JS file names (with nested folders). // There will be one main bundle, and one file per asynchronous chunk. // We don't currently advertise code splitting but Webpack supports it. filename: 'static/js/[name].[hash].js', chunkFilename: 'static/js/[name].[hash].js', // We inferred the "public path" (such as / or /my-project) from homepage. publicPath: publicPath, // Point sourcemap entries to original disk location devtoolModuleFilenameTemplate: info => path.relative(paths.appSrc, info.absoluteResourcePath) }, watch:true, resolve: { // This allows you to set a fallback for where Webpack should look for modules. // We placed these paths second because we want `node_modules` to "win" // if there are any conflicts. This matches Node resolution mechanism. // https://github.com/facebookincubator/create-react-app/issues/253 modules: ['node_modules', paths.appNodeModules].concat( // It is guaranteed to exist because we tweak it in `env.js` process.env.NODE_PATH.split(path.delimiter).filter(Boolean)), // These are the reasonable defaults supported by the Node ecosystem. // We also include JSX as a common component filename extension to support // some tools, although we do not recommend using it, see: // https://github.com/facebookincubator/create-react-app/issues/290 extensions: [ '.ts', '.tsx', '.js', '.json', '.jsx' ], alias: { // Support React Native Web // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/ 'react-native': 'react-native-web' }, plugins: [// Prevents users from importing files from outside of src/ (or node_modules/). // This often causes confusion because we only process files within src/ with babel. // To fix this, we prevent you from importing files out of src/ -- if you'd like to, // please link the files into your node_modules/ and let module-resolution kick in. // Make sure your source files are compiled, as they will not be processed in any way. new ModuleScopePlugin(paths.appSrc)] }, module: { strictExportPresence: true, rules: [ // TODO: Disable require.ensure as it's not a standard language feature. // We are waiting for https://github.com/facebookincubator/create-react-app/issues/2176. // { parser: { requireEnsure: false } }, // First, run the linter. // It's important to do this before Babel processes the JS. { test: /\.(ts|tsx)$/, loader: require.resolve('tslint-loader'), enforce: 'pre', include: paths.appSrc, options: { typeCheck:true } }, { test: /\.js$/, loader: require.resolve('source-map-loader'), enforce: 'pre', include: paths.appSrc }, // ** ADDING/UPDATING LOADERS ** // The "file" loader handles all assets unless explicitly excluded. // The `exclude` list *must* be updated with every change to loader extensions. // When adding a new loader, you must add its `test` // as a new entry in the `exclude` list for "file" loader. // "file" loader makes sure those assets get served by WebpackDevServer. // When you `import` an asset, you get its (virtual) filename. // In production, they would get copied to the `build` folder. { exclude: [ /\.html$/, // We have to write /\.(js|jsx)(\?.*)?$/ rather than just /\.(js|jsx)$/ // because you might change the hot reloading server from the custom one // to Webpack's built-in webpack-dev-server/client?/, which would not // get properly excluded by /\.(js|jsx)$/ because of the query string. // Webpack 2 fixes this, but for now we include this hack. // https://github.com/facebookincubator/create-react-app/issues/1713 /\.(js|jsx)(\?.*)?$/, /\.(ts|tsx)(\?.*)?$/, /\.css$/, /\.json$/, /\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/ ], loader: require.resolve('file-loader'), options: { name: 'static/media/[name].[hash:8].[ext]' } }, // "url" loader works like "file" loader except that it embeds assets // smaller than specified limit in bytes as data URLs to avoid requests. // A missing `test` is equivalent to a match. { test: [ /\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/ ], loader: require.resolve('url-loader'), options: { limit: 10000, name: 'static/media/[name].[hash:8].[ext]' } }, // Compile .tsx? { test: /\.(ts|tsx)$/, include: paths.appSrc, loader: require.resolve('ts-loader') }, // "postcss" loader applies autoprefixer to our CSS. // "css" loader resolves paths in CSS and adds assets as dependencies. // "style" loader turns CSS into JS modules that inject