Навыки фронтенд-разработки SDK, которых вы не знаете

JavaScript TypeScript PWA
Навыки фронтенд-разработки SDK, которых вы не знаете

Автор: Чен Дафу

Аспирант Китайского университета Гонконга, один из авторов книги «Эффективная разработка веб-интерфейса для мобильных устройств», один из переводчиков «Руководства для разработчиков интерфейса 2017», выступал с программными докладами на технических конференциях, таких как China Front. Конференция разработчиков и конференция мезозойских технологий, посвященная новым исследованиям и использованию технологий.

Данная статья является оригинальной статьей, просьба указывать автора и источник для перепечатки

Недавно я занимаюсь рефакторингом SDK внутри компании. Вот краткое изложение некоторого опыта, которым я хочу поделиться с вами.

Проверка типов и intellisense

В качестве SDK наша цель состоит в том, чтобы позволить пользователям сократить время для просмотра документов, поэтому нам нужно предоставить некоторые типы чеков и интеллектуальных подсказок. Как правило, наш подход должен предоставить JSDOC. Большинство редакторов могут обеспечить быстрый способ генерировать JSDOC , Наши более часто используемые VSCode можно использоватьDocument This.

Другой способ - использовать Flow или TypeScript.Основная причина выбора TypeScript заключается в том, что автоматически сгенерированный JsDoc относительно примитивен, и нам все еще нужно его редактировать на нем, поэтому обслуживание JsDoc и разработка кода разделены, и часто происходят обновления кода, и JsDoc забывает об обновленной ситуации.

Кроме того, в процессе разработки мы не можем пользоваться функциями, которые более важны для разработки SDK, такими как проверка типов. TypeScript может помочь нам уменьшить количество ошибок и сократить время отладки. С другой стороны, SDK, разработанный на этот раз, будет перенесен , когда он предоставляется Относительно простое сжатие обеспечивает объем после введения, поэтому вам нужно будет сжать JsDoc, а TypeScript может передать отдельный файл d.ts, установив для объявления значение true в tsconfig.json.

Подсказанный SDK:

Наконец, для студентов-разработчиков, даже если TypeScript не используется, настоятельно рекомендуется использовать vscode для предоставления//@ts-checkАннотация, он проверит правильность вашего кода с помощью некоторого вывода типа, что может уменьшить количество ошибок в процессе разработки.

Еще один трюк: если используемая вами библиотека не поддерживает IntelliSense, вы можете сделать это с помощьюNPM/yarnиз-DУстановить@types/{pkgname}, чтобы вы могли пользоваться умными советами, предоставляемыми vscode в процессе разработки, и-Dустановить наdevDependencies, это не увеличит размер вашего кода во время сборки.

интерфейс

Как упоминалось в TypeScript, чтобы упомянуть синтаксис TypeScript, тип основы не обязательно повторять их, и некоторый прежний высокоуровневый синтаксис ES6 теперь также может поддерживать, не говоря уже о нескольких общих разработчиках JavaScript, не имеющих привычки использовать синтаксис здесь.

Многие люди одержимы использованием any или any по умолчанию, когда они начинают использовать TypeScript.Рекомендуется включить strict и noImplicitAny в tsconfig во время разработки, чтобы гарантировать, что использование any будет минимальным.Вы должны знать, что злоупотребление любым эквивалентно проверке вашего типа и никакого реального эффекта.

Для некоторых типов объектов, содержимое которых временно не может быть определено, можно использовать{[key: string]: any}Вместо того, чтобы использовать any напрямую, вы можете медленно расширять этот интерфейс до тех пор, пока any не будет полностью устранен. В то же время TypeScript поддерживает наследование. В процессе разработки вы можете разобрать интерфейс и использовать комбинированный метод наследования, чтобы уменьшить повторяющиеся определения.

Тем не менее, интерфейс также принесет небольшую боль.В настоящее время интеллектуальное напоминание vscode не может очень хорошо соответствовать интерфейсу.Когда вы вводите соответствующую переменную, хотя она будет выделена, выделенный интерфейс - это только интерфейс с определенным имя. Невозможно напрямую увидеть, что определено в интерфейсе. Но когда вы вводите часть ключа, определенную в интерфейсе, vscode предложит вам ввести полный ключ. Хотя это немного недружественно в процессе разработки, команда разработчиков vscode сказала, что это было преднамеренно разработано, поэтому с точки зрения параметров API вы можете выбрать использование некоторых необходимых (важных) параметров непосредственно с базовым типом и поставить некоторую конфигурацию в объект, определенный как интерфейс.

перечислить

Вы использовали в своем коде:

const Platform = {
    ios: 0,
  	android: 1
}

Затем вы должны использовать перечисления в TypeScript:

enum Platform {
  ios,
  android
}

Таким образом, в функции вы можете установить числовой тип для параметра, а затем передатьPlatform.iosТаким образом, перечисление может повысить удобство сопровождения кода, оно может использовать intellisense, чтобы гарантировать, что вы вводите правильное, не магическое число (магическое число). По сравнению с объектом, он гарантирует тип входных данных (определяемый вами объект может перестать иметь значение типа number в один прекрасный день), и не требуется никакого дополнительного суждения о типе.

декоратор

На самом деле многие разработчики знакомы и не знакомы с декораторами.Сейчас, когда redux и mobx более популярны, очень часто вызывают декораторы в коде, но у большинства разработчиков нет привычки извлекать логику своего кода в декораторы.

Например, при разработке этого SDK нам необходимо предоставить некоторые фасады для совместимости с разными платформами (iOS, Android или Web), и этот фасад позволит разработчикам регистрироваться в виде плагинов, а SDK будет поддерживать введенный объект Обычный способ его использования - оценить среду после использования функции, а затем определить, есть ли плагины, которые вы хотите в объекте, и использовать плагины, если они есть.

С практической точки зрения, вилка является блокиратором, пока мы останавливаем запуск, это может быть реальной функцией, вероятно, логика такова:

export function facade(env: number) {
  return function(
    target: object,
    name: string,
    descriptor: TypedPropertyDescriptor<any>
  ) {
    let originalMethod = descriptor.value;
    let method;

    return {
      ...descriptor,
      value(...args: any[]): any {
        let [arg] = args;
        let { param, success, failure, polyfill } = arg;   // 这部分可以自定义
        if ((method = polyfill[env])) {
          method.use(param, success, failure);
          return;
        }
        originalMethod.apply(this, args);
      }
    };
  };
}

Еще одна вещь, с которой часто приходится сталкиваться при разработке SDK, — это проверка и переинкапсуляция многих параметров, также мы можем использовать декораторы для завершения:

export function snakeParam(
  target: object,
  name: string,
  descriptor: TypedPropertyDescriptor<any>
) {
  let callback = descriptor.value!;

  return {
    ...descriptor,
    value(...args: any[]): any {
      let [arg, ...other] = args;
      arg = convertObjectName(arg, ConvertNameMode.toSnake);
      callback.apply(this, [arg, ...other]);
    }
  };
}÷

общий

Обобщения могут определять вывод на основе пользовательского ввода, самый простой пример:

function identity<T>(arg: T): T {
    return arg;
}

Конечно, это не имеет особого значения, но показывает, что возврат основан на типе аргумента.В общем процессе разработки вы не можете избежать универсального типа, такого как Promise или предыдущий TypedPropertyDescriptor, который требует ввода типа. , Не используйте ничего небрежно, если ваш бэкенд возвращает стандартную структуру, например:

export interface IRes {
  status: number;
  message: string;
  data?: object;
}

Затем вы можете использовать промисы следующим образом:

function example(): Promise<IRes> {
    return new Promise ...
}

Конечно, есть много расширенных приложений дженериков, таких как универсальные ограничения и фабричные функции создания дженериков, которые выходят за рамки этой статьи и могут быть найдены в официальной документации.

Построить

Если ваш инструмент сборки является WebPack, в разработке SDK, попробуйте использовать метод узла для вызова (то есть WebPack.run выполнение), поскольку конструкция SDK часто реагирует на множество различных изменений параметров, а метод узла является более Гибкий, чем метод чистого конфигурации. Чтобы отрегулировать входные и выходные параметры, вы также можете рассмотреть возможность использования Rollup, код сборки ROTUP более ориентирован на программирование.

Следует отметить, что метод модуляризации ES6 можно использовать при построении в Webpack3 и rollup, так что после того, как бизнес-код будет введен в ваш SDK, объем конечного бизнес-кода может быть уменьшен за счет деконструкции введения. предоставьте пакет commonjs, тогда древовидная акула инструмента сборки не вступит в силу.Если вы используете babel, обратите внимание на закрытие компиляции модуля.

Еще один способ уменьшить размер одного пакета, вы можете использоватьlernaПри сборке нескольких NPM-пакетов в git-репозиторий удобнее использовать код общей части, чем разбирать репозиторий, но также необходимо обратить внимание на модификацию кода общей части, чтобы не затрагивать другие пакеты .

На самом деле, для большинства SDK Webpack3 и rollup имеют похожий опыт, а наиболее часто используемые подключаемые модули имеют почти одинаковые имена. Однако у rollup есть два преимущества. Первое состоит в том, что конструкция rollup более совершенна. rollup.rollup принимает inputOptions для создания пакета, а также может генерировать исходную карту и писать для генерирования вывода. В этом процессе мы можем выполнить некоторую детальную работу.

Второй момент заключается в том, что rollup.rollup вернет промис, а это значит, что мы можем использовать асинхронный метод для написания кода сборки, а webpack.run по-прежнему является используемой функцией обратного вызова, хотя разработчики могут инкапсулировать ее в промис, но лично Я думаю, что это все еще роллап. Написание все еще немного круче.

модульный тест

На прошлой неделе мой коллега сделал онлайн-совместное использование. Я обнаружил, что многие студенты очень заинтересованы и смущены в отношении тестирования подразделения. В разделении предельной работы трудно разрабатывать однозначное тестирование для бизнес-кода, связанного с UI, но для SDK, тестирование блока должно быть необходимым и достаточным условием, которое должно быть одобрено. Конечно, я на самом деле не люблю писать один тесты, потому что одиночные тесты часто скучают, но если я не пишу один тесты, я обязательно буду «образован» старыми драйверами ~ _ ~.

Общее использование одного тестаmochaВ качестве тестовой среды,expectВ качестве библиотеки утверждений используйтеnycПредоставьте один отчет об испытаниях, примерный одиночный тест выглядит следующим образом:

describe('xxx api test', function() {			// 注意如果要用this调用mocha,不要用箭头函数
  this.timeout(6000);
  it('xxx', done => {
    SDK.file
      .chooseImage({
        count: 10,
        cancel: () => {
          console.log('选择图片取消----');
        }
      })
      .then(res => {
        console.dir(res);
        expect(res).to.be.an('object');
        expect(res).to.have.keys('ids');
        expect(res.ids).to.be.an('array');
        expect(res.ids).to.have.length.above(0);
        uploadImg(res.ids);
        done();
      });
  });
});

Точно так же вы можете использовать TypeScript для написания модульных тестов.Конечно, в процессе выполнения нет необходимости снова компилировать.Мы можем напрямую зарегистрировать ts-node для прямого выполнения mocha.Подробности см.Пишите тесты для проектов TypeScript с мокко и чаем  на TypeScript!. Но есть одна вещь, которую я должен вам напомнить: старайтесь полагаться на документацию вместо интеллектуальных подсказок при написании модульных тестов, потому что ваш код неверен, это может привести к тому, что ваши интеллектуальные подсказки будут неправильными, а модульные тесты, которые вы пишете, основаны на неправильных умные подсказки тоже должны быть. . .

Для моделирования сетевых запросов вы можете использоватьnockЭта библиотека должна быть добавлена ​​доbeforeEachметод:

describe('proxy', () => {
  beforeEach(() => {
    nock('http://test.com')
      .post('/test1')
      .delay(200)
      .reply(200, {			// body
        test1: 1,
        test2: 2
      }, {
        'server-id': 'test' // header
      });
  });
  it(...
}

Наконец, мы используем скрипт npm, чтобы добавить nyc перед mocha, и мы можем получить наш единственный тестовый отчет.

Здесь я также упоминаю несколько небольших советов по использованию TypeScript для справки.

советы: Как добавить объявления во внутренние библиотеки без выпуска пакетов

Этот SDK в процессе разработки будет зависеть от внутреннего пакета NPM, чтобы позволить NPM поддерживать вызов TypeScript, у нас есть несколько способов:

  • Добавьте файл d.ts в исходный пакет и опубликуйте его.

  • Публикуя пакет @types, следует отметить, что NPM не поддерживает@types/@scope/{pkgname}Если такое письмо является пакетом частной библиотеки, вы можете использовать@types/scope_{pkgname}этот способ написания.

  • На этот раз папка отмечена для хранения соответствующего файла d.ts.Этот метод подходит для разработки.Если вы чувствуете, что написанный вами d.ts не идеален, или этот файл d.ts в настоящее время нужен только этому SDK , Его можно использовать так, измените его в tsconfig.json:

    "baseUrl": "./",
    "paths": {
        "*": ["/type/*"]
    }
    

подсказки: как обрабатывать и отклонять различные типы обратных вызовов обещаний

Отклоненные по умолчанию возвращаемый тип параметра - это любой, не обязательно соответствует нашим потребностям, здесь дают решение, не лучший, как бросающий нефть:

interface IPromise<T, U> {
  then<TResult1 = T, TResult2 = never>(
    onfulfilled?:
      | ((value: T) => TResult1 | PromiseLike<TResult1>)
      | undefined
      | null,
    onrejected?:
      | ((reason: U) => TResult2 | PromiseLike<TResult2>)
      | undefined
      | null
  ): IPromise<TResult1 , TResult2>;
  catch<TResult = never>(
    onrejected?:
      | ((reason: U) => TResult | PromiseLike<TResult>)
      | undefined
      | null
  ): Promise<TResult>;


В 2019 году оригинальная новая книга iKcamp «Практика разработки Koa и Node.js» была продана на JD.com, Tmall, Amazon и Dangdang!

Категории