我正在开发一个本地化日期(以及其他类型和对象)的 JavaScript i18n 库。
它当前依赖于moment.js
,它被定义为 peerDependency (本地化是功能之一但不是唯一的,它可能不会被使用)
// package.json
{
"name": "my-i18n-library",
// ...
"scripts": {
// ...
"clean": "rimraf build",
"build": "babel src -d build",
"prepare": "npm run clean && npm run build"
},
"peerDependency": {
"moment": "~2.20.1",
"date-fns": "~1.29.0"
},
// ...
}
// .babelrc
{
"presets": ["env", "stage-1", "react"]
}
基本上类似于(更防错但我简化了逻辑):
import Moment from 'moment.js'
import 'moment/min/locales'
class Localizer {
localizeDate(value, locale, displayFormat = "L", parseFormat = "LTS") {
return Moment(date, parseFormat, locale).format(displayFormat);
}
}
问题是,如果moment.js
它是一个好作品,它就像一个背包的石头,你不会把它带到 50 英里的小路上,特别是如果你只需要在整个应用程序中本地化一个日期。带宽方面,IMO 不值得(实际上在很多人看来也是如此)。
所以我正在考虑切换到更轻的库,例如date-fns
,但我想出了一个我认为更好的选择:如果我们可以让另一个库选择最适合他的库怎么办?
我正在考虑定义与库相关的本地化程序的不同实现,并根据安装的 peerDependency 有条件地导入它们:
// /Date/DateFnsLocalizer.js
import { parse } from 'date-fns/parse'
import { format } from 'date-fns/format'
class DateFnsLocalizer {
localizeDate(value, locale, displayFormat = "L") {
return format(parse(date), displayFormat, { locale })
}
}
这在 JavaScript 中是否可行?
// /Localizer.js
if (isModuleDefined('moment.js')) {
import BaseLocalizer from './Date/MomentLocalizer'
} else if (isModuleDefined('date-fns')) {
import BaseLocalizer './Date/DateFnsLocalizer'
} else if (isModuleDefined('some-other-lib')) {
import BaseLocalizer './Date/SomeOtherLibLocalizer'
} else {
throw new Error('No date library defined! Please install at least one of ["moment.js", "date-fns", "some-other-lib"]')
}
export default class Localizer extends BaseLocalizer
我认为“导入”语句必须作为文件中的第一条语句。也许require
改用...(如ES6: Conditional & Dynamic Import Statements中所建议)?是否可以在不导入模块的情况下测试模块的存在(基本上如何编写该isModuleDefined()
方法?)
我也看过那些:
但是由于我们目前正在使用babel
编译这个库,如果这个架构是可能的,它会不会在其他构建工具中造成编译问题,例如webpack
,gulp
等grunt
?