2016-06-02 16:42:00 +02:00
|
|
|
/* eslint-disable strict, no-console, object-shorthand, prefer-template */
|
2016-06-02 15:24:16 +02:00
|
|
|
/* eslint-disable import/no-extraneous-dependencies, import/newline-after-import */
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const path = require('path');
|
2016-06-02 15:31:21 +02:00
|
|
|
const removeTrailingSlash = require('remove-trailing-slash');
|
2016-06-02 15:24:16 +02:00
|
|
|
|
|
|
|
const webpack = require('webpack');
|
|
|
|
const autoPrefixer = require('autoprefixer');
|
|
|
|
const combineLoaders = require('webpack-combine-loaders');
|
2016-06-02 15:35:31 +02:00
|
|
|
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
2016-06-02 15:24:16 +02:00
|
|
|
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
2016-06-02 15:26:28 +02:00
|
|
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
2016-06-02 15:24:16 +02:00
|
|
|
|
|
|
|
require('dotenv').load({ silent: true });
|
|
|
|
|
2016-06-03 18:06:51 +02:00
|
|
|
const EXTRACT = process.env.NODE_ENV === 'extract';
|
2016-06-02 15:24:16 +02:00
|
|
|
const PRODUCTION = process.env.NODE_ENV === 'production';
|
|
|
|
|
|
|
|
const PATHS = {
|
|
|
|
APP: path.resolve(__dirname, 'js/app.js'),
|
|
|
|
BUILD: path.resolve(__dirname, 'build'),
|
|
|
|
DIST: path.resolve(__dirname, 'dist'),
|
|
|
|
NODE_MODULES: path.resolve(__dirname, 'node_modules'),
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** EXTERNAL DEFINITIONS INJECTED INTO APP **/
|
|
|
|
const DEFINITIONS = {
|
|
|
|
'process.env': {
|
|
|
|
NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development'),
|
2016-06-02 15:31:21 +02:00
|
|
|
|
|
|
|
APP_VERSION: JSON.stringify(process.env.ONION_APP_VERSION || 'dev'),
|
|
|
|
|
|
|
|
API_URL: JSON.stringify(
|
|
|
|
removeTrailingSlash(process.env.ONION_API_URL || 'https://staging.ascribe.io/api')
|
|
|
|
),
|
|
|
|
APP_BASE_PATH: JSON.stringify(
|
|
|
|
removeTrailingSlash(process.env.ONION_BASE_PATH || '')
|
|
|
|
),
|
|
|
|
SERVER_URL: JSON.stringify(
|
|
|
|
removeTrailingSlash(process.env.ONION_SERVER_URL || 'https://staging.ascribe.io')
|
|
|
|
),
|
|
|
|
|
|
|
|
RAVEN_DSN_URL: JSON.stringify(process.env.RAVEN_DSN_URL || ''),
|
|
|
|
|
|
|
|
S3_ACCESS_KEY: JSON.stringify(process.env.S3_ACCESS_KEY || ''),
|
2016-06-24 16:14:16 +02:00
|
|
|
S3_ACL: JSON.stringify(process.env.S3_ACL || 'public-read'),
|
|
|
|
S3_BUCKET: JSON.stringify(process.env.S3_BUCKET || 'ascribe0'),
|
2016-06-02 15:31:21 +02:00
|
|
|
},
|
2016-06-02 15:24:16 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** PLUGINS **/
|
|
|
|
const PLUGINS = [
|
|
|
|
new webpack.DefinePlugin(DEFINITIONS),
|
|
|
|
new webpack.NoErrorsPlugin(),
|
2016-06-02 15:35:31 +02:00
|
|
|
|
|
|
|
// Handle any dependencies that don't play nicely with System.import resolution
|
|
|
|
new CopyWebpackPlugin([
|
|
|
|
{
|
|
|
|
from: path.resolve(PATHS.NODE_MODULES, 'audiojs/audiojs'),
|
|
|
|
to: 'third_party/audiojs'
|
|
|
|
},
|
|
|
|
]),
|
|
|
|
|
2016-06-02 15:26:28 +02:00
|
|
|
// Generate index.html for app with link and style tags addded
|
|
|
|
new HtmlWebpackPlugin({
|
|
|
|
filename: 'index.html',
|
|
|
|
minify: PRODUCTION ? {
|
|
|
|
collapseWhitespace: true,
|
|
|
|
minifyJS: true,
|
|
|
|
removeComments: true,
|
|
|
|
removeRedundantAttributes: true
|
|
|
|
} : false,
|
|
|
|
template: path.resolve(__dirname, 'index_template.html'),
|
|
|
|
}),
|
|
|
|
];
|
|
|
|
|
2016-06-02 15:24:16 +02:00
|
|
|
const PROD_PLUGINS = [
|
2016-06-03 11:17:07 +02:00
|
|
|
new webpack.optimize.DedupePlugin(),
|
2016-06-02 15:24:16 +02:00
|
|
|
new webpack.optimize.UglifyJsPlugin({
|
|
|
|
compress: {
|
2016-06-15 13:00:51 +02:00
|
|
|
screw_ie8: true,
|
2016-06-02 15:24:16 +02:00
|
|
|
warnings: false
|
|
|
|
},
|
|
|
|
output: {
|
|
|
|
comments: false
|
2016-06-15 12:58:36 +02:00
|
|
|
},
|
|
|
|
sourceMap: true,
|
2016-06-02 15:24:16 +02:00
|
|
|
}),
|
|
|
|
new webpack.LoaderOptionsPlugin({
|
|
|
|
debug: false,
|
|
|
|
minimize: true
|
|
|
|
}),
|
|
|
|
];
|
|
|
|
|
2016-06-03 18:06:51 +02:00
|
|
|
if (PRODUCTION || EXTRACT) {
|
|
|
|
// Extract stylesheets out of bundle
|
|
|
|
PLUGINS.push(
|
|
|
|
new ExtractTextPlugin(PRODUCTION ? 'css/styles.min.css' : 'css/styles.css', {
|
|
|
|
allChunks: true
|
|
|
|
})
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-06-02 15:24:16 +02:00
|
|
|
if (PRODUCTION) {
|
|
|
|
PLUGINS.push(...PROD_PLUGINS);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** LOADERS **/
|
|
|
|
const JS_LOADER = combineLoaders([
|
|
|
|
{
|
|
|
|
loader: 'babel',
|
|
|
|
query: {
|
|
|
|
cacheDirectory: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
|
|
|
|
const CSS_LOADER = combineLoaders([
|
|
|
|
{
|
|
|
|
loader: 'css',
|
|
|
|
query: {
|
|
|
|
sourceMap: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{ loader: 'postcss' },
|
|
|
|
]);
|
|
|
|
|
|
|
|
const SASS_LOADER = `${CSS_LOADER}!` + combineLoaders([
|
|
|
|
{
|
|
|
|
loader: 'sass',
|
|
|
|
query: {
|
|
|
|
precision: '8', // See https://github.com/twbs/bootstrap-sass#sass-number-precision
|
|
|
|
outputStyle: 'expanded',
|
|
|
|
sourceMap: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
]);
|
|
|
|
|
|
|
|
const URL_FONT_LOADER = combineLoaders([
|
|
|
|
{
|
|
|
|
loader: 'url',
|
|
|
|
query: {
|
|
|
|
limit: 10000,
|
|
|
|
name: 'fonts/[name].[ext]',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
|
|
|
|
const FILE_FONT_LOADER = combineLoaders([
|
|
|
|
{
|
|
|
|
loader: 'file',
|
|
|
|
query: {
|
|
|
|
name: 'fonts/[name].[ext]',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
|
|
|
|
const LOADERS = [
|
|
|
|
{
|
|
|
|
test: /\.jsx?$/,
|
|
|
|
exclude: [PATHS.NODE_MODULES],
|
|
|
|
loader: JS_LOADER,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
test: /\.s[ac]ss$/,
|
|
|
|
exclude: [PATHS.NODE_MODULES],
|
2016-06-03 18:06:51 +02:00
|
|
|
loader: PRODUCTION || EXTRACT ? ExtractTextPlugin.extract('style', SASS_LOADER)
|
|
|
|
: `style!${SASS_LOADER}`,
|
2016-06-02 15:24:16 +02:00
|
|
|
},
|
|
|
|
|
2016-06-02 15:35:31 +02:00
|
|
|
// Dependencies
|
|
|
|
// Shmui
|
|
|
|
{
|
|
|
|
test: /\.css$/,
|
|
|
|
include: [path.resolve(PATHS.NODE_MODULES, 'shmui')],
|
|
|
|
loader: `style!${CSS_LOADER}`,
|
|
|
|
},
|
|
|
|
|
2016-06-02 15:24:16 +02:00
|
|
|
// Fonts
|
|
|
|
// woffs and svgs are typically smaller should we can try to load them as a url
|
|
|
|
{
|
|
|
|
test: /\.(woff2?|svg)$/,
|
|
|
|
loader: URL_FONT_LOADER,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
test: /\.(ttf|eot)$/,
|
|
|
|
loader: FILE_FONT_LOADER,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
/** EXPORTED WEBPACK CONFIG **/
|
|
|
|
const config = {
|
2016-06-03 18:06:51 +02:00
|
|
|
entry: [
|
|
|
|
PRODUCTION || EXTRACT ? 'bootstrap-loader/extractStyles' : 'bootstrap-loader',
|
|
|
|
PATHS.APP
|
|
|
|
],
|
2016-06-02 15:24:16 +02:00
|
|
|
|
|
|
|
output: {
|
|
|
|
filename: PRODUCTION ? 'js/bundle.min.js' : 'js/bundle.js',
|
|
|
|
path: PRODUCTION ? PATHS.DIST : PATHS.BUILD,
|
2016-06-02 17:08:03 +02:00
|
|
|
publicPath: '/static/',
|
2016-06-02 15:24:16 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
debug: !PRODUCTION,
|
|
|
|
|
|
|
|
devtool: PRODUCTION ? '#source-map' : '#inline-source-map',
|
|
|
|
|
2016-06-24 13:46:30 +02:00
|
|
|
target: 'web',
|
|
|
|
|
2016-06-02 15:24:16 +02:00
|
|
|
resolve: {
|
2016-06-24 13:46:09 +02:00
|
|
|
// Dedupe any dependencies' polyfill, react, or react-css-modules dependencies when
|
|
|
|
// developing with npm link
|
|
|
|
alias: {
|
|
|
|
'babel-runtime': path.resolve(PATHS.NODE_MODULES, 'babel-runtime'),
|
|
|
|
'core-js': path.resolve(PATHS.NODE_MODULES, 'core-js'),
|
|
|
|
'js-utility-belt': path.resolve(PATHS.NODE_MODULES, 'js-utility-belt'),
|
|
|
|
'react': path.resolve(PATHS.NODE_MODULES, 'react'),
|
|
|
|
'react-dom': path.resolve(PATHS.NODE_MODULES, 'react-dom'),
|
|
|
|
'react-css-modules': path.resolve(PATHS.NODE_MODULES, 'react-css-modules'),
|
|
|
|
},
|
2016-06-02 15:24:16 +02:00
|
|
|
extensions: ['', '.js', '.jsx'],
|
|
|
|
modules: ['node_modules'], // Don't use absolute path here to allow recursive matching
|
|
|
|
},
|
|
|
|
|
|
|
|
plugins: PLUGINS,
|
|
|
|
|
|
|
|
module: {
|
|
|
|
loaders: LOADERS,
|
|
|
|
},
|
|
|
|
|
|
|
|
postcss: [autoPrefixer()],
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = config;
|