Рабочие пространства NPM с Expo и Typescript
Я пытаюсь использовать рабочие области NPM 7 в проекте Typescript Expo. На данный момент я хочу сохранить обычную структуру Expo (с корневым
App.tsx
файл), но я хочу изолировать некоторые части кода в рабочих областях.
У меня проблемы с компиляцией кода TS в рабочих областях. Я пробовал много всего, чтобы настроить конфигурации TS и / или Webpack, но безуспешно. Итак, вот минимальная файловая структура для ее воспроизведения:
package.json
tsconfig.json
App.tsx
/packages
/core
index.ts
package.json
Вот соответствующая часть корня
./package.json
{
"main": "node_modules/expo/AppEntry.js",
"workspaces": [
"packages/*"
],
"scripts": {...},
"dependencies": {...},
"devDependencies": {...},
"private": true
}
Это самый минимум
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true
}
}
В
./packages/core/package.json
тоже очень просто
{
"name": "core",
"private": true
}
И
./packages/core/index.ts
просто экспортирует
log()
функция для этого примера
export function log(s: string) {
console.log(s)
}
Наконец, в
./App.tsx
, просто импортирует функцию и пытается вызвать ее
import { log } from 'core'
log('hello')
//...
Не компилируется
Когда я пытаюсь создать для Интернета (с
expo build:web
например) у меня следующая ошибка
✖ Expo Webpack
Compiled with some errors in 1.62s
Failed to compile.
[path]/node_modules/core/index.ts 1:21
Module parse failed: Unexpected token (1:21)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> export function log(s: string) {
| console.log(s)
| }
Я не удивлен, потому что
/node_modules
каталог добровольно исключен.
Итак, мой вопрос: что мне нужно сделать, чтобы скомпилировать код рабочих пространств ? Я бы хотел, чтобы он работал "на лету" (т.е. не был предварительно скомпилирован), как если бы в моем проекте были какие-то обычные файлы. Это вообще выполнимо?
Некоторые неудачные попытки исправить это
В основном я пытался настроить tsconfig, чтобы он работал (хотя мне интересно, меняет ли это что-нибудь)
# 1
Я пробовал добавить
"include": ["./node_modules/core"],
в
./tsconfig.json
. Это не повлияло (та же ошибка).
#2
Я попытался создать следующие
/packages/core/tsconfig.json
с составным вариантом:
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true,
"composite": true
}
}
И сослался на него в корне
tsconfig.json
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true
},
"references": [{ "path": "./node_modules/core" }]
// or even with:
"references": [{ "path": "./packages/core" }]
}
Это не повлияло (та же ошибка).
Большое спасибо
1 ответ
Я придумал решение, которым я не очень доволен, но, по крайней мере, оно работает. На самом деле это довольно просто, я просто настроил Webpack для компиляции моего
packages/*
(как символические ссылки в
node_modules
.
Итак, сначала я установил:
$ npm i -D ts-loader@8 webpack@4.430
Здесь важны версии, чтобы они соответствовали версии веб-пакета, используемой Expo 41.
Я также переименовал свое имя пакета (в
/packages/core/package.json
) на что-то вроде
@workspace/core
так что все мои пользовательские пакеты находятся внутри
node_modules/@workspace
каталог.
Это также упростит нашу конфигурацию.
Бег
$ expo customize:web
необходимо для настройки конфигурации webpack. Это произведет
webpack.config.js
.
Его можно настроить следующим образом:
const createExpoWebpackConfigAsync = require('@expo/webpack-config')
module.exports = async function (env, argv) {
const config = await createExpoWebpackConfigAsync(env, argv)
config.module.rules = [
{
// this is why I renamed my packages with the @workspaces prefix.
test: /node_modules\/@workspaces\/(.*)\.ts$/,
use: [
{
loader: 'ts-loader',
// force ts-loader to compile in node_modules
options: { allowTsInNodeModules: true },
},
],
},
...config.module.rules,
]
return config
}
Не удивлюсь, если найдется более чистое решение. Но пока я буду придерживаться этого