Мы разрабатываем надстройку для Excel с использованием ReactJs + UI Fabric React. Это приложение уже работает в производственной среде, но в нашей дорожной карте продукта есть новые функции. Мы начали использовать Office UI Fabric React 6, который не поддерживал TypeScript, но в этом году был выпущен Fabric React 7 и TypeScript теперь поддерживается! 🚀😂🤩

Для нас это хорошие и плохие новости. Мы хотели интегрировать новую версию из-за улучшений и стабильности, но наша кодовая база немного велика. Мы планируем перенести все на TypeScript, но у нас нет на это времени. Я провел небольшое исследование и подумал, что мы можем сделать, чтобы мы могли хотя бы подготовиться к будущей миграции, но в то же время по-прежнему работать над новыми (ожидающими) функциями 😵🥶. У нас есть еще одно приложение на JavaScript, которое мы хотим перенести, так что сейчас отличный момент для экспериментов.

Приложение Excel Addin, которое мы использовали в качестве отправной точки, было создано с помощью классического create-react-app, которое мы перенесли react-scripts в версию 3.2.0 в соответствии с официальной документацией.

Переход на последнюю версию create-react-app не составит труда, если вы не внесли серьезных изменений. Вам почти нужно обновить package.json, повторно запустить yarn start или react-scripts start и следовать советам.

Теперь давайте приступим к переносу нашей кодовой базы на TypeScript (конечно, постепенно 😉), но прежде, чем мы сможем начать, сначала сохраните свои изменения, пожалуйста😇.

Структура и пакеты проекта

Наша текущая структура проекта аналогична этой (это значение по умолчанию для create-react-app).

src/
    //ALL JS+JSX FILES
.gitignore
package.json

Первый шаг - создать папку с именем assets внутри src папки, сюда мы собираемся переместить любой css или png или любой статический файл, который находится в src корне. Если у вас нет файлов, просто создайте эту папку для будущих изменений.

src/
    assets
    //ALL JS+JSX FILES
.gitignore
package.json

Исправьте ссылки в коде, если вы переместите какой-либо файл в папку assets. После этих изменений скопируйте папку src в папку с именем ts по тому же пути. Внутри ts создайте файл с именем tsconfig.json. Также создайте еще два файла на том же уровне, что и папка ts, эти файлы должны называться tsconfig.build.json и tsconfig.lint.json.

src/
    assets
    //ALL JS+JSX FILES
ts/
    assets
    //ALL JS+JSX FILES
    tsconfig.json
tsconfig.build.json
tsconfig.lint.json
.gitignore
package.json

Теперь нам нужно установить следующие пакеты для интеграции TypeScript:

yarn add typescript tslib 
yarn add --dev @types/node @types/react @types/jest @types/react-dom @types/react-redux

Конфигурация TypeScript

Теперь давайте отредактируем tsconfig.lint.json, добавив в этот файл следующее содержание. Пожалуйста, проверьте, что в outDir мы пишем src, потому что там мы собираемся выводить наши транспилированные файлы, поэтому мы не будем eject наш проект. Также проверьте baseUrl, эта конфигурация позволит нам использовать не относительный импорт в TypeScript. Проверяем include конфигурацию, мы указываем путь к нашим источникам. Наконец, проверьте конфигурацию exclude, в которую мы добавляем src, чтобы централизовать наш код в папке ts. Этот tsconfig.lint.json файл используется для линтинга и проверки файлов .js и .ts.

Этот файл не испускает никакого кода, он используется только для анализа кода.

tsconfig.lint.json

{
    "compilerOptions": {
        "outDir": "src",
        "module": "esnext",
        "target": "ES6",
        "lib": ["es6", "dom"],
        "sourceMap": false,
        "inlineSourceMap": true,
        "allowJs": true,
        "jsx": "preserve",
        "moduleResolution": "node",
        "noImplicitReturns": true,
        "noImplicitThis": true,
        "noImplicitAny": true,
        "strictNullChecks": true,
        "baseUrl": "ts",
        "checkJs": false,
        "resolveJsonModule": true,
        "esModuleInterop": true,
        "skipLibCheck": true,
        "allowSyntheticDefaultImports": true,
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "isolatedModules": true,
        "importHelpers": true
    },
    "include": ["ts"],
    "exclude": ["node_modules", "build", "scripts", "acceptance-tests", "webpack", "jest", "src"],
    "types": []
}

В зависимости от вашей конфигурации вы можете указать jsx значение на preserve, react or react-native. Согласно docs:

TypeScript поставляется с тремя режимами JSX: preserve, react и react-native. Эти режимы влияют только на этап испускания - проверка типов не затрагивается. Режим preserve сохраняет JSX как часть вывода для дальнейшего использования на другом этапе преобразования (например, Babel). Кроме того, выходные данные будут иметь расширение .jsx. Режим react будет генерировать React.createElement, не нужно выполнять преобразование JSX перед использованием, и выходные данные будут иметь расширение .js. Режим react-native эквивалентен preserve в том смысле, что в нем хранится весь JSX, но вместо этого выходной файл будет иметь расширение .js.

Давайте отредактируем tsconfig.build.json, добавив в этот файл следующее содержание. Убедитесь, что мы расширяемся с tsconfig.lint.json, чтобы повторно использовать уже написанную конфигурацию. Этот файл используется для генерации кода, поэтому здесь мы снова указываем include, но только для .ts files, остальные файлы будут скопированы практически без каких-либо изменений, за исключением sourcemaps.

tsconfig.build.json

{
    "extends": "./tsconfig.lint.json",
    "include": ["ts/**/*.ts", "ts/**/*.tsx"]
}

Наконец, давайте отредактируем ts/tsconfig.json. Этот файл, как мы уже сказали, находится внутри папки ts.

Этот файл также используется для обмана VSCode, поэтому, когда мы откроем наш проект, он будет полностью проанализирован. Если вы используете другую среду IDE, проверьте свои требования.

ts / tsconfig.json

{
    "extends": "../tsconfig.lint.json"
}

Очистка и бег

Удалите все файлы и папки в src, кроме папки assets. Затем измените ваш .gitignore файл (если необходимо), чтобы игнорировать перенесенные файлы.

src/**/*.js
src/**/*.json

Теперь, чтобы транспилировать наш код, запустите в консоли следующую команду:

yarn tsc --project tsconfig.build.json --watch

А затем запустите свой проект, как обычно, например (используя yarn или react-scripts в зависимости от вашей конфигурации):

yarn start

Откройте свой сайт и убедитесь, что все работает нормально, и все.

Тестирование

Вы можете добавить компонент, чтобы просто убедиться, что файлы tsx работают, например: давайте создадим, например, файл в ts/components с именем tsx-test.tsx.

src/
    assets
    //ALL JS+JSX FILES
ts/
    components/
        tsx-test.tsx    //just for testing purposes 😅
    assets
    //ALL JS+JSX FILES
    tsconfig.json
tsconfig.build.json
tsconfig.lint.json
.gitignore
package.json

Напишите это содержание:

TS / компоненты / tsx-test.tsx

import React from "react";
class TsxProps {}
function TsxTest(props: TsxProps) {
    return <div>Hello from TS and JS project</div>;
}
export default TsxTest;

И добавьте на любую страницу или представление, которое у вас есть. Он будет правильно переведен и принят react-scripts:

VSCode

Вы можете построить свой проект в VSCode как стандартную задачу. Вы можете добавить или изменить свою задачу сборки в VSCode (tasks.json), чтобы включить наш новый профиль:

.vscode / tasks.json

{
    "version": "2.0.0",
    "command": "gulp",
    "isBackground": true,
    "echoCommand": false,
    "type": "shell",
    "windows": {},
    "tasks": [
        {
            "type": "typescript",
            "tsconfig": "tsconfig.build.json",
            "option": "watch",
            "problemMatcher": [
                "$tsc-watch"
            ],
            "group": "build"
        }
    ]
}

Также нам нужно исключить старые файлы из проводника VSCode в settings.json:

.vscode / settings.json

{    
    // ... more stuff ...
    "files.exclude": {
        // ... more files ...
        "src/{[^a],?[^s],??[^s],???[^e],????[^t],?????[^s]}*": true
    },
    // ... more stuff ...
}

Заключительные примечания

✋ Возможно, вам придется внести некоторые незначительные изменения в зависимости от вашего импорта (относительного или не относительного).

👍 Не относительные пути все еще работают! Например, мы можем: импортировать TsxTest из «components / tsx-test»;

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

Вот и все, ребята! Обратная связь приветствуется. Давай продолжим учиться.