-
-
Save leonid-bauxy/d94f54e41d67c8346caaaed3046cd9c6 to your computer and use it in GitHub Desktop.
webpack.config.babel.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { relative, join } from 'path'; | |
import _ from 'lodash'; | |
import { load as loadEnv } from 'dotenv-extended'; | |
import webpack from 'webpack'; | |
import validate from 'webpack-validator'; | |
import nodeExternals from 'webpack-node-externals'; | |
import StatsPlugin from 'stats-webpack-plugin'; | |
import HtmlWebpackPlugin from 'html-webpack-plugin'; | |
import { | |
getBabelConfig, | |
getStylesLoaders, | |
getEnvHelpers, | |
getPostCssPlugins, | |
hoistLoaderIfOne, | |
} from './helpers'; | |
import { | |
ROOT_DIR, | |
SRC_DIR, | |
TEST_DIR, | |
BUTTONS_DIR, | |
POPUP_DIR, | |
PUBLIC_DIR, | |
DEMO_DIR, | |
META_DIR, | |
URL_LOADER_LIMIT, | |
ASSETS_DIR, | |
} from './constants'; | |
loadEnv({ | |
path: join(ROOT_DIR, '.env'), | |
defaults: join(ROOT_DIR, '.env.defaults'), | |
}); | |
const { | |
isDev, | |
isProd, | |
isTest, | |
ifDev, | |
ifProd, | |
ifTest, | |
ifServer, | |
ifNotTest, | |
ifWithDemo, | |
} = getEnvHelpers(); | |
const { | |
NODE_ENV, | |
DEV_SERVER_HOSTNAME, | |
DEV_SERVER_PORT, | |
DEV_SERVER_SECURE, | |
API_ROOT, | |
PUBLIC_PATH, | |
OPEN_BROWSER, | |
} = process.env; | |
const DEV_SERVER_PROTOCOL = (DEV_SERVER_SECURE === 'true') ? 'https' : 'http'; | |
const DEV_SERVER_PATH = `${DEV_SERVER_PROTOCOL}://${DEV_SERVER_HOSTNAME}:${DEV_SERVER_PORT}`; | |
const publicPath = isDev ? DEV_SERVER_PATH : PUBLIC_PATH; | |
const commonPostCssPlugins = getPostCssPlugins(); | |
const config = { | |
target: isTest ? 'node' : 'web', | |
bail: isProd, | |
devtool: isProd ? false : 'eval', | |
progress: true, | |
cache: true, | |
externals: ifTest([ | |
{ | |
'react/addons': true, | |
'react/lib/ExecutionEnvironment': true, | |
'react/lib/ReactContext': true, | |
}, | |
nodeExternals(), | |
]), | |
entry: ifNotTest({ | |
myProject: _.compact([ | |
ifServer( | |
`webpack-dev-server/client?${DEV_SERVER_PATH}` | |
), | |
join(SRC_DIR, 'entries/buttons/buttons'), | |
]), | |
}), | |
devServer: ifServer({ | |
serverPath: DEV_SERVER_PATH, | |
hostname: DEV_SERVER_HOSTNAME, | |
port: Number(DEV_SERVER_PORT), | |
openBrowser: OPEN_BROWSER, | |
}), | |
output: { | |
publicPath: _.endsWith(publicPath, '/') ? publicPath : `${publicPath}/`, | |
path: PUBLIC_DIR, | |
filename: `[name]${isProd ? '.min' : ''}.js`, | |
chunkFilename: `[name]${isProd ? '.[chunkhash:5].min' : ''}.js`, | |
library: 'MyProject', | |
libraryTarget: 'umd', | |
}, | |
resolve: { | |
extensions: ['', '.js', '.jsx', '.json'], | |
alias: { | |
'src': SRC_DIR, | |
'popup': POPUP_DIR, | |
'buttons': BUTTONS_DIR, | |
'Popup': join(POPUP_DIR, 'components/Popup'), | |
'assets': join(SRC_DIR, 'assets'), | |
'styles': join(SRC_DIR, 'assets/styles'), | |
'shared': join(POPUP_DIR, 'shared'), | |
'decorators': join(POPUP_DIR, 'shared/decorators'), | |
}, | |
}, | |
module: { | |
loaders: _.compact([ | |
{ | |
test: /\.js$/, | |
include: [SRC_DIR, TEST_DIR], | |
loader: 'babel', | |
query: getBabelConfig(), | |
}, | |
hoistLoaderIfOne({ | |
test: /\/assets\/styles\/main\.scss$/, | |
loaders: getStylesLoaders({ cssModules: false, preRender: isTest }), | |
}), | |
hoistLoaderIfOne({ | |
test: /(\/entries\/buttons\/\S+\.scss|\/assets\/styles\/shared\/\S+\.scss)$/, | |
loaders: getStylesLoaders({ cssModules: true, preRender: isTest, postCssPack: 'buttons' }), | |
}), | |
hoistLoaderIfOne({ | |
test: /(\/entries\/popup\/\S+\.scss|\/assets\/styles\/shared\/\S+\.scss)$/, | |
loaders: getStylesLoaders({ cssModules: true, preRender: isTest, postCssPack: 'popup' }), | |
}), | |
{ | |
test: /\.svg$/, | |
loader: isTest ? 'null' : 'svg-inline', | |
}, | |
{ | |
test: /\.json$/, | |
loader: 'json', | |
}, | |
hoistLoaderIfOne({ | |
test: /\.(jpe?g|png|gif)$/, | |
loaders: _.compact([ | |
ifTest('null'), | |
ifNotTest({ | |
loader: 'url', | |
query: { | |
limit: URL_LOADER_LIMIT, | |
name: 'images/[name].[hash:5].[ext]', | |
}, | |
}), | |
ifProd({ | |
loader: 'image-webpack', | |
query: { | |
bypassOnDebug: true, | |
progressive: true, | |
interlaced: false, | |
pngquant: { | |
quality: '75-95', | |
speed: 5, | |
}, | |
}, | |
}), | |
]), | |
}), | |
hoistLoaderIfOne({ | |
test: /\.(ttf|eot)$/, | |
include: join(ASSETS_DIR, 'fonts'), | |
loaders: _.compact([ | |
ifTest('null'), | |
ifNotTest({ | |
loader: 'url', | |
query: { | |
limit: URL_LOADER_LIMIT, | |
name: `fonts/[name]${isProd ? '.[hash:5]' : ''}.[ext]`, | |
}, | |
}), | |
]), | |
}), | |
]), | |
}, | |
postcss: () => ifNotTest({ | |
defaults: commonPostCssPlugins, | |
buttons: commonPostCssPlugins, | |
popup: getPostCssPlugins({ parentSelector: '#my-popup' }), | |
}), | |
plugins: _.compact([ | |
new webpack.DefinePlugin({ | |
'process.env': { | |
NODE_ENV: JSON.stringify(NODE_ENV), | |
API_ROOT: JSON.stringify(API_ROOT), | |
}, | |
}), | |
new webpack.LoaderOptionsPlugin({ | |
minify: isProd, | |
debug: isDev, | |
}), | |
ifDev( | |
new webpack.NamedModulesPlugin() | |
), | |
_.flowRight(ifNotTest, ifWithDemo)( | |
new HtmlWebpackPlugin({ | |
template: join(DEMO_DIR, 'index.ejs'), | |
filename: join(PUBLIC_DIR, 'index.html'), | |
inject: false, | |
}) | |
), | |
ifNotTest( | |
new StatsPlugin( | |
relative(PUBLIC_DIR, join(META_DIR, 'webpack-stats.json')), | |
{ chunkModules: true } | |
) | |
), | |
ifNotTest( | |
new webpack.optimize.OccurrenceOrderPlugin() | |
), | |
_.flowRight(ifNotTest, ifProd)( | |
new webpack.optimize.DedupePlugin() | |
), | |
_.flowRight(ifNotTest, ifProd)( | |
new webpack.optimize.UglifyJsPlugin({ | |
mangle: true, | |
warnings: false, | |
comments: false, | |
compressor: { | |
dead_code: true, | |
unused: true, | |
keep_fnames: true, | |
pure_getters: true, | |
unsafe: true, | |
unsafe_comps: true, | |
screw_ie8: true, | |
warnings: false, | |
}, | |
}) | |
), | |
]), | |
}; | |
const { Joi } = validate; | |
export default validate(config, { | |
schemaExtension: Joi.object({ | |
...ifServer({ | |
devServer: Joi.object({ | |
serverPath: Joi.string().required(), | |
hostname: Joi.string().required(), | |
port: Joi.number().required(), | |
openBrowser: Joi.string().required(), | |
}), | |
}), | |
}), | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment