UNPKG

11.9 kBJavaScriptView Raw
1const path = require('path');
2const webpack = require('webpack');
3const BabelConfig = require('./BabelConfig');
4const Utils = require('../lib/utils');
5const ProgressBarPlugin = require('progress-bar-webpack-plugin');
6const ExtractTextPlugin = require('extract-text-webpack-plugin');
7const HtmlWebpackPlugin = require('html-webpack-plugin');
8const nodeExternals = require('webpack-node-externals');
9const CleanWebpackPlugin = require('clean-webpack-plugin');
10const LessPluginCleanCSS = require('less-plugin-clean-css');
11
12exports._default = function (env) {
13 env = env || 'development'
14 const output = {
15 path: path.join(process.cwd(), `.${path.sep}dist${path.sep}`),
16 };
17
18 const AUTOPREFIXER_BROWSERS = [
19 'Android 2.3',
20 'Android >= 4',
21 'Chrome >= 35',
22 'Firefox >= 31',
23 'Explorer >= 8',
24 'iOS >= 6',
25 'Opera >= 12',
26 'Safari >= 7.1',
27 ];
28
29 const GLOBALS = {
30 __IS_SSR__: false,
31 __MODE__:`'${env}'`,
32 'process.env.NODE_ENV': `'${env}'`,
33 };
34
35 const plugins = [
36 new webpack.DefinePlugin(GLOBALS),
37 new webpack.optimize.AggressiveMergingPlugin(),
38 new webpack.NoEmitOnErrorsPlugin(),
39 new webpack.optimize.ModuleConcatenationPlugin(),
40 new ProgressBarPlugin(),
41 new webpack.ProvidePlugin({
42 React: 'react',
43 ReactDOM: 'react-dom',
44 }),
45 new webpack.optimize.UglifyJsPlugin({
46 sourceMap:env === 'development',
47 beautify: false,
48 comments: false,
49 compress: {
50 warnings: false,
51 drop_console: false,
52 collapse_vars: true,
53 reduce_vars: true,
54 }
55 }),
56 ];
57
58 const moduleConfig = {
59 rules: [{
60 enforce: 'pre',
61 test: /\.jsx?$/,
62 use: {
63 loader: require.resolve('babel-loader'),
64 options: BabelConfig.get(),
65 },
66 include: /(node_modules\/igame_base_libs|src)/
67 }, {
68 test: /\.(png|jpg|jpeg|gif)$/,
69 use: require.resolve('url-loader') + '?limit=1024&&name=images/[name].[hash:6].[ext]',
70 }, {
71 test: /\.(eot|ttf|wav|mp3|svg|woff|woff2)$/,
72 use: require.resolve('file-loader') + '?name=fonts/[name].[hash:6].[ext]',
73 }, {
74 test: /\.css$/,
75 use: ExtractTextPlugin.extract({
76 allChunks: true,
77 fallback: require.resolve('style-loader'),
78 use: [require.resolve('css-loader'), {
79 loader: require.resolve('postcss-loader'),
80 options: {
81 plugins: (loader) => [
82 require('postcss-import')({
83 path: [Utils.resolveNodeModulesPath()]
84 }),
85 require('postcss-mixins')(),
86 require('postcss-nested')(),
87 require('cssnano')({
88 colormin: false,
89 zindex: false,
90 autoprefixer: false,
91 }),
92 require('postcss-cssnext')({
93 browsers: AUTOPREFIXER_BROWSERS,
94 }),
95 require('postcss-opacity')(),
96 require('../postcssPlugins/rgbaPlugin')(),
97 ]
98 }
99 }]
100 })
101 },{
102 test: /\.less$/,
103 use: ExtractTextPlugin.extract({
104 allChunks: true,
105 fallback: require.resolve('style-loader'),
106 use:[require.resolve('css-loader'),{
107 loader:require.resolve('less-loader'),
108 options:{
109 plugins:[
110 new LessPluginCleanCSS({ advanced: true })
111 ]
112 }
113 }]
114 })
115 }]
116 };
117
118 const resolve = {
119 extensions: ['.webpack.js', '.web.js', '.js', '.jsx'],
120 modules: [
121 Utils.resolveNodeModulesPath(),
122 'node_modules'
123 ]
124 };
125
126 const config = {
127 entry: {},
128 output,
129 module: moduleConfig,
130 plugins,
131 externals: {
132 'react': {
133 commonjs: 'react',
134 commonjs2: 'react',
135 amd: 'react',
136 root: 'React',
137 'var': 'React'
138 },
139 'react-dom': {
140 commonjs: 'react-dom',
141 commonjs2: 'react-dom',
142 amd: 'react-dom',
143 root: 'ReactDOM',
144 'var': 'ReactDOM'
145 },
146 'react-router': {
147 commonjs: 'react-router',
148 commonjs2: 'react-router',
149 amd: 'react-router',
150 root: 'ReactRouter',
151 'var': 'ReactRouter'
152 },
153 },
154 resolve,
155 };
156
157 return config;
158}
159
160exports.development = function () {
161 var config = this._default();
162 return config
163}
164
165exports.postDevelopment = function (config, devServerConfig,webpackConfig) {
166 process.noDeprecation = true;
167 var nodeModulesPath = Utils.resolveNodeModulesPath();
168 var preEntrys = [];
169 config.output.publicPath = webpackConfig.devPath;
170 //dev模式下不加hash
171 config.output.filename = '[name].js';
172 if(webpackConfig.preset === 'ie8'){
173 shimIe8Plugins(config);
174 }
175 config.plugins.push(new ExtractTextPlugin('[name].css'));
176 if (devServerConfig.hot) {
177 const patch = path.join(nodeModulesPath,`react-hot-loader${path.sep}patch`);
178 let devServer = path.join(nodeModulesPath,`webpack-dev-server${path.sep}client`);
179 devServer = `${devServer}?http://127.0.0.1:${devServerConfig.port}/`;
180 const hotDevServer = path.join(nodeModulesPath,`webpack${path.sep}hot${path.sep}dev-server`);
181 preEntrys = preEntrys.concat([patch, devServer, hotDevServer])
182 }
183
184 if(webpackConfig.devBuildOnly && Array.isArray(webpackConfig.devBuildOnly) && webpackConfig.devBuildOnly.length > 0){
185 const obj = {};
186 webpackConfig.devBuildOnly.map((item)=>{
187 obj[item] = config.entry[item];
188 })
189 config.entry = obj;
190 }
191
192 Object.keys(config.entry).forEach(function (entry) {
193 if (Array.isArray(config.entry[entry])) {
194 config.entry[entry].unshift.apply(config.entry[entry], preEntrys)
195 } else {
196 config.entry[entry] = preEntrys.concat(config.entry[entry])
197 }
198
199 config.plugins.push(new HtmlWebpackPlugin({
200 template: path.join(__dirname, `..${path.sep}template${path.sep}js.ejs`),
201 filename: process.cwd() + `${path.sep}dist_ejs${path.sep}${entry}.js.ejs`,
202 chunks: [entry],
203 inject:false
204 }))
205 config.plugins.push(new HtmlWebpackPlugin({
206 template: path.join(__dirname, `..${path.sep}template${path.sep}css.ejs`),
207 filename:process.cwd() + `${path.sep}dist_ejs${path.sep}${entry}.css.ejs`,
208 chunks: [entry],
209 favicon:webpackConfig.favicon,
210 inject:false
211 }))
212 })
213 if (devServerConfig.hot) {
214 config.module.rules.unshift({
215 test: /\.jsx?$/,
216 use: require.resolve(`react-hot-loader${path.sep}webpack`),
217 exclude: /node_modules/,
218 })
219 config.plugins.push(new webpack.HotModuleReplacementPlugin());
220 }
221 config.devtool = webpackConfig.sourceMap || '';
222}
223
224exports.production = function () {
225 var config = this._default('production')
226 return config
227}
228
229exports.postProduction = function (config, devServerConfig,webpackConfig) {
230 var preEntrys = [];
231 config.output.publicPath = process.env.NODE_ENV === "production" ? webpackConfig.cdnPath : webpackConfig.fatPath;
232 //pro模式加hash
233 config.output.filename = webpackConfig.libs ? '[name].js' : '[name].[chunkhash:6].js'
234 if(webpackConfig.preset === 'ie8'){
235 shimIe8Plugins(config);
236 }
237 config.plugins.unshift(new CleanWebpackPlugin(['dist'], {
238 root: process.cwd(),
239 verbose: true,
240 allowExternal: true
241 }));
242 webpackConfig.libs ? config.plugins.push(new ExtractTextPlugin('[name].css')) : config.plugins.push(new ExtractTextPlugin('[name].[contenthash:6].css'));
243 let tempPath = '';
244 webpackConfig.useTempPath && process.env.NODE_ENV === "production" ? tempPath = 'dist_ejs_temp' : tempPath = 'dist_ejs';
245 Object.keys(config.entry).forEach(function (entry) {
246 if (Array.isArray(config.entry[entry])) {
247 config.entry[entry].unshift.apply(config.entry[entry], preEntrys)
248 } else {
249 config.entry[entry] = preEntrys.concat(config.entry[entry])
250 }
251 if(!webpackConfig.libs){
252 config.plugins.push(new HtmlWebpackPlugin({
253 template: path.join(__dirname, `..${path.sep}template${path.sep}css.ejs`),
254 filename: process.cwd() + `${path.sep}${tempPath}${path.sep}${entry}.css.ejs`,
255 chunks: [entry],
256 favicon:webpackConfig.favicon,
257 inject:false
258 }))
259 config.plugins.push(new HtmlWebpackPlugin({
260 template: path.join(__dirname, `..${path.sep}template${path.sep}js.ejs`),
261 filename: process.cwd() + `${path.sep}${tempPath}${path.sep}${entry}.js.ejs`,
262 chunks: [entry],
263 inject:false
264 }))
265 }
266 });
267}
268
269
270exports.NodeSSR = function () {
271 var config = this._default('NodeSSR')
272 return config;
273}
274
275exports.postNodeSSR = function (config, devServerConfig,webpackConfig) {
276 var serverConfig = this._default('NodeSSR');
277 let preEntrys = [];
278 let nodeServerEntry = webpackConfig.nodeServerEntry;
279 Object.keys(nodeServerEntry).forEach(function (entry) {
280 if (Array.isArray(nodeServerEntry[entry])) {
281 nodeServerEntry[entry].unshift.apply(nodeServerEntry[entry], preEntrys)
282 } else {
283 nodeServerEntry[entry] = preEntrys.concat(nodeServerEntry[entry])
284 }
285 });
286 Object.assign(serverConfig, {
287 entry : nodeServerEntry,
288 output: {
289 path: path.join(process.cwd(), `.${path.sep}dist_server${path.sep}`),
290 filename: "[name].server.js",
291 libraryTarget: 'commonjs2',
292 publicPath:process.env.NODE_ENV === "production" ? webpackConfig.cdnPath : process.env.NODE_ENV === "fat" ? webpackConfig.fatPath : webpackConfig.devPath,
293 },
294 module: {
295 rules: [{
296 test: /\.jsx?$/,
297 use: {
298 loader: require.resolve('babel-loader'),
299 options:{
300 presets: ['react'],
301 plugins: [
302 require.resolve("babel-plugin-transform-decorators-legacy"),
303 require.resolve("babel-plugin-transform-es2015-modules-commonjs"),
304 ]
305 }
306 },
307 include: /(node_modules\/igame_base_libs|src)/
308 },
309 {
310 test: /\.(png|jpg|jpeg|gif)$/,
311 use: require.resolve('url-loader'),
312 },
313 {
314 test: /\.(styl|css)$/,
315 use: 'null-loader'
316 },
317 ]
318 },
319 plugins: [
320 new webpack.ProvidePlugin({
321 React: 'react',
322 ReactDOM: 'react-dom',
323 }),
324 new webpack.DefinePlugin({
325 __IS_SSR__: true,
326 __MODE__:'"node_ssr"'
327 }),
328 ],
329 externals: [nodeExternals({
330 whitelist: ['igame_base_libs']
331 })]
332 });
333 return serverConfig;
334}
335
336function shimIe8Plugins(config) {
337 config.module.rules.unshift({
338 enforce: 'post',
339 test: /\.js$/,
340 use: {
341 loader: require.resolve('es3ify-loader'),
342 },
343 include: /(node_modules\/igame_base_libs|src)/
344 });
345 config.plugins.pop();
346 config.plugins.push(new webpack.optimize.UglifyJsPlugin({
347 compress: {
348 unused: true,
349 drop_console: false,
350 drop_debugger: true,
351 dead_code: true,
352 properties: false,
353 warnings: false,
354 screw_ie8: false,
355 },
356 mangle: false,
357 mangle: {
358 screw_ie8: false
359 },
360 output: {
361 screw_ie8: false
362 },
363 comments: false
364 }))
365}