Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save dan-dr/59e335212bac0b897b92bb28913ea490 to your computer and use it in GitHub Desktop.
Save dan-dr/59e335212bac0b897b92bb28913ea490 to your computer and use it in GitHub Desktop.
webpack: (config, { stage, defaultLoaders }) => {
/*
* TypeScript Support
* */
// Add .ts and .tsx extension to resolver
config.resolve.extensions.push('.ts', '.tsx')
// Add TypeScript Path Mappings (from tsconfig via webpack.config.js)
// to react-statics alias resolution
config.resolve.alias = typescriptWebpackPaths.resolve.alias
// Needed for momoent js resolution in React 16
// See: https://github.com/moment/moment/issues/2979#issuecomment-332217206
config.resolve.alias.moment$ = 'moment/moment.js'
// We replace the existing JS rule with one, that allows us to use
// both TypeScript and JavaScript interchangeably
const jsTsLoader = {
test: /\.(js|jsx|ts|tsx)$/,
exclude: defaultLoaders.jsLoader.exclude, // as std jsLoader exclude
use: [
{
loader: 'babel-loader',
},
{
loader: 'ts-loader',
options: {
transpileOnly: true,
},
},
],
}
/*
* Less Support
* */
// Add .less & .css to resolver
config.resolve.extensions.push('.less')
config.resolve.extensions.push('.css')
// Loader depending on stage. Same format as the default cssLoader.
let lessLoader = {}
let loaders = [
{
loader: 'css-loader',
options: {
importLoaders: 1,
minimize: stage !== 'dev',
sourceMap: true,
},
},
{
loader: 'postcss-loader',
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
sourceMap: true,
ident: 'postcss',
plugins: () => [
postcssFlexbugsFixes,
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
{
loader: 'less-loader',
options: {
sourceMap: true,
modifyVars: themeVariables,
javascriptEnabled: true,
},
},
]
if (stage === 'dev') {
// Enable Hot Module Replacement
config.plugins.push(new webpack.HotModuleReplacementPlugin())
// In-Line with style-loader
lessLoader =
{
test: /\.less$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1,
minimize: false,
sourceMap: true,
},
},
{
loader: 'postcss-loader',
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
sourceMap: true,
ident: 'postcss',
plugins: () => [
postcssFlexbugsFixes,
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
{
loader: 'less-loader',
options: {
sourceMap: true,
modifyVars: themeVariables,
javascriptEnabled: true,
},
},
],
}
} else {
loaders = ['style-loader'].concat(loaders)
} else if (stage === 'prod') {
// Extract to style.css
lessLoader =
{
test: /\.less$/,
loader: ExtractTextPlugin.extract({
fallback: {
loader: 'style-loader',
options: {
hmr: false,
sourceMap: false,
},
},
use: [
{
loader: 'css-loader',
options: {
importLoaders: 1,
minimize: true,
sourceMap: false,
},
},
{
loader: 'postcss-loader',
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
postcssFlexbugsFixes,
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
{
loader: 'less-loader',
options: {
sourceMap: false,
modifyVars: themeVariables,
javascriptEnabled: true,
},
},
],
}),
}
loaders = ExtractTextPlugin.extract({
fallback: {
loader: 'style-loader',
options: {
hmr: false,
sourceMap: false,
},
},
use: loaders,
})
}
const lessLoader = {
test: /\.less$/,
use: loaders,
}
/*
* Add new Loaders to default Loaders
* */
config.module.rules = [
{
oneOf: [
jsTsLoader,
lessLoader,
defaultLoaders.cssLoader,
defaultLoaders.fileLoader,
],
oneOf: [jsTsLoader, lessLoader, defaultLoaders.cssLoader, defaultLoaders.fileLoader],
},
]
// Update ExtractTextPlugin with current instance
config.plugins[2] =
new ExtractTextPlugin({
filename: getPath => {
process.env.extractedCSSpath = 'styles.css'
return getPath('styles.css')
},
allChunks: true,
if (stage === 'prod') {
// Update ExtractTextPlugin with current instance
config.plugins.forEach((plugin, index) => {
if (plugin instanceof ExtractTextPlugin) {
config.plugins[index] = new ExtractTextPlugin({
filename: getPath => {
process.env.extractedCSSpath = 'styles.css'
return getPath('styles.css')
},
allChunks: true,
})
}
})
}
return config
},
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment