前言
当TS 使用 ES6
模块化标准,而编译目标使用 CommonJs
时,导入模块时出现问题。
//tsconfig.json
{
"compilerOptions":{
"target": "es2016", //配置编译目标代码的版本标准
"module": "CommonJS", //配置编译目标使用的模块化标准
}
}
抛出问题
//index.ts
import fs from "fs"; //在这里是会报一个错的 **Module '"fs"' has no default export** 意思是 fs 模块没有默认导出
fs.readFileSync("/");
编译后的js
//index.js
Object.defineProperty(exports, "__esModule", { value: true }); //这一行忽略,不讨论
const fs_1 = require("fs");
fs_1.default.readFileSync("/");
分析
在TS中,我们是想调用fs模块暴露出来的 readFileSync
方法,而编译后的 js 是:导入 fs 模块并赋值给 fs_1
变量,再调用 fs_1
的 default
属性的 readFileSync
结果,而 fs
模块并么没有 default
属性。
解决
方法三最便捷
方法一(很繁琐)
使用 具名 导出
//ts
import { readFileSync } from "fs";
readFileSync("/");
//编译后的代码
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = require("fs");
(0, fs_1.readFileSync)("/");
方法二
导出全部重命名
import * as fs from "fs";
fs.readFileSync("/");
//编译后的代码
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
fs.readFileSync("/");
方法三(使用配置一步搞定)
配置 tsconfig.json
esModuleInterop
属性
{
"compilerOptions":{
"target": "es2016",
"module": "CommonJS",
"esModuleInterop":true, //启用 es 模块化交互非 es 模块导出
}
}
//ts
import fs from "fs";
fs.readFileSync("/");
//编译后的文件
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
fs_1.default.readFileSync("/");