* Moving files to their new homes. Subsequent commit will wire everything up again. * Relink files and split stylesheet. Requires adding resolve-url-loader to fix sass import relativity. * Remove browserslist warning. * Remove the need for ProfileMain * Fix test issues - needed thunk.
223 lines
7.9 KiB
JavaScript
Executable File
223 lines
7.9 KiB
JavaScript
Executable File
// This is the prod Webpack config. All settings here should prefer smaller,
|
|
// optimized bundles at the expense of a longer build time.
|
|
const Merge = require('webpack-merge');
|
|
const commonConfig = require('./webpack.common.config.js');
|
|
const path = require('path');
|
|
const glob = require('glob');
|
|
const webpack = require('webpack');
|
|
const CleanWebpackPlugin = require('clean-webpack-plugin');
|
|
const HtmlWebpackNewRelicPlugin = require('html-webpack-new-relic-plugin');
|
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
|
const PurgecssPlugin = require('purgecss-webpack-plugin');
|
|
const NewRelicSourceMapPlugin = require('new-relic-source-map-webpack-plugin');
|
|
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; // eslint-disable-line prefer-destructuring
|
|
const PostCssRtlPlugin = require('postcss-rtl');
|
|
const PostCssAutoprefixerPlugin = require('autoprefixer');
|
|
const CssNano = require('cssnano');
|
|
|
|
module.exports = Merge.smart(commonConfig, {
|
|
mode: 'production',
|
|
devtool: 'source-map',
|
|
output: {
|
|
filename: '[name].[chunkhash].js',
|
|
path: path.resolve(__dirname, '../dist'),
|
|
},
|
|
module: {
|
|
// Specify file-by-file rules to Webpack. Some file-types need a particular kind of loader.
|
|
rules: [
|
|
// The babel-loader transforms newer ES2015+ syntax to older ES5 for older browsers.
|
|
// Babel is configured with the .babelrc file at the root of the project.
|
|
{
|
|
test: /\.(js|jsx)$/,
|
|
include: [
|
|
path.resolve(__dirname, '../src'),
|
|
path.resolve(__dirname, '../footer'),
|
|
path.resolve(__dirname, '../header'),
|
|
],
|
|
loader: 'babel-loader',
|
|
},
|
|
{
|
|
test: /\.js$/,
|
|
use: ['source-map-loader'],
|
|
enforce: 'pre',
|
|
},
|
|
// Webpack, by default, includes all CSS in the javascript bundles. Unfortunately, that means:
|
|
// a) The CSS won't be cached by browsers separately (a javascript change will force CSS
|
|
// re-download). b) Since CSS is applied asyncronously, it causes an ugly
|
|
// flash-of-unstyled-content.
|
|
//
|
|
// To avoid these problems, we extract the CSS from the bundles into separate CSS files that
|
|
// can be included as <link> tags in the HTML <head> manually.
|
|
//
|
|
// We will not do this in development because it prevents hot-reloading from working and it
|
|
// increases build time.
|
|
{
|
|
test: /(.scss|.css)$/,
|
|
use: [
|
|
MiniCssExtractPlugin.loader,
|
|
{
|
|
loader: 'css-loader', // translates CSS into CommonJS
|
|
options: {
|
|
sourceMap: true,
|
|
},
|
|
},
|
|
{
|
|
loader: 'postcss-loader',
|
|
options: {
|
|
plugins: () => [
|
|
PostCssRtlPlugin(),
|
|
PostCssAutoprefixerPlugin({ grid: true }),
|
|
CssNano(),
|
|
],
|
|
},
|
|
},
|
|
{
|
|
loader: 'resolve-url-loader',
|
|
},
|
|
{
|
|
loader: 'sass-loader', // compiles Sass to CSS
|
|
options: {
|
|
sourceMap: true,
|
|
includePaths: [
|
|
path.join(__dirname, '../node_modules'),
|
|
path.join(__dirname, '../src'),
|
|
],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
test: /.svg$/,
|
|
issuer: {
|
|
test: /\.jsx?$/,
|
|
},
|
|
loader: '@svgr/webpack',
|
|
},
|
|
// Webpack, by default, uses the url-loader for images and fonts that are required/included by
|
|
// files it processes, which just base64 encodes them and inlines them in the javascript
|
|
// bundles. This makes the javascript bundles ginormous and defeats caching so we will use the
|
|
// file-loader instead to copy the files directly to the output directory.
|
|
{
|
|
test: /\.(woff2?|ttf|svg|eot)(\?v=\d+\.\d+\.\d+)?$/,
|
|
loader: 'file-loader',
|
|
},
|
|
{
|
|
test: /\.(jpe?g|png|gif|ico)(\?v=\d+\.\d+\.\d+)?$/,
|
|
use: [
|
|
'file-loader',
|
|
{
|
|
loader: 'image-webpack-loader',
|
|
options: {
|
|
optimizationlevel: 7,
|
|
mozjpeg: {
|
|
progressive: true,
|
|
},
|
|
gifsicle: {
|
|
interlaced: false,
|
|
},
|
|
pngquant: {
|
|
quality: '65-90',
|
|
speed: 4,
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
// New in Webpack 4. Replaces CommonChunksPlugin. Extract common modules among all chunks to one
|
|
// common chunk and extract the Webpack runtime to a single runtime chunk.
|
|
optimization: {
|
|
runtimeChunk: 'single',
|
|
splitChunks: {
|
|
chunks: 'all',
|
|
},
|
|
},
|
|
// Specify additional processing or side-effects done on the Webpack output bundles as a whole.
|
|
plugins: [
|
|
// Cleans the dist directory before each build
|
|
new CleanWebpackPlugin(['dist'], {
|
|
root: path.join(__dirname, '../'),
|
|
}),
|
|
// Writes the extracted CSS from each entry to a file in the output directory.
|
|
new MiniCssExtractPlugin({
|
|
filename: '[name].[chunkhash].css',
|
|
}),
|
|
// Scan files for class names and ids and remove unused css
|
|
new PurgecssPlugin({
|
|
paths: [].concat(
|
|
// Scan files in this app
|
|
glob.sync(`${path.resolve(__dirname, '../src')}/**/*`, { nodir: true }),
|
|
// Scan files in any edx frontend-component
|
|
glob.sync(`${path.resolve(__dirname, '../node_modules/@edx/frontend-component')}*/**/*`, { nodir: true }),
|
|
// Scan files in paragon
|
|
glob.sync(`${path.resolve(__dirname, '../node_modules/@edx/paragon')}/**/*`, { nodir: true }),
|
|
),
|
|
// Protect react-css-transition class names
|
|
whitelistPatterns: [/-enter/, /-appear/, /-exit/],
|
|
}),
|
|
// Generates an HTML file in the output directory.
|
|
new HtmlWebpackPlugin({
|
|
inject: true, // Appends script tags linking to the webpack bundles at the end of the body
|
|
template: path.resolve(__dirname, '../public/index.html'),
|
|
}),
|
|
new webpack.EnvironmentPlugin({
|
|
NODE_ENV: 'production',
|
|
|
|
// App configuration
|
|
ACCESS_TOKEN_COOKIE_NAME: null,
|
|
BASE_URL: null,
|
|
CREDENTIALS_BASE_URL: null,
|
|
CSRF_COOKIE_NAME: 'csrftoken',
|
|
CSRF_TOKEN_API_PATH: null,
|
|
ECOMMERCE_BASE_URL: null,
|
|
LANGUAGE_PREFERENCE_COOKIE_NAME: null,
|
|
LMS_BASE_URL: null,
|
|
LOGIN_URL: null,
|
|
LOGOUT_URL: null,
|
|
MARKETING_SITE_BASE_URL: null,
|
|
ORDER_HISTORY_URL: null,
|
|
REFRESH_ACCESS_TOKEN_ENDPOINT: null,
|
|
SEGMENT_KEY: null,
|
|
SITE_NAME: null,
|
|
USER_INFO_COOKIE_NAME: null,
|
|
|
|
// ProfileFooter configuration
|
|
APPLE_APP_STORE_URL: null,
|
|
CONTACT_URL: null,
|
|
ENTERPRISE_MARKETING_FOOTER_UTM_MEDIUM: null,
|
|
ENTERPRISE_MARKETING_URL: null,
|
|
ENTERPRISE_MARKETING_UTM_CAMPAIGN: null,
|
|
ENTERPRISE_MARKETING_UTM_SOURCE: null,
|
|
FACEBOOK_URL: null,
|
|
GOOGLE_PLAY_URL: null,
|
|
LINKED_IN_URL: null,
|
|
OPEN_SOURCE_URL: null,
|
|
PRIVACY_POLICY_URL: null,
|
|
REDDIT_URL: null,
|
|
SUPPORT_URL: null,
|
|
TERMS_OF_SERVICE_URL: null,
|
|
TWITTER_URL: null,
|
|
YOU_TUBE_URL: null,
|
|
}),
|
|
new HtmlWebpackNewRelicPlugin({
|
|
// This plugin fixes an issue where the newrelic script will break if
|
|
// not added directly to the HTML.
|
|
// We use non empty strings as defaults here to prevent errors for empty configs
|
|
license: process.env.NEW_RELIC_LICENSE_KEY || 'fake_app',
|
|
applicationID: process.env.NEW_RELIC_APP_ID || 'fake_license',
|
|
}),
|
|
new NewRelicSourceMapPlugin({
|
|
applicationId: process.env.NEW_RELIC_APP_ID,
|
|
nrAdminKey: process.env.NEW_RELIC_ADMIN_KEY,
|
|
staticAssetUrl: process.env.BASE_URL,
|
|
noop: typeof process.env.NEW_RELIC_ADMIN_KEY === 'undefined', // upload source maps in prod builds only
|
|
}),
|
|
new BundleAnalyzerPlugin({
|
|
analyzerMode: 'static',
|
|
openAnalyzer: false,
|
|
}),
|
|
],
|
|
});
|