[vuejs/vue-cli]在vue3.0里面require一段js代码,和其他环境执行结果不一致

2023-12-19 446 views
5
Version

3.7.0

Environment info
"vue": "^2.6.10"
Steps to reproduce

(function () { var l = void 0, aa = this; console.log('this', this); function r(c, d) { var a1112222222222222 = c.split("."); console.log('b', c); };

}).call(this);

(function () { var l = void 0, aa = this; console.log('this', this); function r(c, d) { var a1112222222222222; console.log('b', c); };

}).call(this); 分别require上面两段代码 a1112222222222222 赋值之后输出thisundefined

What is expected?

都是{}

What is actually happening?

undefined

回答

8

image image

3

这个问题要解释起来的话……很复杂。请问有实际的应用场景吗?有的话我可以针对性地给一下建议。

7

我在FBXLoader.js里面require inflate.min.js 因为undefined导致代码不能正常运行,换之前的cli就没问题

6

根源是这样的: 我们配置了 @babel/preset-envuseBuiltIns 选项为 usage (https://babeljs.io/docs/en/babel-preset-env#usebuiltins) 它检测到你代码中用了 .split String.prototype.split 在 ES6+ 中有增加新的特性,需要用到 es6.regexp.split 这个 polyfill 所以它默认给你的代码加了一句 import "core-js/modules/es6.regexp.split";


至于为什么这里是 import 不是 require,则是有这几个原因

  1. 我们配置了 modules: false 选项,默认 babel 不进行模块转换,webpack 直接处理 ES module,这样可以进行 tree shaking,打包后代码体积最小
  2. 你的模块代码里面只有一个自执行的函数,没有任何 import / export,理论上这是一个 ambiguous module,任何编译器都无法判断这究竟该是一个 CommonJS module 还是 ES Module,不管 babel 实际实现如何,默认 import 是完全合理的。

然后 ES module 默认是 strict mode,顶层 this 为 undefined CommonJS 默认是 sloppy mode,顶层 this 为 exports 对象

3

解决办法就是不要用 babel 编译这个文件

两个方式:

  1. 改 babel.config.js,加上这个字段:ignore: ['./path/to/inflate.min.js']
  2. 改 webpack 配置,
    config.module.rule('js').exclude.add('/absolute/path/to/infalte.min.js')

其实理论上 .min.js 都应该来源于 node_modules 文件夹,所以默认不应该被编译的……

9

这不是bug吧,严格模式下this就会是undefined啊,你可以在你代码外面在包一层 (function() { "use strict"; (function () { var l = void 0, aa = this; console.log('this', this); function r(c, d) { var a1112222222222222 = c.split("."); console.log('b', c); };

}).call(this);

}())