环境
- @mpxjs/core 2.10.19 / @mpxjs/webpack-plugin 2.10.19(已复核最新 2.11.1 源码同样存在)
- @mpxjs/mpx-cli-service 2.2.16 / @mpxjs/vue-cli-plugin-mpx
- webpack 5.110.3(问题在 5.110 引入,5.101.3 正常;webpack 声明支持范围 ^5.75.0 内)
- 目标平台:微信小程序(dev 模式)
- Node 24 / npm 11
复现步骤
- 新建或使用任意带
setup() 页面的 MPX 项目
- 重装依赖使 webpack 解析到 ≥5.110(lockfile 未入库或手动
npm update webpack)
npm run dev 启动,微信开发者工具打开
实际表现
- 所有
createPage({ setup() {...} }) 页面 data 恒为 {}:模板绑定全部为空,事件绑定全部失效
- 控制台无任何报错
npm run build(生产模式)完全正常,极难定位
期望表现
dev 与 build 行为一致,setup 返回的数据正常注入页面。
根因分析
1. webpack 5.110 行为变化(webpack/lib/NodeStuffPlugin.js):
// 5.110:environment.globalThis 为 true(默认)时,`global` 被替换为字面量
const getGlobalDep = (expr) => {
if (compilation.outputOptions.environment.globalThis) {
return new ConstDependency("globalThis", expr.range);
}
return new ConstDependency(RuntimeGlobals.global, expr.range, [RuntimeGlobals.global]);
};
5.101.3 中 global 一律编译为 RuntimeGlobals.global(__webpack_require__.g,运行时解析为真实全局对象,不受局部声明遮蔽);5.110 起改为字面量 globalThis。
2. 与 mpx webpack-plugin 的 chunk 胶水冲突(@mpxjs/webpack-plugin/lib/index.js processChunk,约 :1815):
source.add(`\nvar ${globalObject} = {};\n`)
dev 模式下 globalObject 为 webpack 默认值 globalThis,即每个产物文件(bundle.js、每个页面 chunk)头部都被注入 var globalThis = {};。
3. 遮蔽导致交接断裂:loader 生成的 global.currentCtor / global.currentInject(@mpxjs/webpack-plugin/lib/loader.js :228 附近)被 1 编译为字面量 globalThis.xxx,写入的是本文件局部 shadow 对象;而 @mpxjs/core 的 transferOptions.js 在 bundle.js 中读取 globalThis.currentInject(同样读 bundle 自己的 shadow)。页面写、bundle 读,对象不是同一个 → currentInject 永远拿不到 → 页面 data 恒为 {}。
4. 为什么 build 正常:生产 + optimizeSize 时插件把 globalObject 重命名为 'g'(:389-395),shadow 变成无害的 var g = {},真实 globalThis 未被遮蔽。
临时解法
项目 mpx.config.js 中关闭该开关,使 webpack 退回 __webpack_require__.g 编译方式(单例、跨文件共享,不受胶水影响),已在 webpack 5.110.3 上验证 dev/build 均恢复正常:
export default {
configureWebpack: {
output: {
environment: {
globalThis: false
}
}
}
}
修复后产物特征:dist/wx/bundle.js 中 currentInject 的前缀从 globalThis.(坏)变为 __webpack_require__.g.(好)。
修复建议(任一)
- processChunk 注入胶水时感知
output.environment.globalThis(该开关开启时字面量会被遮蔽);
- 或在插件内自动设置
output.environment.globalThis = false;
- 或在文档中标注 webpack ≥5.110 需要此配置。
环境
复现步骤
setup()页面的 MPX 项目npm update webpack)npm run dev启动,微信开发者工具打开实际表现
createPage({ setup() {...} })页面 data 恒为{}:模板绑定全部为空,事件绑定全部失效npm run build(生产模式)完全正常,极难定位期望表现
dev 与 build 行为一致,setup 返回的数据正常注入页面。
根因分析
1. webpack 5.110 行为变化(
webpack/lib/NodeStuffPlugin.js):5.101.3 中
global一律编译为RuntimeGlobals.global(__webpack_require__.g,运行时解析为真实全局对象,不受局部声明遮蔽);5.110 起改为字面量globalThis。2. 与 mpx webpack-plugin 的 chunk 胶水冲突(
@mpxjs/webpack-plugin/lib/index.jsprocessChunk,约 :1815):dev 模式下
globalObject为 webpack 默认值globalThis,即每个产物文件(bundle.js、每个页面 chunk)头部都被注入var globalThis = {};。3. 遮蔽导致交接断裂:loader 生成的
global.currentCtor/global.currentInject(@mpxjs/webpack-plugin/lib/loader.js :228 附近)被 1 编译为字面量globalThis.xxx,写入的是本文件局部 shadow 对象;而@mpxjs/core的 transferOptions.js 在 bundle.js 中读取globalThis.currentInject(同样读 bundle 自己的 shadow)。页面写、bundle 读,对象不是同一个 →currentInject永远拿不到 → 页面 data 恒为{}。4. 为什么 build 正常:生产 + optimizeSize 时插件把
globalObject重命名为'g'(:389-395),shadow 变成无害的var g = {},真实globalThis未被遮蔽。临时解法
项目
mpx.config.js中关闭该开关,使 webpack 退回__webpack_require__.g编译方式(单例、跨文件共享,不受胶水影响),已在 webpack 5.110.3 上验证 dev/build 均恢复正常:修复后产物特征:
dist/wx/bundle.js中 currentInject 的前缀从globalThis.(坏)变为__webpack_require__.g.(好)。修复建议(任一)
output.environment.globalThis(该开关开启时字面量会被遮蔽);output.environment.globalThis = false;