Pull to refresh
9
0
Эдуард Щавелев @edward_nsk

Разработчик: C#, SQL

Send message
Спасибо за пример. Хорошая заготовка.
Приложение даже запустилось без проблем.
Только версии NPM-пакетов очень старые.
Подтягивание dot.net core до версии 2.1 прошло нормально.
Но перейти на свежий webpack не получилось — не хватает образования.
Попытка подтянуть версию Vue.js тоже сходу не проходит (ошибки компиляции TypeScript).
Официальный стайл-гайд требует, чтобы для фреймворка явно описывались типы свойств компонента. У вас — массив. Исправляем, делаем явно — и получаем дубликат описаний, то есть еще хуже.

Массив использовать опасно ещё по одной причине — у компилятора TypeScript частично отключается контроль типов.


Теоретически оба варианта определения props, которые приведены ниже, должны работать одинаково. И это действительно так. Даже получаемый на выходе JavaScript код одинаковый.


...
export default Vue.extend({
    template: '#demo-grid-template',
    props: ['rows', 'columns', 'filterKey'],
    //props: { rows: Array, columns: Array, filterKey: String },
    ...
});

Но обнаруживается неприятный баг-фича в тайпинге Vue.js.


Если props определены как массив, то для компилятора TypeScript перечисленные свойства становятся легальными.
Например, компилятор спокойно скушает использование this.filterKey.
Перечисленные в props свойства даже в IntelliSense появляются при использовании VS2017.


А если определить props явно с указанием типов, то компилятор будет материться на тот же this.filterKey.


Вот такой баг-фича.

Меня тоже не устраивает описанный мной вариант для использования в продакшн. Только для тестирования и прототипирования.

В продакшн используем декоратор vue-class-component.
Про TSX и ангруляр ничего не скажу.

К этому ещё можно добавить Razor-рендеринг в приложениях Asp.Net Core MVC.
Razor-синтаксис позволяет жестко связать модель и представление.
Но здесь одно лечат, другое — калечат.

Полностью с вами согласен. Имя автора ничего не гарантирует. Но зато, при сильных наездах, легче отмазаться :).


Насчет "явно не TypeScript":


Образец на vuejs.org, куда вы ссылаетесь — лохматого года, и явно не Typescript. Вы его портируете, и остальные лохматости оставляете как есть.

И я про тоже самое говорю:


На широких просторах Интернета можно найти массу качественных примеров и готовых приложений, использующих Vue.js. Но подавляющее большинство этих примеров написано на JavaScript.

Зачастую, при попытке причесать "лохматости" что-нибудь отваливалось. Поэтому я и стараюсь оставлять "как есть".

Кстати, первый пример, который я использую в этой статье, тоже практически официальный.
Переход с официального сайта typescriptlang.org, выбрать Vue.js.
Автор примера: DanielRosenwasser — Program Manager of TypeScript.


Развве может он писать на TypeScript криво?

При написании tutotial я не ставил себе задачу написать идеальный пример.
Я выбрал официальный пример известного автора: Evan You.
Затем постарался минимизировать изменения в исходном коде.
Чтобы не потерять узнаваемость.
Так что: "так вообще писать нельзя" — это к автору :).


Что касается кривости кода — посмотрите на цитаты от создателя Vue.js в начале статьи. В них содержится ответ.
Vue.js изначально был плохо заточен под TypeScript.
Например, дублирование определений props неизбежно даже при использовании vue-class-component.
Поэтому и приходится использовать "костыли".
Есть варианты "костылей", которые выглядят получше, чем использованный мной.


Описанный мной вариант с интерфейсами, мне лично, экономит массу времени и нервов при изучении потрохов самого Vue.js, а также "чужих" компонент, которые я подбираю для использования в своих приложениях.
Обычно сам пример мне не нужен, поэтому тратиться на него нет смысла.
Главное — быстро заставить работать подходящий пример использования "нужной" компоненты.
А потом ставишь точки остановки и шаришься по коду "нужной" компоненты и Vue.js.


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


Всё зависит от поставленных целей.

Надежная связь между ts-кодом компоненты и его представленим (шаблоном) — это частный случай общей проблемы поддержания взаимосвязей между моделью и представлением.

Например, те же проблемы есть в приложениях WPF или XamarinForms. XAML-файлы представления тоже можно ненароком сломать. И здесь тоже определенные ошибки проявятся только в рантайм.

На 100% эту проблему никто ещё не решил нормально. Поэтому рефакторинг объектов, которые участвуют в биндинге — везде вызывает затруднения.

На уровне привязки ts-кода Vue-компоненты к его шаблону особых проблем нет.
Обычно это решается соглашением по именам (для AppGrid templateId=«app-grid-template», для DemoGrid templateId=«demo-grid-template»).

На уровне привязки (биндинга) атрибутов компоненты к определенным элементам представления, естественно можно нарваться на ошибки в рантайм.

Тут только грамотное тестирование сможет помочь. По-моему, Vue.js ругается вполне осмысленно в случае отсутствия нужных тэгов или сломанного биндинга.

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

Вариант с интерфейсами удобен, когда не сам проектируешь компоненты, а сдираешь чужой js-код.
Кроме того, бывает полезно видеть результат компиляции из TypeScript в JavaScript без посредников. Декоратор несколько искажает картину.
На всякий случай уточняю, что «esModuleInterop» появился в версии TypeScript 2.7. На ноуте не обновился и некоторое время не мог понять, почему работавшее приложение вдруг перестало собираться.

Спасибо автору за сий труд. Для меня лично, многое стало понятнее, после ответа на этот вопрос:


В: Тони Хор (Tony Hoare) назвал null ошибкой на миллиард долларов. Какое было самое неудачное техническое решение в твоей карьере?
O: Было бы неплохо использовать TypeScript изначально, еще когда я начал переписывать код для Vue 2.x.

Может Vue.js 3.0 уже будет на TypeScript при примеру Angular?

Спасибо за полезный пример.


Если поддерживаете свой репозиторий на github в актуальном состоянии, то надо немного подправить hello.ts.


Компилятор TypeScript, вероятно, стал более привередливым и ругается на неинициализированную переменную message. Всё работает после модификации private message!: string;.

В статью внесено дополнение под заголовком UPD 01.03.2018 с учетом предложенного решения @mayorovp.


Также все необходимые изменения внесены в решение VS2017 на github.

Сработало! Спасибо!
Проект с amd-модулями работает без заплатки и через SystemJS, и через RequireJS. В файлах TypeScript ничего менять не надо, достаточно поменять tsconfig.json:


{
  "compilerOptions": {
    "sourceMap": true,
    "target": "es5",
    "strict": true,
    "module": "amd",
    "outFile": "wwwroot/dist/main.js",
    "moduleResolution": "node",
    "esModuleInterop": true
  },
  "include": [
    "./ClientApp/**/*.ts"
  ]
}

Заплатку можно убирать. Получается зря гланды вырывал не через то место.

Компилятор, вроде, берет родные тайпинги здесь: «node_modules/vue/types/index». Если надо что-то добавить — я готов попробовать.

Может есть ссылка на работающий пример с TypeScript для случая: import * as Vue from «vue»?
RequireJS, гад такой, вообще отказался vue.esm.js переваривать:
vue.esm.js:10809 Uncaught SyntaxError: Unexpected token export
Спасибо. Попробую поковырять этот вариант.

Хотя «в лоб» не проходит, при выполнении ошибка:
Uncaught (in promise) Error: Unable to dynamically transpile ES module

A loader plugin needs to be configured via `SystemJS.config({ transpiler: 'transpiler-module' })`.

Instantiating cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.esm.js
Попробовал import * as Vue from «vue»;
Компилятор TS выдает ошибки.
Может подскажете, что ещё подкрутить?

TryVue D:\Git\starter-vue\TryVue\ClientApp\index.ts 5
Ошибка TS2351 Build: Невозможно использовать new с выражением, у типа которого нет сигнатуры вызова или конструктора.

TryVue D:\Git\starter-vue\TryVue\ClientApp\components\Hello.ts 4
Ошибка TS2339 Build: Свойство «extend» не существует в типе «typeof „D:/Git/starter-vue/TryVue/node_modules/vue/types/index“».

Толстый node_modules для деплоя не нужен, в приведенном примере используется только для сборки. Всё необходимое в рантайм тащится по ссылкам CDN: vue.js, jquery.js, system.js. Деплой можно делать визардом vs2017.
Спасибо, посмотрю.
1

Information

Rating
Does not participate
Location
Новосибирск, Новосибирская обл., Россия
Registered
Activity