forked from kodeklubben/codeclub-viewer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwebpack.config.babel.js
192 lines (164 loc) · 5.46 KB
/
webpack.config.babel.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/**
* The webpack config file
* -----------------------
*
* BOOTSTRAP:
* To adjust which parts of bootstrap to include in the build, adjust options in .bootstraprc.
* The more you include, the bigger the final build will be.
* Also, to get smaller builds, do
* import Button from 'react-bootstrap/lib/Button'; // YES
* rather than
* import { Button } from 'react-bootstrap'; // NO
*
*
* Regarding CSS extraction:
* CSS is not extracted for hot reloading (i.e. when isHot is true).
* We never extract css from the 'main' entry, since we want this CSS to override CSS from vendors,
* e.g. override bootstrap. By not extracting it, it will become inline in the <head>.
* (i.e. don't use ExtractTextPlugin.extract() in the css and scss loaders.)
* Bootstrap has its own extract-methods (activated f.ex. by using bootstrap-loader/extractStyles)
*
*/
////////////////////////////////////////
// DEFINE GLOBAL VARIABLES FOR ESLINT //
////////////////////////////////////////
/* eslint-env node */
//////////////////////
// IMPORT / REQUIRE //
//////////////////////
import baseConfig, {getValuesAsArray, getLoaders, buildDir, publicPath} from './webpack.base.config.babel';
const webpack = require('webpack');
import path from 'path';
import autoprefixer from 'autoprefixer';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import CleanWebpackPlugin from 'clean-webpack-plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
///////////////
// CONSTANTS //
///////////////
const isHot = process.argv.indexOf('--hot') >= 0;
console.log(`isHot=${isHot}`);
const isProduction = process.env.NODE_ENV === 'production';
console.log(`isProduction=${isProduction}`);
console.log();
const filenameBase = isHot ? '[name]' : '[name].[chunkhash]';
// Small hack to avoid having to type a slash at the end of the url if there is a subdir in publicPath:
const newPublicPath = (isHot && publicPath.length > 1 && publicPath.slice(-1) === '/') ?
publicPath.slice(0, -1) : publicPath;
///////////////
// FUNCTIONS //
///////////////
function getEntry() {
const appEntry = './src/index.js';
if (isHot) {
return {
main: [
'bootstrap-loader',
appEntry
]
};
} else {
console.log('Splitting out vendors to separate chunks (vendor and vendor2):');
// Get all packages that exist in package.json's 'dependencies' into config.entry.vendor:
const pkg = require('./package.json');
// Exclude any packages that don't play nice with CommonsChunkPlugin, and add them via vendor2:
const excludeFromVendorEntry = ['react-bootstrap'];
return {
// Include all dependencies from package.json:
vendor: Object.keys(pkg.dependencies).filter(function(v) {
const includeVendor = excludeFromVendorEntry.indexOf(v) < 0;
if (!includeVendor) {
console.log(` ---> EXCLUDED from the 'vendor' chunk: ${v}`);
}
return includeVendor;
}),
vendor2: [ // Include other vendors not in 'vendor'
'bootstrap-loader/extractStyles'
],
main: appEntry
};
}
}
function getPlugins() {
let plugins = [
// Create the root index.html needed regardless of whether we make the other static index.htmls.
new HtmlWebpackPlugin({
title: 'Kodeklubben',
template: 'src/index-template.ejs',
inject: 'body',
chunksSortMode: 'dependency' // Make sure they are loaded in the right order in index.html
}),
// Create template for the static non-root index.html files
new HtmlWebpackPlugin({
title: 'Kodeklubben (server)',
filename: 'index-html-template.ejs',
appcss: '<%= appCss %>',
appcontent: '<%= appHtml %>',
template: 'src/index-template.ejs',
inject: 'body',
chunksSortMode: 'dependency' // Make sure they are loaded in the right order in index.html
})
];
if (isProduction) {
plugins = plugins.concat([
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
pure_funcs: 'console.log' // removes these functions from the code
}
})
]);
}
if (!isHot) {
plugins = plugins.concat([
new CleanWebpackPlugin([buildDir], {
root: path.resolve(__dirname)
}),
new ExtractTextPlugin(filenameBase + '.css', {allChunks: false}),
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest'] // Extract vendor and manifest files; only if vendor is defined in entry
})
]);
}
return plugins;
}
///////////////////////
// THE ACTUAL CONFIG //
///////////////////////
const config = {
...baseConfig,
entry: getEntry(),
output: {
...baseConfig.output,
publicPath: newPublicPath,
filename: `${filenameBase}.js`,
chunkFilename: `${filenameBase}.js`
},
devServer: {
historyApiFallback: true // needed when using browserHistory (instead of hashHistory)
},
historyApiFallback: {
index: publicPath
},
plugins: [
...baseConfig.plugins,
...getPlugins()
],
postcss: [autoprefixer]
};
////////////////////
// Modify loaders //
////////////////////
if (isHot) {
const loaders = getLoaders();
loaders.js.loader = 'react-hot-loader!' + loaders.js.loader;
config.module.loaders = getValuesAsArray(loaders);
}
export default config;