Advertisement
Guest User

webpack.config.prod.js

a guest
Mar 21st, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. 'use strict';
  2.  
  3. const autoprefixer = require('autoprefixer');
  4. const path = require('path');
  5. const webpack = require('webpack');
  6. const HtmlWebpackPlugin = require('html-webpack-plugin');
  7. const ExtractTextPlugin = require('extract-text-webpack-plugin');
  8. const ManifestPlugin = require('webpack-manifest-plugin');
  9. const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
  10. const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');
  11. const eslintFormatter = require('react-dev-utils/eslintFormatter');
  12. const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
  13. const paths = require('./paths');
  14. const getClientEnvironment = require('./env');
  15.  
  16. // Webpack uses `publicPath` to determine where the app is being served from.
  17. // It requires a trailing slash, or the file assets will get an incorrect path.
  18. const publicPath = paths.servedPath;
  19. // Some apps do not use client-side routing with pushState.
  20. // For these, "homepage" can be set to "." to enable relative asset paths.
  21. const shouldUseRelativeAssetPaths = publicPath === './';
  22. // Source maps are resource heavy and can cause out of memory issue for large source files.
  23. const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
  24. // `publicUrl` is just like `publicPath`, but we will provide it to our app
  25. // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
  26. // Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
  27. const publicUrl = publicPath.slice(0, -1);
  28. // Get environment variables to inject into our app.
  29. const env = getClientEnvironment(publicUrl);
  30.  
  31. // Assert this just to be safe.
  32. // Development builds of React are slow and not intended for production.
  33. if (env.stringified['process.env'].NODE_ENV !== '"production"') {
  34.   throw new Error('Production builds must have NODE_ENV=production.');
  35. }
  36.  
  37. // Note: defined here because it will be used more than once.
  38. const cssFilename = 'static/css/[name].[contenthash:8].css';
  39.  
  40. // ExtractTextPlugin expects the build output to be flat.
  41. // (See https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/27)
  42. // However, our output is structured with css, js and media folders.
  43. // To have this structure working with relative paths, we have to use custom options.
  44. const extractTextPluginOptions = shouldUseRelativeAssetPaths
  45.   ? // Making sure that the publicPath goes back to to build folder.
  46.     { publicPath: Array(cssFilename.split('/').length).join('../') }
  47.   : {};
  48.  
  49. // This is the production configuration.
  50. // It compiles slowly and is focused on producing a fast and minimal bundle.
  51. // The development configuration is different and lives in a separate file.
  52. module.exports = {
  53.   // Don't attempt to continue if there are any errors.
  54.   bail: true,
  55.   // We generate sourcemaps in production. This is slow but gives good results.
  56.   // You can exclude the *.map files from the build during deployment.
  57.   devtool: shouldUseSourceMap ? 'source-map' : false,
  58.   // In production, we only want to load the polyfills and the app code.
  59.   entry: [require.resolve('./polyfills'), paths.appIndexJs],
  60.   output: {
  61.     // The build folder.
  62.     path: paths.appBuild,
  63.     // Generated JS file names (with nested folders).
  64.     // There will be one main bundle, and one file per asynchronous chunk.
  65.     // We don't currently advertise code splitting but Webpack supports it.
  66.     filename: 'static/js/[name].[chunkhash:8].js',
  67.     chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
  68.     // We inferred the "public path" (such as / or /my-project) from homepage.
  69.     publicPath: publicPath,
  70.     // Point sourcemap entries to original disk location (format as URL on Windows)
  71.     devtoolModuleFilenameTemplate: info =>
  72.       path
  73.         .relative(paths.appSrc, info.absoluteResourcePath)
  74.         .replace(/\\/g, '/'),
  75.   },
  76.   resolve: {
  77.     // This allows you to set a fallback for where Webpack should look for modules.
  78.     // We placed these paths second because we want `node_modules` to "win"
  79.     // if there are any conflicts. This matches Node resolution mechanism.
  80.     // https://github.com/facebookincubator/create-react-app/issues/253
  81.     modules: ['node_modules', paths.appNodeModules].concat(
  82.       // It is guaranteed to exist because we tweak it in `env.js`
  83.       process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
  84.     ),
  85.     // These are the reasonable defaults supported by the Node ecosystem.
  86.     // We also include JSX as a common component filename extension to support
  87.     // some tools, although we do not recommend using it, see:
  88.     // https://github.com/facebookincubator/create-react-app/issues/290
  89.     // `web` extension prefixes have been added for better support
  90.     // for React Native Web.
  91.     extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
  92.     alias: {
  93.      
  94.       // Support React Native Web
  95.       // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
  96.       'react-native': 'react-native-web',
  97.     },
  98.     plugins: [
  99.       // Prevents users from importing files from outside of src/ (or node_modules/).
  100.       // This often causes confusion because we only process files within src/ with babel.
  101.       // To fix this, we prevent you from importing files out of src/ -- if you'd like to,
  102.       // please link the files into your node_modules/ and let module-resolution kick in.
  103.       // Make sure your source files are compiled, as they will not be processed in any way.
  104.       new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
  105.     ],
  106.   },
  107.   module: {
  108.     strictExportPresence: true,
  109.     rules: [
  110.       // TODO: Disable require.ensure as it's not a standard language feature.
  111.       // We are waiting for https://github.com/facebookincubator/create-react-app/issues/2176.
  112.       // { parser: { requireEnsure: false } },
  113.  
  114.       // First, run the linter.
  115.       // It's important to do this before Babel processes the JS.
  116.       {
  117.         test: /\.(js|jsx|mjs)$/,
  118.         enforce: 'pre',
  119.         use: [
  120.           {
  121.             options: {
  122.               formatter: eslintFormatter,
  123.               eslintPath: require.resolve('eslint'),
  124.              
  125.             },
  126.             loader: require.resolve('eslint-loader'),
  127.           },
  128.         ],
  129.         include: paths.appSrc,
  130.       },
  131.       {
  132.         // "oneOf" will traverse all following loaders until one will
  133.         // match the requirements. When no loader matches it will fall
  134.         // back to the "file" loader at the end of the loader list.
  135.         oneOf: [
  136.           // "url" loader works just like "file" loader but it also embeds
  137.           // assets smaller than specified size as data URLs to avoid requests.
  138.           {
  139.             test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
  140.             loader: require.resolve('url-loader'),
  141.             options: {
  142.               limit: 10000,
  143.               name: 'static/media/[name].[hash:8].[ext]',
  144.             },
  145.           },
  146.           // Process JS with Babel.
  147.           {
  148.             test: /\.(js|jsx|mjs)$/,
  149.             include: paths.appSrc,
  150.             loader: require.resolve('babel-loader'),
  151.             exclude: /.*node_modules((?!localModule).)*$/,
  152.             options: {
  153.              
  154.               compact: true,
  155.             },
  156.           },
  157.           // The notation here is somewhat confusing.
  158.           // "postcss" loader applies autoprefixer to our CSS.
  159.           // "css" loader resolves paths in CSS and adds assets as dependencies.
  160.           // "style" loader normally turns CSS into JS modules injecting <style>,
  161.           // but unlike in development configuration, we do something different.
  162.           // `ExtractTextPlugin` first applies the "postcss" and "css" loaders
  163.           // (second argument), then grabs the result CSS and puts it into a
  164.           // separate file in our build process. This way we actually ship
  165.           // a single CSS file in production instead of JS code injecting <style>
  166.           // tags. If you use code splitting, however, any async bundles will still
  167.           // use the "style" loader inside the async code so CSS from them won't be
  168.           // in the main CSS file.
  169.           {
  170.             test: /\.css$/,
  171.             loader: ExtractTextPlugin.extract(
  172.               Object.assign(
  173.                 {
  174.                   fallback: {
  175.                     loader: require.resolve('style-loader'),
  176.                     options: {
  177.                       hmr: false,
  178.                     },
  179.                   },
  180.                   use: [
  181.                     {
  182.                       loader: require.resolve('css-loader'),
  183.                       options: {
  184.                         importLoaders: 1,
  185.                         minimize: true,
  186.                         sourceMap: shouldUseSourceMap,
  187.                       },
  188.                     },
  189.                     {
  190.                       loader: require.resolve('postcss-loader'),
  191.                       options: {
  192.                         // Necessary for external CSS imports to work
  193.                         // https://github.com/facebookincubator/create-react-app/issues/2677
  194.                         ident: 'postcss',
  195.                         plugins: () => [
  196.                           require('postcss-flexbugs-fixes'),
  197.                           autoprefixer({
  198.                             browsers: [
  199.                               '>1%',
  200.                               'last 4 versions',
  201.                               'Firefox ESR',
  202.                               'not ie < 9', // React doesn't support IE8 anyway
  203.                             ],
  204.                             flexbox: 'no-2009',
  205.                           }),
  206.                         ],
  207.                       },
  208.                     },
  209.                   ],
  210.                 },
  211.                 extractTextPluginOptions
  212.               )
  213.             ),
  214.             // Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
  215.           },
  216.           // "file" loader makes sure assets end up in the `build` folder.
  217.           // When you `import` an asset, you get its filename.
  218.           // This loader doesn't use a "test" so it will catch all modules
  219.           // that fall through the other loaders.
  220.           {
  221.             loader: require.resolve('file-loader'),
  222.             // Exclude `js` files to keep "css" loader working as it injects
  223.             // it's runtime that would otherwise processed through "file" loader.
  224.             // Also exclude `html` and `json` extensions so they get processed
  225.             // by webpacks internal loaders.
  226.             exclude: [/\.js$/, /\.html$/, /\.json$/],
  227.             options: {
  228.               name: 'static/media/[name].[hash:8].[ext]',
  229.             },
  230.           },
  231.           // ** STOP ** Are you adding a new loader?
  232.           // Make sure to add the new loader(s) before the "file" loader.
  233.         ],
  234.       },
  235.     ],
  236.   },
  237.   plugins: [
  238.     // Makes some environment variables available in index.html.
  239.     // The public URL is available as %PUBLIC_URL% in index.html, e.g.:
  240.     // <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
  241.     // In production, it will be an empty string unless you specify "homepage"
  242.     // in `package.json`, in which case it will be the pathname of that URL.
  243.     new InterpolateHtmlPlugin(env.raw),
  244.     // Generates an `index.html` file with the <script> injected.
  245.     new HtmlWebpackPlugin({
  246.       inject: true,
  247.       template: paths.appHtml,
  248.       minify: {
  249.         removeComments: true,
  250.         collapseWhitespace: true,
  251.         removeRedundantAttributes: true,
  252.         useShortDoctype: true,
  253.         removeEmptyAttributes: true,
  254.         removeStyleLinkTypeAttributes: true,
  255.         keepClosingSlash: true,
  256.         minifyJS: true,
  257.         minifyCSS: true,
  258.         minifyURLs: true,
  259.       },
  260.     }),
  261.     // Makes some environment variables available to the JS code, for example:
  262.     // if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
  263.     // It is absolutely essential that NODE_ENV was set to production here.
  264.     // Otherwise React will be compiled in the very slow development mode.
  265.     new webpack.DefinePlugin(env.stringified),
  266.     // Minify the code.
  267.     new webpack.optimize.UglifyJsPlugin({
  268.       compress: {
  269.         warnings: false,
  270.         // Disabled because of an issue with Uglify breaking seemingly valid code:
  271.         // https://github.com/facebookincubator/create-react-app/issues/2376
  272.         // Pending further investigation:
  273.         // https://github.com/mishoo/UglifyJS2/issues/2011
  274.         comparisons: false,
  275.       },
  276.       mangle: {
  277.         safari10: true,
  278.       },        
  279.       output: {
  280.         comments: false,
  281.         // Turned on because emoji and regex is not minified properly using default
  282.         // https://github.com/facebookincubator/create-react-app/issues/2488
  283.         ascii_only: true,
  284.       },
  285.       sourceMap: shouldUseSourceMap,
  286.     }),
  287.     // Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
  288.     new ExtractTextPlugin({
  289.       filename: cssFilename,
  290.     }),
  291.     // Generate a manifest file which contains a mapping of all asset filenames
  292.     // to their corresponding output file so that tools can pick it up without
  293.     // having to parse `index.html`.
  294.     new ManifestPlugin({
  295.       fileName: 'asset-manifest.json',
  296.     }),
  297.     // Generate a service worker script that will precache, and keep up to date,
  298.     // the HTML & assets that are part of the Webpack build.
  299.     new SWPrecacheWebpackPlugin({
  300.       // By default, a cache-busting query parameter is appended to requests
  301.       // used to populate the caches, to ensure the responses are fresh.
  302.       // If a URL is already hashed by Webpack, then there is no concern
  303.       // about it being stale, and the cache-busting can be skipped.
  304.       dontCacheBustUrlsMatching: /\.\w{8}\./,
  305.       filename: 'service-worker.js',
  306.       logger(message) {
  307.         if (message.indexOf('Total precache size is') === 0) {
  308.           // This message occurs for every build and is a bit too noisy.
  309.           return;
  310.         }
  311.         if (message.indexOf('Skipping static resource') === 0) {
  312.           // This message obscures real errors so we ignore it.
  313.           // https://github.com/facebookincubator/create-react-app/issues/2612
  314.           return;
  315.         }
  316.         console.log(message);
  317.       },
  318.       minify: true,
  319.       // For unknown URLs, fallback to the index page
  320.       navigateFallback: publicUrl + '/index.html',
  321.       // Ignores URLs starting from /__ (useful for Firebase):
  322.       // https://github.com/facebookincubator/create-react-app/issues/2237#issuecomment-302693219
  323.       navigateFallbackWhitelist: [/^\/saml\//],
  324.       // Don't precache sourcemaps (they're large) and build asset manifest:
  325.       staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/],
  326.     }),
  327.     // Moment.js is an extremely popular library that bundles large locale files
  328.     // by default due to how Webpack interprets its code. This is a practical
  329.     // solution that requires the user to opt into importing specific locales.
  330.     // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
  331.     // You can remove this if you don't use Moment.js:
  332.     new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
  333.   ],
  334.   // Some libraries import Node modules but don't use them in the browser.
  335.   // Tell Webpack to provide empty mocks for them so importing them works.
  336.   node: {
  337.     dgram: 'empty',
  338.     fs: 'empty',
  339.     net: 'empty',
  340.     tls: 'empty',
  341.     child_process: 'empty',
  342.   },
  343. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement