UNPKG

11.2 kBJavaScriptView Raw
1// @remove-on-eject-begin
2/**
3 * Copyright (c) 2015-present, Facebook, Inc.
4 * All rights reserved.
5 *
6 * This source code is licensed under the BSD-style license found in the
7 * LICENSE file in the root directory of this source tree. An additional grant
8 * of patent rights can be found in the PATENTS file in the same directory.
9 */
10// @remove-on-eject-end
11'use strict';
12
13var autoprefixer = require('autoprefixer');
14var webpack = require('webpack');
15var HtmlWebpackPlugin = require('html-webpack-plugin');
16var ExtractTextPlugin = require('extract-text-webpack-plugin');
17var ManifestPlugin = require('webpack-manifest-plugin');
18var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
19var prometheus = require('./prometheus');
20var paths = require('./paths');
21var getClientEnvironment = require('./env');
22
23// @remove-on-eject-begin
24// `path` is not used after eject - see https://github.com/facebookincubator/create-react-app/issues/1174
25var path = require('path');
26// @remove-on-eject-end
27
28// Webpack uses `publicPath` to determine where the app is being served from.
29// It requires a trailing slash, or the file assets will get an incorrect path.
30var publicPath = paths.servedPath;
31// Some apps do not use client-side routing with pushState.
32// For these, "homepage" can be set to "." to enable relative asset paths.
33var shouldUseRelativeAssetPaths = publicPath === './';
34// `publicUrl` is just like `publicPath`, but we will provide it to our app
35// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
36// Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
37var publicUrl = publicPath.slice(0, -1);
38// Get environment variables to inject into our app.
39var env = getClientEnvironment(publicUrl);
40
41// Assert this just to be safe.
42// Development builds of React are slow and not intended for production.
43if (env.stringified['process.env'].NODE_ENV !== '"production"') {
44 throw new Error('Production builds must have NODE_ENV=production.');
45}
46
47// Note: defined here because it will be used more than once.
48const cssFilename = 'css/[name].[contenthash:8].css';
49
50// ExtractTextPlugin expects the build output to be flat.
51// (See https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/27)
52// However, our output is structured with css, js and media folders.
53// To have this structure working with relative paths, we have to use custom options.
54const extractTextPluginOptions = shouldUseRelativeAssetPaths
55 // Making sure that the publicPath goes back to to build folder.
56 ? { publicPath: Array(cssFilename.split('/').length).join('../') }
57 : undefined;
58
59// This is the production configuration.
60// It compiles slowly and is focused on producing a fast and minimal bundle.
61// The development configuration is different and lives in a separate file.
62module.exports = {
63 // Don't attempt to continue if there are any errors.
64 bail: true,
65 // We generate sourcemaps in production. This is slow but gives good results.
66 // You can exclude the *.map files from the build during deployment.
67 devtool: 'source-map',
68 // In production, we only want to load the polyfills and the app code.
69 entry: [require.resolve('./polyfills')]
70 // PROMETHEUS: rex autoloaded dependencies
71 .concat(prometheus.entry)
72 .concat([paths.appIndexJs]),
73 output: {
74 // The build folder.
75 path: paths.appBuild,
76 // Generated JS file names (with nested folders).
77 // There will be one main bundle, and one file per asynchronous chunk.
78 // We don't currently advertise code splitting but Webpack supports it.
79 filename: 'js/[name].[chunkhash:8].js',
80 chunkFilename: 'js/[name].[chunkhash:8].chunk.js',
81 // We inferred the "public path" (such as / or /my-project) from homepage.
82 publicPath: publicPath
83 },
84 resolve: {
85 // This allows you to set a fallback for where Webpack should look for modules.
86 // We read `NODE_PATH` environment variable in `paths.js` and pass paths here.
87 // We use `fallback` instead of `root` because we want `node_modules` to "win"
88 // if there any conflicts. This matches Node resolution mechanism.
89 // https://github.com/facebookincubator/create-react-app/issues/253
90 fallback: [paths.appNodeModules].concat(paths.nodePaths),
91 // These are the reasonable defaults supported by the Node ecosystem.
92 // We also include JSX as a common component filename extension to support
93 // some tools, although we do not recommend using it, see:
94 // https://github.com/facebookincubator/create-react-app/issues/290
95 extensions: ['.js', '.json', '.jsx', ''],
96 alias: {
97 // Support React Native Web
98 // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
99 'react-native': 'react-native-web'
100 }
101 },
102 // @remove-on-eject-begin
103 // Resolve loaders (webpack plugins for CSS, images, transpilation) from the
104 // directory of `react-scripts` itself rather than the project directory.
105 resolveLoader: {
106 root: paths.ownNodeModules.concat(paths.nodePaths)
107 // PROMETHEUS: This is required for backward compat.
108 // moduleTemplates: ['*-loader']
109 },
110 // @remove-on-eject-end
111 module: {
112 // First, run the linter.
113 // It's important to do this before Babel processes the JS.
114 preLoaders: [
115 {
116 test: /\.(js|jsx)$/,
117 loader: 'eslint',
118 include: paths.appSrc
119 }
120 ],
121 loaders: [
122 // ** ADDING/UPDATING LOADERS **
123 // The "url" loader handles all assets unless explicitly excluded.
124 // The `exclude` list *must* be updated with every change to loader extensions.
125 // When adding a new loader, you must add its `test`
126 // as a new entry in the `exclude` list in the "url" loader.
127
128 // "url" loader embeds assets smaller than specified size as data URLs to avoid requests.
129 // Otherwise, it acts like the "file" loader.
130 {
131 exclude: [
132 /\.html$/,
133 /\.(js|jsx)$/,
134 /\.css$/,
135 /\.json$/,
136 /\.svg$/
137 ],
138 loader: 'url',
139 query: {
140 limit: 10000,
141 name: 'static/media/[name].[hash:8].[ext]'
142 }
143 },
144 // Process JS with Babel.
145 {
146 test: /\.(js|jsx)$/,
147 include: paths.appSrc,
148 loader: 'babel',
149 // @remove-on-eject-begin
150 query: {
151 babelrc: false,
152 presets: [require.resolve('babel-preset-prometheusresearch')],
153 },
154 // @remove-on-eject-end
155 },
156 // The notation here is somewhat confusing.
157 // "postcss" loader applies autoprefixer to our CSS.
158 // "css" loader resolves paths in CSS and adds assets as dependencies.
159 // "style" loader normally turns CSS into JS modules injecting <style>,
160 // but unlike in development configuration, we do something different.
161 // `ExtractTextPlugin` first applies the "postcss" and "css" loaders
162 // (second argument), then grabs the result CSS and puts it into a
163 // separate file in our build process. This way we actually ship
164 // a single CSS file in production instead of JS code injecting <style>
165 // tags. If you use code splitting, however, any async bundles will still
166 // use the "style" loader inside the async code so CSS from them won't be
167 // in the main CSS file.
168 {
169 test: /\.css$/,
170 loader: ExtractTextPlugin.extract(
171 'style',
172 'css?importLoaders=1!postcss',
173 extractTextPluginOptions
174 )
175 // Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
176 },
177 // JSON is not enabled by default in Webpack but both Node and Browserify
178 // allow it implicitly so we also enable it.
179 {
180 test: /\.json$/,
181 loader: 'json'
182 },
183 // "file" loader for svg
184 {
185 test: /\.svg$/,
186 loader: 'file',
187 query: {
188 name: 'static/media/[name].[hash:8].[ext]'
189 }
190 }
191 // ** STOP ** Are you adding a new loader?
192 // Remember to add the new extension(s) to the "url" loader exclusion list.
193 ]
194 },
195 // @remove-on-eject-begin
196 // Point ESLint to our predefined config.
197 eslint: {
198 // TODO: consider separate config for production,
199 // e.g. to enable no-console and no-debugger only in production.
200 configFile: path.join(__dirname, '../eslintrc'),
201 useEslintrc: false
202 },
203 // @remove-on-eject-end
204 // We use PostCSS for autoprefixing only.
205 postcss: function() {
206 return [
207 autoprefixer({
208 browsers: [
209 '>1%',
210 'last 4 versions',
211 'Firefox ESR',
212 'not ie < 9', // React doesn't support IE8 anyway
213 ]
214 }),
215 ];
216 },
217 plugins: [
218 // Makes some environment variables available in index.html.
219 // The public URL is available as %PUBLIC_URL% in index.html, e.g.:
220 // <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
221 // In production, it will be an empty string unless you specify "homepage"
222 // in `package.json`, in which case it will be the pathname of that URL.
223 // PROMETHEUS: disable
224 // new InterpolateHtmlPlugin(env.raw),
225 // Generates an `index.html` file with the <script> injected.
226 // PROMETHEUS: disable
227 // new HtmlWebpackPlugin({
228 // inject: true,
229 // template: paths.appHtml,
230 // minify: {
231 // removeComments: true,
232 // collapseWhitespace: true,
233 // removeRedundantAttributes: true,
234 // useShortDoctype: true,
235 // removeEmptyAttributes: true,
236 // removeStyleLinkTypeAttributes: true,
237 // keepClosingSlash: true,
238 // minifyJS: true,
239 // minifyCSS: true,
240 // minifyURLs: true
241 // }
242 // }),
243 // Makes some environment variables available to the JS code, for example:
244 // if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
245 // It is absolutely essential that NODE_ENV was set to production here.
246 // Otherwise React will be compiled in the very slow development mode.
247 new webpack.DefinePlugin(env.stringified),
248 // This helps ensure the builds are consistent if source hasn't changed:
249 new webpack.optimize.OccurrenceOrderPlugin(),
250 // Try to dedupe duplicated modules, if any:
251 new webpack.optimize.DedupePlugin(),
252 // Minify the code.
253 new webpack.optimize.UglifyJsPlugin({
254 compress: {
255 screw_ie8: true, // React doesn't support IE8
256 warnings: false
257 },
258 mangle: {
259 screw_ie8: true
260 },
261 output: {
262 comments: false,
263 screw_ie8: true
264 }
265 }),
266 // Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
267 new ExtractTextPlugin(cssFilename),
268 // Generate a manifest file which contains a mapping of all asset filenames
269 // to their corresponding output file so that tools can pick it up without
270 // having to parse `index.html`.
271 new ManifestPlugin({
272 fileName: 'asset-manifest.json'
273 }),
274 ].concat(prometheus.plugins),
275 // Some libraries import Node modules but don't use them in the browser.
276 // Tell Webpack to provide empty mocks for them so importing them works.
277 node: {
278 fs: 'empty',
279 net: 'empty',
280 tls: 'empty'
281 }
282};