| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2017-05-07 02:41:26 +08:00
										 |  |  | "use strict"; | 
					
						
							|  |  |  | const AliasPlugin = require("enhanced-resolve/lib/AliasPlugin"); | 
					
						
							|  |  |  | const ParserHelpers = require("../ParserHelpers"); | 
					
						
							|  |  |  | const nodeLibsBrowser = require("node-libs-browser"); | 
					
						
							| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-07 02:41:26 +08:00
										 |  |  | module.exports = class NodeSourcePlugin { | 
					
						
							|  |  |  | 	constructor(options) { | 
					
						
							|  |  |  | 		this.options = options; | 
					
						
							| 
									
										
										
										
											2014-03-19 05:34:35 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-05-07 02:41:26 +08:00
										 |  |  | 	apply(compiler) { | 
					
						
							| 
									
										
										
										
											2017-05-07 04:16:50 +08:00
										 |  |  | 		const options = this.options; | 
					
						
							| 
									
										
										
										
											2017-06-02 07:47:43 +08:00
										 |  |  | 		if(options === false) // allow single kill switch to turn off this plugin
 | 
					
						
							|  |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2016-11-12 01:42:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		const getPathToModule = (module, type) => { | 
					
						
							| 
									
										
										
										
											2017-05-07 02:41:26 +08:00
										 |  |  | 			if(type === true || (type === undefined && nodeLibsBrowser[module])) { | 
					
						
							|  |  |  | 				if(!nodeLibsBrowser[module]) throw new Error(`No browser version for node.js core module ${module} available`); | 
					
						
							|  |  |  | 				return nodeLibsBrowser[module]; | 
					
						
							|  |  |  | 			} else if(type === "mock") { | 
					
						
							|  |  |  | 				return require.resolve(`node-libs-browser/mock/${module}`); | 
					
						
							|  |  |  | 			} else if(type === "empty") { | 
					
						
							|  |  |  | 				return require.resolve("node-libs-browser/mock/empty"); | 
					
						
							|  |  |  | 			} else return module; | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2016-11-23 00:58:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		const addExpression = (parser, name, module, type, suffix) => { | 
					
						
							| 
									
										
										
										
											2017-05-07 02:41:26 +08:00
										 |  |  | 			suffix = suffix || ""; | 
					
						
							| 
									
										
										
										
											2017-12-19 21:35:30 +08:00
										 |  |  | 			parser.hooks.expression.for(name).tap("NodeSourcePlugin", () => { | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 				if(parser.state.module && parser.state.module.resource === getPathToModule(module, type)) return; | 
					
						
							|  |  |  | 				const mockModule = ParserHelpers.requireFileAsExpression(parser.state.module.context, getPathToModule(module, type)); | 
					
						
							|  |  |  | 				return ParserHelpers.addParsedVariableToModule(parser, name, mockModule + suffix); | 
					
						
							| 
									
										
										
										
											2017-05-07 02:41:26 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-06 22:01:25 +08:00
										 |  |  | 		compiler.hooks.compilation.tap("NodeSourcePlugin", (compilation, { | 
					
						
							|  |  |  | 			normalModuleFactory | 
					
						
							|  |  |  | 		}) => { | 
					
						
							| 
									
										
										
										
											2017-12-14 17:22:27 +08:00
										 |  |  | 			const handler = (parser, parserOptions) => { | 
					
						
							| 
									
										
										
										
											2017-05-07 02:41:26 +08:00
										 |  |  | 				if(parserOptions.node === false) | 
					
						
							|  |  |  | 					return; | 
					
						
							| 
									
										
										
										
											2016-09-14 18:04:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-07 02:41:26 +08:00
										 |  |  | 				let localOptions = options; | 
					
						
							|  |  |  | 				if(parserOptions.node) | 
					
						
							|  |  |  | 					localOptions = Object.assign({}, localOptions, parserOptions.node); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if(localOptions.global) { | 
					
						
							| 
									
										
										
										
											2017-12-19 21:35:30 +08:00
										 |  |  | 					parser.hooks.expression.for("global").tap("NodeSourcePlugin", () => { | 
					
						
							| 
									
										
										
										
											2017-11-08 18:32:05 +08:00
										 |  |  | 						const retrieveGlobalModule = ParserHelpers.requireFileAsExpression(parser.state.module.context, require.resolve("../../buildin/global.js")); | 
					
						
							|  |  |  | 						return ParserHelpers.addParsedVariableToModule(parser, "global", retrieveGlobalModule); | 
					
						
							| 
									
										
										
										
											2017-05-07 02:41:26 +08:00
										 |  |  | 					}); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if(localOptions.process) { | 
					
						
							| 
									
										
										
										
											2017-05-07 04:16:50 +08:00
										 |  |  | 					const processType = localOptions.process; | 
					
						
							| 
									
										
										
										
											2017-05-07 02:41:26 +08:00
										 |  |  | 					addExpression(parser, "process", "process", processType); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if(localOptions.console) { | 
					
						
							| 
									
										
										
										
											2017-05-07 04:16:50 +08:00
										 |  |  | 					const consoleType = localOptions.console; | 
					
						
							| 
									
										
										
										
											2017-05-07 02:41:26 +08:00
										 |  |  | 					addExpression(parser, "console", "console", consoleType); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-05-07 04:16:50 +08:00
										 |  |  | 				const bufferType = localOptions.Buffer; | 
					
						
							| 
									
										
										
										
											2017-05-07 02:41:26 +08:00
										 |  |  | 				if(bufferType) { | 
					
						
							|  |  |  | 					addExpression(parser, "Buffer", "buffer", bufferType, ".Buffer"); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if(localOptions.setImmediate) { | 
					
						
							| 
									
										
										
										
											2017-05-07 04:16:50 +08:00
										 |  |  | 					const setImmediateType = localOptions.setImmediate; | 
					
						
							| 
									
										
										
										
											2017-05-07 02:41:26 +08:00
										 |  |  | 					addExpression(parser, "setImmediate", "timers", setImmediateType, ".setImmediate"); | 
					
						
							|  |  |  | 					addExpression(parser, "clearImmediate", "timers", setImmediateType, ".clearImmediate"); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-12-14 17:22:27 +08:00
										 |  |  | 			}; | 
					
						
							|  |  |  | 			normalModuleFactory.hooks.parser.for("javascript/auto").tap("NodeSourcePlugin", handler); | 
					
						
							|  |  |  | 			normalModuleFactory.hooks.parser.for("javascript/dynamic").tap("NodeSourcePlugin", handler); | 
					
						
							|  |  |  | 			normalModuleFactory.hooks.parser.for("javascript/esm").tap("NodeSourcePlugin", handler); | 
					
						
							| 
									
										
										
										
											2015-01-07 01:20:45 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-12-06 22:01:25 +08:00
										 |  |  | 		compiler.hooks.afterResolvers.tap("NodeSourcePlugin", (compiler) => { | 
					
						
							| 
									
										
										
										
											2017-05-07 02:41:26 +08:00
										 |  |  | 			Object.keys(nodeLibsBrowser).forEach((lib) => { | 
					
						
							|  |  |  | 				if(options[lib] !== false) { | 
					
						
							| 
									
										
										
										
											2017-12-20 16:53:33 +08:00
										 |  |  | 					compiler.resolverFactory.hooks.resolver.for("normal").tap("NodeSourcePlugin", resolver => { | 
					
						
							| 
									
										
										
										
											2017-05-07 02:41:26 +08:00
										 |  |  | 						new AliasPlugin("described-resolve", { | 
					
						
							|  |  |  | 							name: lib, | 
					
						
							|  |  |  | 							onlyModule: true, | 
					
						
							|  |  |  | 							alias: getPathToModule(lib, options[lib]) | 
					
						
							| 
									
										
										
										
											2017-12-20 16:53:33 +08:00
										 |  |  | 						}, "resolve").apply(resolver); | 
					
						
							|  |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2017-05-07 02:41:26 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2013-02-26 20:31:05 +08:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-05-07 02:41:26 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-22 03:25:25 +08:00
										 |  |  | }; |