如何解决Rollupjs提示‘"this"已被重写为"undefined"’的问题?
解决Rollup构建时"this"被重写为"undefined"的警告
我在开发一个同时兼容浏览器和Node.js的库时,执行pnpm install && pnpm build出现了警告:"this" has been rewritten to "undefined"。排查后发现问题出在tslib生成的代码中,编译器无法识别this的值,因此将其替换为undefined。
可复现环境
- Node.js: v18.16.0
- pnpm: 8.5.1
- TypeScript: 5.0.4
- Rollup: v3.22.0
项目文件
package.json
{ "name": "rollup-test", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "build": "rollup -c rollup.config.js" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "fp-ts": "^2.15.0" }, "devDependencies": { "@rollup/plugin-node-resolve": "^15.0.2", "@rollup/plugin-typescript": "^11.1.1", "tslib": "^2.5.2" } }
rollup.config.js
const typescript = require('@rollup/plugin-typescript'); const { nodeResolve } = require('@rollup/plugin-node-resolve'); module.exports = [ { input: 'src/index.ts', output: { file: 'dist/index.cjs.js', format: 'cjs' }, plugins: [ nodeResolve(), typescript() ] } ];
src/index.ts
import * as E from 'fp-ts/Either' function mylog(str: string) { const x = E.right(str) if (E.isLeft(x)) { console.log(x.left) } else { console.log(x.right) } } mylog('hi')
构建输出
执行pnpm build后的输出:
> rollup-test@1.0.0 build /Users/theuser/Desktop/rollup-test > rollup -c rollup.config.js src/index.ts → dist/index.cjs.js... (!) "this" has been rewritten to "undefined" https://rollupjs.org/troubleshooting/#error-this-is-undefined node_modules/.pnpm/fp-ts@2.15.0/node_modules/fp-ts/es6/function.js 1: var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { ^ 2: if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { 3: if (ar || !(i in from)) { ...and 1 other occurrence node_modules/.pnpm/fp-ts@2.15.0/node_modules/fp-ts/es6/internal.js 1: var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { ^ 2: if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { 3: if (ar || !(i in from)) { ...and 1 other occurrence created dist/index.cjs.js in 369ms
解决方案
这个警告源于Rollup处理ES模块时,默认将顶层this设为undefined,而fp-ts的ES6代码中用this检测内置的__spreadArray方法。以下是几种修复方式:
方法1:配置Rollup的context选项
修改rollup.config.js的output部分,添加context: 'globalThis',让顶层this指向全局对象(浏览器的window、Node.js的globalThis):
module.exports = [ { input: 'src/index.ts', output: { file: 'dist/index.cjs.js', format: 'cjs', context: 'globalThis' // 添加该行 }, plugins: [ nodeResolve(), typescript() ] } ];
方法2:使用@rollup/plugin-commonjs处理模块特性
先安装插件:
pnpm add -D @rollup/plugin-commonjs
再修改rollup.config.js引入并启用插件:
const typescript = require('@rollup/plugin-typescript'); const { nodeResolve } = require('@rollup/plugin-node-resolve'); const commonjs = require('@rollup/plugin-commonjs'); // 引入插件 module.exports = [ { input: 'src/index.ts', output: { file: 'dist/index.cjs.js', format: 'cjs' }, plugins: [ nodeResolve(), commonjs(), // 添加该行 typescript() ] } ];
方法3:调整TypeScript编译配置
新建或修改tsconfig.json,设置更高的编译目标,减少tslib生成依赖this的辅助函数:
{ "compilerOptions": { "target": "ES2020", "module": "ESNext", "lib": ["ES2020", "DOM"], "useDefineForClassFields": true, "moduleResolution": "Node", "strict": true, "skipLibCheck": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "outDir": "./dist", "declaration": true }, "include": ["src/**/*"] }
内容的提问来源于stack exchange,提问作者Shnd
相关产品推荐
相关产品推荐

