1 | 'use strict';
|
2 |
|
3 |
|
4 |
|
5 | const path = require('path');
|
6 | const webpack = require('webpack');
|
7 | const HtmlWebpackPlugin = require('html-webpack-plugin');
|
8 | const ManifestPlugin = require('webpack-manifest-plugin');
|
9 | const ChunkManifestPlugin = require('chunk-manifest-webpack-plugin');
|
10 | const WebpackMd5Hash = require('webpack-md5-hash');
|
11 | const merge = require('webpack-merge');
|
12 | const prettyjson = require('prettyjson');
|
13 | const semverUtils = require('semver-utils');
|
14 | const webpackVersion = semverUtils.parseRange(require('webpack/package.json').version)[0].major;
|
15 | const isWebpack2 = webpackVersion === '2';
|
16 | const nodeModulesDir = path.resolve(__dirname, '../node_modules');
|
17 |
|
18 | function validateWebpackConfig(webpackConfig) {
|
19 | webpackConfig.module.loaders.forEach(loader => {
|
20 | if (!loader.include && !loader.exclude) {
|
21 | throw Error('DvhbWebpack: "include" option is missing for ' + loader.test + ' Webpack loader.');
|
22 | }
|
23 | });
|
24 | }
|
25 |
|
26 | module.exports = function (config, env) {
|
27 | process.env.NODE_ENV = process.env.BABEL_ENV = env;
|
28 |
|
29 | const isProd = env === 'production';
|
30 |
|
31 | let webpackConfig = {
|
32 | output: {
|
33 | path: config.distDir,
|
34 | filename: '[name].js'
|
35 | },
|
36 | resolveLoader: {
|
37 | moduleExtensions: ['-loader', '.loader'],
|
38 | },
|
39 | plugins: [
|
40 | new webpack.DefinePlugin({
|
41 | 'process.env': {
|
42 | NODE_ENV: JSON.stringify(env),
|
43 | },
|
44 | }),
|
45 | new webpack.optimize.CommonsChunkPlugin({
|
46 | name: 'vendor',
|
47 | minChunks: function (module) {
|
48 | return /node_modules/.test(module.resource);
|
49 | }
|
50 | }),
|
51 | new WebpackMd5Hash(),
|
52 | new ManifestPlugin(),
|
53 | new ChunkManifestPlugin({
|
54 | filename: "chunk-manifest.json",
|
55 | manifestVariable: "webpackManifest"
|
56 | }),
|
57 | ],
|
58 | module: {
|
59 | loaders: [
|
60 | {
|
61 | test: /\.css$/,
|
62 | include: config.sourceDir,
|
63 | loader: 'style!css',
|
64 | },
|
65 | ],
|
66 | },
|
67 | };
|
68 |
|
69 | if (config.template) {
|
70 | webpackConfig.plugins.push(
|
71 | new HtmlWebpackPlugin({
|
72 | title: config.title,
|
73 | template: config.template,
|
74 | inject: true,
|
75 | }));
|
76 | }
|
77 |
|
78 | const loaderModulesDirectories = [
|
79 | nodeModulesDir,
|
80 | 'node_modules',
|
81 | ];
|
82 |
|
83 | if (isWebpack2) {
|
84 | webpackConfig = merge(webpackConfig, {
|
85 | resolve: {
|
86 | extensions: ['.js', '.jsx', '.json'],
|
87 | modules: [
|
88 | config.sourceDir,
|
89 | nodeModulesDir,
|
90 | 'node_modules',
|
91 | ],
|
92 | },
|
93 | resolveLoader: {
|
94 | modules: loaderModulesDirectories,
|
95 | },
|
96 | plugins: [
|
97 | new webpack.LoaderOptionsPlugin({
|
98 | minimize: isProd,
|
99 | debug: !isProd
|
100 | }),
|
101 | ],
|
102 | });
|
103 | }
|
104 | else {
|
105 | webpackConfig = merge(webpackConfig, {
|
106 | resolve: {
|
107 | extensions: ['', '.js', '.jsx', '.json'],
|
108 | root: config.sourceDir,
|
109 | moduleDirectories: [
|
110 | nodeModulesDir,
|
111 | 'node_modules',
|
112 | ],
|
113 | },
|
114 | resolveLoader: {
|
115 | modulesDirectories: loaderModulesDirectories,
|
116 | },
|
117 | debug: !isProd,
|
118 | });
|
119 | }
|
120 |
|
121 | const entryScript = path.resolve(config.sourceDir, 'index');
|
122 |
|
123 | if (isProd) {
|
124 | webpackConfig = merge(webpackConfig, {
|
125 | output: {
|
126 | filename: '[name].[chunkhash].js',
|
127 | chunkFilename: '[name].[chunkhash].js'
|
128 | },
|
129 | entry: [
|
130 | entryScript,
|
131 | ],
|
132 | devtool: false,
|
133 | cache: false,
|
134 | plugins: [
|
135 | new webpack.optimize.DedupePlugin(),
|
136 | new webpack.optimize.UglifyJsPlugin({
|
137 | compress: {
|
138 | warnings: false,
|
139 | },
|
140 | output: {
|
141 | comments: false,
|
142 | },
|
143 | mangle: false,
|
144 | }),
|
145 | ],
|
146 | module: {
|
147 | loaders: [],
|
148 | },
|
149 | });
|
150 | }
|
151 | else {
|
152 | webpackConfig = merge(webpackConfig, {
|
153 | entry: [
|
154 | 'webpack-hot-middleware/client?reload=true',
|
155 | entryScript,
|
156 | ],
|
157 | cache: true,
|
158 | devtool: 'eval',
|
159 | stats: {
|
160 | colors: true,
|
161 | reasons: true,
|
162 | },
|
163 | plugins: [
|
164 | new webpack.optimize.OccurenceOrderPlugin(),
|
165 | new webpack.HotModuleReplacementPlugin(),
|
166 | new webpack.NoErrorsPlugin(),
|
167 | ],
|
168 | module: {
|
169 | loaders: [],
|
170 | },
|
171 | });
|
172 | }
|
173 |
|
174 | if (config.extendWebpackConfig) {
|
175 | webpackConfig = config.extendWebpackConfig(webpackConfig, env);
|
176 | validateWebpackConfig(webpackConfig);
|
177 | }
|
178 |
|
179 | if (config.verbose) {
|
180 | console.log();
|
181 | console.log('Using Webpack config:');
|
182 | console.log(prettyjson.render(webpackConfig));
|
183 | console.log();
|
184 | }
|
185 |
|
186 | return webpackConfig;
|
187 | };
|