Условный импорт peerDependency в es6

Я работаю над библиотекой 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: Условные и динамические операторы импорта)? И можно ли проверить существование модуля без его импорта (в основном, как isModuleDefined() метод?)

Я тоже видел эти:

Имя импорта переменной ES6 в node.js?

Как я могу условно импортировать модуль ES6?

Но, как мы в настоящее время используем babel если эта архитектура возможна, она может вызвать проблемы компиляции в других инструментах сборки, таких как webpack, gulp, grunt так далее.?

0 ответов

Другие вопросы по тегам