| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 | /*	MIT License http://www.opensource.org/licenses/mit-license.php	Author Tobias Koppers @sokra*/"use strict";const NodeStuffInWebError = require("./NodeStuffInWebError");const RuntimeGlobals = require("./RuntimeGlobals");const CachedConstDependency = require("./dependencies/CachedConstDependency");const ConstDependency = require("./dependencies/ConstDependency");const {	evaluateToString,	expressionIsUnsupported} = require("./javascript/JavascriptParserHelpers");const { relative } = require("./util/fs");const { parseResource } = require("./util/identifier");/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource *//** @typedef {import("./Compiler")} Compiler *//** @typedef {import("./Dependency")} Dependency *//** @typedef {import("./DependencyTemplates")} DependencyTemplates *//** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */class NodeStuffPlugin {	constructor(options) {		this.options = options;	}	/**	 * Apply the plugin	 * @param {Compiler} compiler the compiler instance	 * @returns {void}	 */	apply(compiler) {		const options = this.options;		compiler.hooks.compilation.tap(			"NodeStuffPlugin",			(compilation, { normalModuleFactory }) => {				const handler = (parser, parserOptions) => {					if (parserOptions.node === false) return;					let localOptions = options;					if (parserOptions.node) {						localOptions = { ...localOptions, ...parserOptions.node };					}					if (localOptions.global !== false) {						const withWarning = localOptions.global === "warn";						parser.hooks.expression							.for("global")							.tap("NodeStuffPlugin", expr => {								const dep = new ConstDependency(									RuntimeGlobals.global,									expr.range,									[RuntimeGlobals.global]								);								dep.loc = expr.loc;								parser.state.module.addPresentationalDependency(dep);								// TODO webpack 6 remove								if (withWarning) {									parser.state.module.addWarning(										new NodeStuffInWebError(											dep.loc,											"global",											"The global namespace object is a Node.js feature and isn't available in browsers."										)									);								}							});						parser.hooks.rename.for("global").tap("NodeStuffPlugin", expr => {							const dep = new ConstDependency(								RuntimeGlobals.global,								expr.range,								[RuntimeGlobals.global]							);							dep.loc = expr.loc;							parser.state.module.addPresentationalDependency(dep);							return false;						});					}					const setModuleConstant = (expressionName, fn, warning) => {						parser.hooks.expression							.for(expressionName)							.tap("NodeStuffPlugin", expr => {								const dep = new CachedConstDependency(									JSON.stringify(fn(parser.state.module)),									expr.range,									expressionName								);								dep.loc = expr.loc;								parser.state.module.addPresentationalDependency(dep);								// TODO webpack 6 remove								if (warning) {									parser.state.module.addWarning(										new NodeStuffInWebError(dep.loc, expressionName, warning)									);								}								return true;							});					};					const setConstant = (expressionName, value, warning) =>						setModuleConstant(expressionName, () => value, warning);					const context = compiler.context;					if (localOptions.__filename) {						switch (localOptions.__filename) {							case "mock":								setConstant("__filename", "/index.js");								break;							case "warn-mock":								setConstant(									"__filename",									"/index.js",									"__filename is a Node.js feature and isn't available in browsers."								);								break;							case true:								setModuleConstant("__filename", module =>									relative(compiler.inputFileSystem, context, module.resource)								);								break;						}						parser.hooks.evaluateIdentifier							.for("__filename")							.tap("NodeStuffPlugin", expr => {								if (!parser.state.module) return;								const resource = parseResource(parser.state.module.resource);								return evaluateToString(resource.path)(expr);							});					}					if (localOptions.__dirname) {						switch (localOptions.__dirname) {							case "mock":								setConstant("__dirname", "/");								break;							case "warn-mock":								setConstant(									"__dirname",									"/",									"__dirname is a Node.js feature and isn't available in browsers."								);								break;							case true:								setModuleConstant("__dirname", module =>									relative(compiler.inputFileSystem, context, module.context)								);								break;						}						parser.hooks.evaluateIdentifier							.for("__dirname")							.tap("NodeStuffPlugin", expr => {								if (!parser.state.module) return;								return evaluateToString(parser.state.module.context)(expr);							});					}					parser.hooks.expression						.for("require.extensions")						.tap(							"NodeStuffPlugin",							expressionIsUnsupported(								parser,								"require.extensions is not supported by webpack. Use a loader instead."							)						);				};				normalModuleFactory.hooks.parser					.for("javascript/auto")					.tap("NodeStuffPlugin", handler);				normalModuleFactory.hooks.parser					.for("javascript/dynamic")					.tap("NodeStuffPlugin", handler);			}		);	}}module.exports = NodeStuffPlugin;
 |