Skip to content

[Bug report]webpack ≥ 5.10x 时 dev 模式下 setup 页面 data 恒为空:global 被编译为字面量 globalThis,被产物头部 var globalThis = {} 胶水遮蔽,currentInject 跨文件交接断裂 #2579

Description

@keke599

环境

  • @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

复现步骤

  1. 新建或使用任意带 setup() 页面的 MPX 项目
  2. 重装依赖使 webpack 解析到 ≥5.110(lockfile 未入库或手动 npm update webpack)
  3. 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.(好)。

修复建议(任一)

  1. processChunk 注入胶水时感知 output.environment.globalThis(该开关开启时字面量会被遮蔽);
  2. 或在插件内自动设置 output.environment.globalThis = false;
  3. 或在文档中标注 webpack ≥5.110 需要此配置。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions