@hcfy/js-to-mjs
v1.1.0
Published
`tsc -m ESNext` 输出的虽然是 es module 文件,但是:
Downloads
22
Readme
js-to-mjs
tsc -m ESNext
输出的虽然是 es module 文件,但是:
- 文件后缀仍然是
.js
- 文件内的模块导入没有加上完整的文件后缀,比如应该用
import './utils.mjs'
而不是import './utils'
而 js-to-mjs 的作用就是:将 .js
文件重命名为 .mjs
文件,并给文件内的相对路径的模块加入完整的文件扩展名。
使用示例
首先安装 @hcfy/js-to-mjs:
npm i -D @hcfy/js-to-mjs
然后参考下方的 package.json:
{
"type": "commonjs",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
}
},
"scripts": {
"build:mjs": "tsc --outDir dist -m ESNext --moduleResolution bundler -d && js-to-mjs dist",
"build:cjs": "tsc --outDir dist -m NodeNext --moduleResolution NodeNext",
"build": "npm run build:mjs && npm run build:cjs",
"dev": "nodemon --watch src -e ts,tsx,js --exec \"npm run build\""
}
}
如果你使用的是 TypeScript 5.2.0 以下的版本,那么 build:mjs
和 build:cjs
可以用下面这种写法,但是这个写法在 5.2.0 以后会报错,见 TypeScript 5.2.0 的说明
{
"scripts": {
"build:mjs": "tsc --outDir dist -m ESNext --moduleResolution NodeNext -d && js-to-mjs dist",
"build:cjs": "tsc --outDir dist -m CommonJS --moduleResolution NodeNext"
}
}
以上示例中:
build:mjs
用来输出 ESM 和 *.d.ts 文件,其中使用了 js-to-mjs 对 tsc 输出的 .js 文件做了处理。build:cjs
用来输出 CommonJS 文件,注意其中没有-d
参数,这是因为在build:mjs
中已经输出了 *.d.ts。build
用来组合上面两个命令。注意顺序,build:mjs
要先执行。dev
用来在文件变更之后自动 build。由于tsc --watch
不提供执行命令的钩子,所以改为用 nodemon 来监听文件变化并执行 build 命令。
注意事项
js-to-mjs 只会处理相对路径的模块,即以 '.' 开头的模块导入路径:
import '../utils'
// 会变成
import '../utils.mjs'
但 node_modules 里的 submodule 是不会处理的,比如:
// 下面的导入语句不会改变
import isEqual from 'lodash/isEqual'
这种情况,你需要自行在 .ts 文件里加上后缀,即 import isEqual from 'lodash/isEqual.js'
全部的转换规则
// 非相对路径的模块:不会改变
import React from 'react'
// 以 / 结尾的模块:
// 如果 utils/index.js 文件存在,则会变成 './utils/index.mjs',否则不会改变
import utils from './utils/'
// 不是以 / 结尾的模块:
// 如果 ../runSth.js 文件存在,则变为 '../runSth.mjs';
// 如果 ../runSth/index.js 存在,则变成 '../runSth/index.mjs';
// 如果都不存在则不会改变
import '../runSth'