Advertisement
Guest User

webpack.config.prod.js

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