ESM模块TypeScript项目能否省略tsconfig的--alwaysStrict配置
结论速览
纯标准ESM项目移除alwaysStrict不会导致运行时严格模式失效,但存在静态检查漏过严格模式语法错误的隐性风险;绝大多数场景下保留这个配置的成本极低,还能覆盖不少边缘case,没必要特意移除。
移除alwaysStrict的实际风险
你提到的ESM默认启用严格模式是符合规范的事实:只要编译产物是作为标准ES模块被加载(比如package.json固定"type": "module"、运行环境完全符合ES2015+ ESM规范),不管文件顶部有没有"use strict"指令,运行时都会默认开启严格模式,这部分不会出问题。
但很多人会忽略alwaysStrict的两层作用:
- 编译输出层:给生成的JS文件顶部插入
"use strict";指令 - 静态检查层:让TSC在编译阶段就按照严格模式的语法规则做校验,直接拦截
with关键字、未声明变量赋值、arguments.callee这类严格模式下非法的写法
如果你直接关掉alwaysStrict,第二层的静态校验会失效。这些非法写法不会在编译阶段报错,会直接流到产物里,虽然ESM运行时还是会抛错,但等于把本可以在开发阶段发现的问题拖到了运行时,这是最容易踩的隐性坑。
必须保留alwaysStrict的常见场景
以下场景不建议关闭这个配置:
- 双产物输出场景:项目同时编译输出ESM和CommonJS两种格式的产物,CJS模块不会默认开启严格模式,插入的
"use strict"指令是CJS侧严格模式生效的必要条件,否则会出现ESM和CJS侧运行时行为不一致的问题。 - 库类项目:你没法完全控制下游用户的使用方式,极端场景下可能有人把你的ESM产物拼接成普通脚本、用不符合规范的旧加载器运行,顶部的
"use strict"可以兜底保证严格模式生效,避免非预期行为。 - 模块类型混合的项目:代码库内同时存在ESM、CJS两种类型的TS文件(比如混用
.mts/.cts后缀、或部分文件被识别为无模块的脚本文件),开启alwaysStrict可以保证所有文件统一按严格模式做检查和输出,不会出现部分文件跑在非严格模式下的不一致问题。
实际上绝大多数开源ESM项目保留这个配置,本质是算过投入产出比:多输出一行十几个字符的指令对包体积的影响几乎可以忽略,却能兜住很多边缘场景的问题,完全没必要为了“符合ESM不需要手动加use strict”的规范点特意关掉它。
内容的提问来源于stack exchange,提问作者JAYD3V
相关产品推荐
相关产品推荐

