typescript 项目中用 webpack defineplugin 注入环境变量需三步:webpack 配置用 json.stringify 确保替换合法;补充 env.d.ts 声明 processenv 类型;代码中使用已声明变量并避免未定义分支,配合 mode 实现死代码消除。

在 TypeScript 项目中用 Webpack 的 DefinePlugin 注入全局环境变量,关键不是“让 TypeScript 知道变量存在”,而是确保 Webpack 替换后代码语法合法、TS 编译不报错。这需要三步配合:Webpack 配置注入、类型声明补充、使用方式规范。
Webpack 配置要加 JSON.stringify
DefinePlugin 是编译时静态替换,值必须是字符串字面量形式,否则会生成非法 JS 代码。TypeScript 文件里写的 process.env.API_URL,最终会被替换成字符串,所以配置时一定要用 JSON.stringify 包裹:
-
'process.env.API_URL': JSON.stringify('https://api.example.com')✅ 替换后是"https://api.example.com" -
'process.env.API_URL': '"https://api.example.com"'⚠️ 虽然也能运行,但属于硬编码字符串,不够健壮 -
'process.env.API_URL': 'https://api.example.com'❌ 会变成const url = https://api.example.com;,语法错误
TypeScript 需要补全类型声明
TS 默认不认识 process.env.XXX,直接访问会报 Property 'XXX' does not exist on type 'NodeJS.ProcessEnv'。解决方法是在项目中添加类型声明文件(如 src/env.d.ts):
- 声明扩展
NodeJS.ProcessEnv接口:declare namespace NodeJS { interface ProcessEnv { API_URL: string; NODE_ENV: 'development' | 'production'; } } - 如果定义了自定义变量(如
APP_VERSION),也需一并声明:interface ProcessEnv { APP_VERSION: string; } - 确保该文件被 TS 加载:放在
src下,或在tsconfig.json的include中显式包含
代码中使用要避免未定义分支
DefinePlugin 替换发生在 Webpack 编译阶段,TS 类型检查在前,构建在后。因此写法必须保证:无论变量是否被 DefinePlugin 注入,TS 都能通过,且运行时不会访问未定义属性:
- 推荐写法:
if (process.env.NODE_ENV === 'development') { ... }—— TS 已声明NODE_ENV,且值是字面量联合类型,支持类型收窄 - 避免写法:
if (process.env.DEBUG) { ... }—— 若未在 DefinePlugin 中配置DEBUG,构建后该分支仍存在,但值为undefined,可能引发逻辑错误 - 安全取值:
const apiUrl = process.env.API_URL || '';或用非空断言(仅当你 100% 确保它一定被注入):process.env.API_URL!
配合 mode 实现自动死代码消除
Webpack 的 mode: 'production' 会启用 Terser 插件,默认识别 process.env.NODE_ENV === 'development' 这类常量判断并移除整个 if 块。前提是:
- DefinePlugin 明确注入了
'process.env.NODE_ENV': JSON.stringify('production') - TypeScript 声明中
NODE_ENV是字面量类型(如'development' | 'production'),而非string - 不要在条件中拼错字符串,比如写成
'dev'—— 构建后无法匹配,分支不会被删除










