Skip to content
This repository has been archived by the owner on Jun 3, 2019. It is now read-only.

Commit

Permalink
Moves the 'standard' babel config into the webpack configFactory and …
Browse files Browse the repository at this point in the history
…instead lets the project config able to modify it via the plugin point.
  • Loading branch information
ctrlplusb committed Jan 9, 2017
1 parent 3148afc commit 85e9da4
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 79 deletions.
94 changes: 16 additions & 78 deletions config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,87 +291,24 @@ const config = {
// configuration adjustments. Additionally it helps to make merging
// from the origin starter kit a bit easier.
plugins: {
// This is used to resolve the babel configuration used to transpile the
// source bundles for development/production modes.
// This plugin allows you to provide final adjustments your babel
// configurations for each bundle before they get processed.
//
// Please use the provided values and then ensure that you return the
// appropriate values for the given target and mode.
babelConfig: (buildOptions) => {
// This function will be called once for each for your bundles. It will be
// provided the current webpack config, as well as the buildOptions which
// detail which bundle and mode is being targetted for the current function run.
babelConfig: (babelConfig, buildOptions) => {
// eslint-disable-next-line no-unused-vars
const { target, mode } = buildOptions;

return {
// We need to ensure that we do this otherwise the babelrc will
// get interpretted and for the current configuration this will mean
// that it will kill our webpack treeshaking feature as the modules
// transpilation has not been disabled within in.
babelrc: false,
// Example
/*
if (target === 'server' && mode === 'development') {
babelConfig.presets.push('foo');
}
*/

presets: [
// JSX
'react',
// Stage 3 javascript syntax.
// "Candidate: complete spec and initial browser implementations."
// Add anything lower than stage 3 at your own risk. :)
'stage-3',
// For our client bundles we transpile all the latest ratified
// ES201X code into ES5, safe for browsers. We exclude module
// transilation as webpack takes care of this for us, doing
// tree shaking in the process.
target === 'client'
? ['latest', { es2015: { modules: false } }]
: null,
// For our server bundle we use the awesome babel-preset-env which
// acts like babel-preset-latest in that it supports the latest
// ratified ES201X syntax, however, it will only transpile what
// is necessary for a target environment. We have configured it
// to target our current node version. This is cool because
// recent node versions have extensive support for ES201X syntax.
// Also, we have disabled modules transpilation as webpack will
// take care of that for us ensuring tree shaking takes place.
// NOTE: Make sure you use the same node version for development
// and production.
target === 'server'
? ['env', { targets: { node: true }, modules: false }]
: null,
].filter(x => x != null),

plugins: [
// Required to support react hot loader.
mode === 'development'
? 'react-hot-loader/babel'
: null,
// This decorates our components with __self prop to JSX elements,
// which React will use to generate some runtime warnings.
mode === 'development'
? 'transform-react-jsx-self'
: null,
// Adding this will give us the path to our components in the
// react dev tools.
mode === 'development'
? 'transform-react-jsx-source'
: null,
// The following plugin supports the code-split-component
// instances, taking care of all the heavy boilerplate that we
// would have had to do ourselves to get code splitting w/SSR
// support working.
// @see https://github.com/ctrlplusb/code-split-component
//
// We only include it in production as this library does not support
// React Hot Loader, which we use in development.
mode === 'production' && (target === 'server' || target === 'client')
? [
'code-split-component/babel',
{
// For our server bundle we will set the mode as being 'server'
// which will ensure that our code split components can be
// resolved synchronously, being much more helpful for
// pre-rendering.
mode: target,
},
]
: null,
].filter(x => x != null),
};
return babelConfig;
},

// This plugin allows you to provide final adjustments your webpack
Expand All @@ -384,7 +321,8 @@ const config = {
// provided the current webpack config, as well as the buildOptions which
// detail which bundle and mode is being targetted for the current function run.
webpackConfig: (webpackConfig, buildOptions) => {
const { target, mode } = buildOptions; // eslint-disable-line no-unused-vars
// eslint-disable-next-line no-unused-vars
const { target, mode } = buildOptions;

// Example:
/*
Expand Down
71 changes: 70 additions & 1 deletion tools/webpack/configFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,76 @@ export default function webpackConfigFactory(buildOptions) {
// We will use babel to do all our JS processing.
loaders: [{
path: 'babel-loader',
query: config.plugins.babelConfig(buildOptions),
// We will create a babel config and pass it through the plugin
// defined in the project configuration, allowing additional
// items to be added.
query: config.plugins.babelConfig(
// Our "standard" babel config.
{
// We need to ensure that we do this otherwise the babelrc will
// get interpretted and for the current configuration this will mean
// that it will kill our webpack treeshaking feature as the modules
// transpilation has not been disabled within in.
babelrc: false,

presets: [
// JSX
'react',
// Stage 3 javascript syntax.
// "Candidate: complete spec and initial browser implementations."
// Add anything lower than stage 3 at your own risk. :)
'stage-3',
// For our client bundles we transpile all the latest ratified
// ES201X code into ES5, safe for browsers. We exclude module
// transilation as webpack takes care of this for us, doing
// tree shaking in the process.
ifClient(['latest', { es2015: { modules: false } }]),
// For a node bundle we use the awesome babel-preset-env which
// acts like babel-preset-latest in that it supports the latest
// ratified ES201X syntax, however, it will only transpile what
// is necessary for a target environment. We have configured it
// to target our current node version. This is cool because
// recent node versions have extensive support for ES201X syntax.
// Also, we have disabled modules transpilation as webpack will
// take care of that for us ensuring tree shaking takes place.
// NOTE: Make sure you use the same node version for development
// and production.
ifNode(['env', { targets: { node: true }, modules: false }]),
].filter(x => x != null),

plugins: [
// Required to support react hot loader.
ifDevClient('react-hot-loader/babel'),
// This decorates our components with __self prop to JSX elements,
// which React will use to generate some runtime warnings.
ifDev('transform-react-jsx-self'),
// Adding this will give us the path to our components in the
// react dev tools.
ifDev('transform-react-jsx-source'),
// The following plugin supports the code-split-component
// instances, taking care of all the heavy boilerplate that we
// would have had to do ourselves to get code splitting w/SSR
// support working.
// @see https://github.com/ctrlplusb/code-split-component
//
// We only include it in production as this library does not support
// React Hot Loader, which we use in development.
ifElse(isProd && (isServer || isClient))(
[
'code-split-component/babel',
{
// For our server bundle we will set the mode as being 'server'
// which will ensure that our code split components can be
// resolved synchronously, being much more helpful for
// pre-rendering.
mode: target,
},
],
),
].filter(x => x != null),
},
buildOptions,
),
}],
}),

Expand Down

0 comments on commit 85e9da4

Please sign in to comment.