'use strict'; const path = require('path'); const webpack = require('webpack'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); const ManifestPlugin = require('webpack-manifest-plugin'); const ResolveEntryModulesPlugin = require("resolve-entry-modules-webpack-plugin"); const atImport = require('postcss-import'); const postcssURL = require("postcss-url"); const cssNext = require('postcss-cssnext'); const paths = require('./paths'); const getClientEnvironment = require('./env'); // 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 = paths.publicPath; // 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 === './'; // Get environment variables to inject into our app. const env = getClientEnvironment(); // 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.'); } // Allow hashing to be disabled by passing an ENV let hashFilenames = true; if ( env.stringified['process.env'].ASSETS_HASH_FILENAMES && env.stringified['process.env'].ASSETS_HASH_FILENAMES === '"false"' ) { hashFilenames = false; } // Note: defined here because it will be used more than once. const cssFilename = hashFilenames ? '[name].[contenthash:8].css' : '[name].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('../') } : {}; // This is the production configuration. // It compiles slowly and is focused on producing a fast and minimal bundle. // The development configuration is different and lives in a separate file. module.exports = { // Don't attempt to continue if there are any errors. bail: true, // We generate sourcemaps in production. This is slow but gives good results. // You can exclude the *.map files from the build during deployment. // devtool: 'source-map', // Specify the context we expect app code to be loaded from context: paths.appSrc, // In production, we only want to load the polyfills and the app code. entry: paths.appEntries.reduce((output, entry) => { const [name, location] = entry output[name] = [ // We ship a few polyfills by default require.resolve('./polyfills'), location, ] return output }, {}), 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: hashFilenames ? '[name].[chunkhash:8].js' : '[name].js', chunkFilename: hashFilenames ? '[name].[chunkhash:8].chunk.js' : '[name].chunk.js', // We inferred the "public path" (such as / or /my-project) from homepage. publicPath: publicPath, }, resolve: { // This allows you to set a fallback for where Webpack should look for modules. // We read `NODE_PATH` environment variable in `paths.js` and pass paths here. // 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'] .concat(paths.nodePaths), // 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: ['.js', '.json', '.jsx'], }, // Resolve loaders (webpack plugins for CSS, images, transpilation) from the // directory of `icelab-assets` itself rather than the project directory. resolveLoader: { modules: [ paths.ownNodeModules, paths.appNodeModules, ], }, module: { rules: [ // Disable require.ensure as it's not a standard language feature. { parser: { requireEnsure: false } }, // First, run the linter. // It's important to do this before Babel processes the JS. { test: /\.(js|jsx)$/, enforce: 'pre', use: [ { // Point ESLint to our predefined config. options: { // Separate config for production to enable no-debugger only in // production. configFile: path.join(__dirname, '../eslintrc.prod'), useEslintrc: false, }, loader: 'eslint-loader', }, ], include: paths.appSrc, }, // ** ADDING/UPDATING LOADERS ** // The "url" 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 in the "url" loader. // "file" loader makes sure those assets end up in the `build` folder. // When you `import` an asset, you get its filename. { exclude: [ /\.html$/, /\.(js|jsx)$/, /\.css$/, /\.json$/ ], use: [{ loader: 'file-loader', options: { name: hashFilenames ? '[path][name].[hash:8].[ext]' : '[path][name].[ext]', }, }], }, // Process JS with Babel. { test: /\.(js|jsx)$/, include: paths.appSrc, use: [{ loader: 'babel-loader', options: { babelrc: true, presets: [require.resolve('babel-preset-react-app')], plugins: [require.resolve('babel-plugin-syntax-dynamic-import')], }, }], }, // The notation here is somewhat confusing. // "postcss" loader applies autoprefixer to our CSS. // "css" loader resolves paths in CSS and adds assets as dependencies. // "style" loader normally turns CSS into JS modules injecting