| 
									
										
										
										
											2013-09-13 17:17:57 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | "use strict"; | 
					
						
							| 
									
										
										
										
											2013-09-13 17:17:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | const ConstDependency = require("./dependencies/ConstDependency"); | 
					
						
							|  |  |  | const BasicEvaluatedExpression = require("./BasicEvaluatedExpression"); | 
					
						
							| 
									
										
										
										
											2017-01-09 02:11:26 +08:00
										 |  |  | const ParserHelpers = require("./ParserHelpers"); | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | const NullFactory = require("./NullFactory"); | 
					
						
							| 
									
										
										
										
											2014-06-16 21:18:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | class DefinePlugin { | 
					
						
							|  |  |  | 	constructor(definitions) { | 
					
						
							|  |  |  | 		this.definitions = definitions; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 	apply(compiler) { | 
					
						
							| 
									
										
										
										
											2017-02-05 07:22:33 +08:00
										 |  |  | 		const definitions = this.definitions; | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 		compiler.plugin("compilation", (compilation, params) => { | 
					
						
							|  |  |  | 			compilation.dependencyFactories.set(ConstDependency, new NullFactory()); | 
					
						
							|  |  |  | 			compilation.dependencyTemplates.set(ConstDependency, new ConstDependency.Template()); | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 			params.normalModuleFactory.plugin("parser", (parser) => { | 
					
						
							|  |  |  | 				(function walkDefinitions(definitions, prefix) { | 
					
						
							|  |  |  | 					Object.keys(definitions).forEach((key) => { | 
					
						
							| 
									
										
										
										
											2017-02-05 07:22:33 +08:00
										 |  |  | 						const code = definitions[key]; | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 						if(code && typeof code === "object" && !(code instanceof RegExp)) { | 
					
						
							|  |  |  | 							walkDefinitions(code, prefix + key + "."); | 
					
						
							|  |  |  | 							applyObjectDefine(prefix + key, code); | 
					
						
							|  |  |  | 							return; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						applyDefineKey(prefix, key); | 
					
						
							|  |  |  | 						applyDefine(prefix + key, code); | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 				}(definitions, "")); | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 				function stringifyObj(obj) { | 
					
						
							| 
									
										
										
										
											2017-01-26 07:17:31 +08:00
										 |  |  | 					return "__webpack_require__.i({" + Object.keys(obj).map((key) => { | 
					
						
							| 
									
										
										
										
											2017-02-05 07:22:33 +08:00
										 |  |  | 						const code = obj[key]; | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 						return JSON.stringify(key) + ":" + toCode(code); | 
					
						
							| 
									
										
										
										
											2017-01-18 21:39:26 +08:00
										 |  |  | 					}).join(",") + "})"; | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 				function toCode(code) { | 
					
						
							|  |  |  | 					if(code === null) return "null"; | 
					
						
							|  |  |  | 					else if(code === undefined) return "undefined"; | 
					
						
							|  |  |  | 					else if(code instanceof RegExp && code.toString) return code.toString(); | 
					
						
							|  |  |  | 					else if(typeof code === "function" && code.toString) return "(" + code.toString() + ")"; | 
					
						
							|  |  |  | 					else if(typeof code === "object") return stringifyObj(code); | 
					
						
							|  |  |  | 					else return code + ""; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 				function applyDefineKey(prefix, key) { | 
					
						
							|  |  |  | 					const splittedKey = key.split("."); | 
					
						
							|  |  |  | 					splittedKey.slice(1).forEach((_, i) => { | 
					
						
							|  |  |  | 						const fullKey = prefix + splittedKey.slice(0, i + 1).join("."); | 
					
						
							| 
									
										
										
										
											2017-01-11 20:11:42 +08:00
										 |  |  | 						parser.plugin("can-rename " + fullKey, ParserHelpers.approve); | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				function applyDefine(key, code) { | 
					
						
							| 
									
										
										
										
											2017-02-05 07:22:33 +08:00
										 |  |  | 					const isTypeof = /^typeof\s+/.test(key); | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 					if(isTypeof) key = key.replace(/^typeof\s+/, ""); | 
					
						
							| 
									
										
										
										
											2017-02-06 18:40:35 +08:00
										 |  |  | 					let recurse = false; | 
					
						
							|  |  |  | 					let recurseTypeof = false; | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 					code = toCode(code); | 
					
						
							|  |  |  | 					if(!isTypeof) { | 
					
						
							| 
									
										
										
										
											2017-01-11 20:11:42 +08:00
										 |  |  | 						parser.plugin("can-rename " + key, ParserHelpers.approve); | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 						parser.plugin("evaluate Identifier " + key, (expr) => { | 
					
						
							| 
									
										
										
										
											2017-02-06 18:40:35 +08:00
										 |  |  | 							if(recurse) return; | 
					
						
							| 
									
										
										
										
											2017-02-06 18:41:49 +08:00
										 |  |  | 							recurse = true; | 
					
						
							| 
									
										
										
										
											2017-02-05 07:22:33 +08:00
										 |  |  | 							const res = parser.evaluate(code); | 
					
						
							| 
									
										
										
										
											2017-02-06 18:40:35 +08:00
										 |  |  | 							recurse = false; | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 							res.setRange(expr.range); | 
					
						
							|  |  |  | 							return res; | 
					
						
							|  |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2017-01-08 20:46:29 +08:00
										 |  |  | 						parser.plugin("expression " + key, ParserHelpers.toConstantDependency(code)); | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-02-05 07:22:33 +08:00
										 |  |  | 					const typeofCode = isTypeof ? code : "typeof (" + code + ")"; | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 					parser.plugin("evaluate typeof " + key, (expr) => { | 
					
						
							| 
									
										
										
										
											2017-02-06 18:40:35 +08:00
										 |  |  | 						if(recurseTypeof) return; | 
					
						
							| 
									
										
										
										
											2017-02-06 18:41:49 +08:00
										 |  |  | 						recurseTypeof = true; | 
					
						
							| 
									
										
										
										
											2017-02-05 07:22:33 +08:00
										 |  |  | 						const res = parser.evaluate(typeofCode); | 
					
						
							| 
									
										
										
										
											2017-02-06 18:40:35 +08:00
										 |  |  | 						recurseTypeof = false; | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 						res.setRange(expr.range); | 
					
						
							|  |  |  | 						return res; | 
					
						
							|  |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 					parser.plugin("typeof " + key, (expr) => { | 
					
						
							| 
									
										
										
										
											2017-02-05 07:22:33 +08:00
										 |  |  | 						const res = parser.evaluate(typeofCode); | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 						if(!res.isString()) return; | 
					
						
							| 
									
										
										
										
											2017-01-08 20:46:29 +08:00
										 |  |  | 						return ParserHelpers.toConstantDependency(JSON.stringify(res.string)).bind(parser)(expr); | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 					}); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 				function applyObjectDefine(key, obj) { | 
					
						
							| 
									
										
										
										
											2017-02-05 07:22:33 +08:00
										 |  |  | 					const code = stringifyObj(obj); | 
					
						
							| 
									
										
										
										
											2017-01-11 20:11:42 +08:00
										 |  |  | 					parser.plugin("can-rename " + key, ParserHelpers.approve); | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 					parser.plugin("evaluate Identifier " + key, (expr) => new BasicEvaluatedExpression().setRange(expr.range)); | 
					
						
							| 
									
										
										
										
											2017-01-09 02:11:26 +08:00
										 |  |  | 					parser.plugin("evaluate typeof " + key, ParserHelpers.evaluateToString("object")); | 
					
						
							| 
									
										
										
										
											2017-01-08 20:46:29 +08:00
										 |  |  | 					parser.plugin("expression " + key, ParserHelpers.toConstantDependency(code)); | 
					
						
							|  |  |  | 					parser.plugin("typeof " + key, ParserHelpers.toConstantDependency(JSON.stringify("object"))); | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2013-09-24 21:07:55 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2016-12-31 00:34:29 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | module.exports = DefinePlugin; |