面向浏览器时,如何配置tsconfig.json以支持ES6模块语法?
问题:浏览器环境下TypeScript引入npm包出现
require is not defined错误 我以浏览器为目标环境,用VSCode编写TypeScript并引入npm包Graphemer时,浏览器控制台抛出错误:
Uncaught ReferenceError: require is not defined
详细背景
项目配置(tsconfig.json)
{ "compilerOptions": { "target": "es2016", "module": "ES6", "moduleResolution": "node", "outDir": "./dist", "strict": true, "skipLibCheck": true } }
环境版本
- node v16.17.0
- tsc 4.9.3
- Chrome 111.0.5563.65
操作流程
- 执行
npm i graphemer将包安装至/node_modules目录; - 在main.ts中编写代码:
import Graphemer from "Graphemer"; function test() { const splitter = new Graphemer(); }
- VSCode与TSC编译均无报错,但浏览器控制台弹出上述错误;
- 查看编译后的/dist/main.js文件,发现代码仍使用
require("Graphemer"),而非ES6的import语法。
Graphemer包入口文件内容(/node_modules/Graphemer/lib/index.js)
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const Graphemer_1 = __importDefault(require("./Graphemer")); exports.default = Graphemer_1.default; console.log('exports',exports)
核心疑问
面向浏览器环境时,如何正确配置TSC,使其生成可直接运行的ES6 import/export模块语法代码?
解决方法
1. 调整tsconfig.json配置
修改moduleResolution为bundler(TypeScript 4.7及以上版本支持),同时添加esModuleInterop配置优化模块导入逻辑:
{ "compilerOptions": { "target": "es2016", "module": "ESNext", "moduleResolution": "bundler", "outDir": "./dist", "strict": true, "skipLibCheck": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true } }
moduleResolution: "bundler":告知TypeScript你将使用前端打包工具(如Vite、Rollup),它会按照打包工具的逻辑解析模块,避免生成Node.js特有的require语法;esModuleInterop: true:让TypeScript能正确兼容CommonJS格式的npm包,生成符合ES模块规范的导入代码。
2. 必须使用打包工具
浏览器本身不支持直接加载node_modules中的CommonJS格式包,也无法处理复杂的模块依赖树,因此必须借助打包工具将所有代码和依赖打包为浏览器可识别的文件:
推荐使用Vite(配置简单、启动快速):
- 初始化Vite TypeScript项目:
npm create vite@latest my-ts-project -- --template vanilla-ts - 将你的代码迁移到项目的src目录下,重新安装Graphemer:
npm i graphemer - 启动开发服务器:
npm run dev,此时浏览器即可正常运行代码。
也可以选择Rollup或Webpack,配置对应的TypeScript插件完成打包。
为什么之前的配置无效?
之前设置moduleResolution: node会让TypeScript按照Node.js的模块规则解析依赖,即便module设为ES6,对于CommonJS格式的包,TypeScript仍会生成require调用(默认适配Node.js环境)。而浏览器环境中不存在require函数,因此触发报错。
内容的提问来源于stack exchange,提问作者Vanquished Wombat
相关产品推荐
相关产品推荐

