Webpack node、output.jsonpFunction 配置详解

本文详细解析了Webpack中的node配置项,包括node.global、node.__filename和node.__dirname等,以及output.jsonpFunction配置在Webpack4和Webpack5中的应用。文章通过实例展示了如何避免全局变量污染,理解其工作原理,并给出了在Webpack5中去除jsonpFunction配置的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Webpack node、output.jsonpFunction 配置详解

最近尝试给一些用到 webpack 的项目升级到最新 webpack5 版本,其中遇到了一些问题,我挑了两个比较典型的问题,其中主要涉及到了 webpacknode 属性跟 output.jsonpFunction (webpack5 以前版本)属性,下面我们结合 webpack 的源码来分析一下这两个属性。

开始

这里使用的 webpack 版本为:

  • webpack@^4.46.0
  • webpack@^5.88.2

首先我们创建一个 webpack4 的项目:

webpack-node1:

mkdir webpack-node2 && cd webpack-node2 && npm init -y

接着安装 webpack4

npm install -D webpack@4.46.0 webpack-cli@4.10.0

创建创建一个 src/index.js 入口文件:

mkdir src && touch src/index.js

在项目根目录 webpack-node1 目录下创建一个 webpack 配置文件 webpack.config.js

cd .. && touch webpack.config.js
// webpack.config.js
module.exports = {
   
    output: {
   
        publicPath: "./dist/",
    },
    devtool: false, // 关闭 source-map 功能
};

ok,我们在项目根目录 webpack-node1 下执行一下 webpack 打包命令看效果:

 npx webpack build --mode=development

在这里插入图片描述

可以看到,因为我们的入口文件 src/index.js 是一个空文件,所以打包后的 dist/main.js 文件除了一些 webpack 的辅助函数外,入口文件里面为空。

最后我们创建一个 test.html 文件来测试:

touch test.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>webpack4</title>
    <script src="./dist/main.js"></script>
</head>
<body>

</body>
</html>

ok,项目我们就创建完了,接下来我们看一下 webpack.node 配置。

Node 配置

我们先看一下 webpack官网 对它的介绍:

这些选项可以配置是否 polyfill 或 mock 某些 Node.js 全局变量

此功能由 webpack 内部的 NodeStuffPlugin 插件提供。

Warning

从 webpack 5 开始,你只能在 node 选项下配置 global__filename__dirname。如果需要在 webpack 5 下的 Node.js 中填充 fs,请查阅 resolve.fallback 获取相关帮助。

node

boolean: false` `object

webpack.config.js

module.exports = {
    
  //...
  node: {
    
    global: false,
    __filename: false,
    __dirname: false,
  },
};

从 webpack 3.0.0 开始,node 选项可能被设置为 false,以完全关闭 NodeStuffPlugin 插件。

node.global

boolean` `'warn'
Tip

如果你正在使用一个需要全局变量的模块,请使用 ProvidePlugin 替代 global

关于此对象的准确行为,请查看Node.js 文档

选项:

  • true: 提供 polyfill.
  • false: 不提供任何 polyfill。代码可能会出现 ReferenceError 的崩溃。
  • 'warn': 当使用 global 时展示一个警告。

node.__filename

boolean` `'mock' | 'warn-mock' | 'eval-only'

选项:

  • true: 输入文件的文件名,是相对于 context 选项
  • false: webpack 不会更改 __filename 的代码。在 Node.js 环境中运行时,文件的文件名。
  • 'mock': value 填充为 'index.js'
  • 'warn-mock': 使用 '/index.js' 但是会展示一个警告。
  • 'eval-only'

node.__dirname

boolean` `'mock' | 'warn-mock' | 'eval-only'

选项:

  • true: 输入 文件的目录名,是相对于 context 选项
  • false: webpack 不会更改 __dirname 的代码,这意味着你有常规 Node.js 中的 __dirname 的行为。在 Node.js 环境中运行时,输出 文件的目录名。
  • 'mock': value 填充为 '/'
  • 'warn-mock': 使用 '/' 但是会显示一个警告。
  • 'eval-only'

以上是 webpack5node 配置的描述。

webpack4

ok,看完了官网的描述,我们来用一下这个 node 配置。

我们修改一下 src/index.js 文件:

// 判断是浏览器环境
const isBrowser = process.browser; // 使用 nodejs 的 process 对象
console.log(isBrowser);
console.log(__dirname); // 使用 nodejs 的 __dirname 全局属性
console.log(global); // 使用 nodejs 全局对象 global

我们重新执行打包命令看效果:

npx webpack build --mode=development

浏览器打开 test.html 文件:

在这里插入图片描述

可以看到,即使是 nodejs 环境中的变量,我们在浏览器中仍然可以访问,这是为什么呢?

因为 webpack 提前给我们注入了这些 nodejs 的全局变量,我们来找一下 webpack4 的源码。

node_modules/webpack/lib/node/NodeSourcePlugin.js

/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
"use strict";
const AliasPlugin = require("enhanced-resolve/lib/AliasPlugin");
const ParserHelpers = require("../ParserHelpers");
const nodeLibsBrowser = require("node-libs-browser");

module.exports = class NodeSourcePlugin {
   
	constructor(options) {
   
		this.options = options;
	}
	apply(compiler) {
   
		const options = this.options;
    // 当 webpack.node 配置为 false 的时候关闭该插件
		if (options === false) {
   
			// allow single kill switch to turn off this plugin
			return;
		}
		// 获取 nodepollyfill 的依赖地址
		const getPathToModule = (module, type) => {
   
      // 配置成 true 的话就去找到对应的 pollyfill 库
			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];
      // 配置成 mock 就简单模拟一下
			} else if (type === "mock") {
   
				return require.resolve(`node-libs-browser/mock/${
     module}`);
      // 配置成 empty 就返回 undeifned
			} else if (type === "empty") {
   
				return require.resolve("node-libs-browser/mock/empty");
			} else {
   
				return module;
			}
		};
    
    // 修改变量为依赖引入
		const addExpression = (
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值