ReactJS. вынос компоненты из директории src

Рейтинг: 1Ответов: 1Опубликовано: 31.07.2023
// project/site/package.json:
"my-comp": "file: ./../../utilites/slick"

// project/site/src/App.js
import {Slick} from "my-comp/Slick"

// project/utilites/slick/Slick.js
// UPD 1: это просто мой файл с компонентом, а не полноценный npm пакет
export function Slick () {
    return test123
}

Имеем:
проект на ReactJS, в нем естественно package.json, есть файл который импортирует компоненту вне проекта, и это все работает.
Однако, если function Slick переписать под const Slick ( чтобы наслаждаться синтаксисом компонент ), то все падает

// project/utilites/slick/Slick.js
// Support for the experimental syntax 'jsx' isn't currently enabled..
export const Slick = () => {
    return <div>test123</div>
}

Может кто помочь советом, желательно подробным, что в моём коде поправить, или, есть ли какой то другой способ импорта компоненты?

p.s. гуглил , и по теме уже много перекопал, но натыкаюсь на проекты которые выдают ошибки при установке, или нет достаточного описания что делать, или идут какие то правки в jest/ts_config, которых нету у меня в проекте

UPD 2: есть видос на ютубе от индуса, про вынос компоненты выше директории src, но там придётся прописывать абсолютный путь к компоненту, что наверно прикольно для видео, но не для реального проекта

UPD 3: уточню, еще немного. импортировать не из директории проекта JS, я могу, и что бы избавить всех от Гугления (вдруг кому понадобится), выше привел полные URL. а вот если возвращать JSX ( о чем я и написал - ошибка ) и вот советы, как настроить проект, что бы он позволял делать импорт компонент с JSX - непонятно

Ответы

▲ 1Принят

Немного предположений:

Ваше приложение создано с помощью create-react-app и при этом не сделан eject проекта, поэтому невозможно простым способом изменить настройки Webpack и Babel.

Я пишу ответ именно для этого случая - когда не хочется делать eject проекта.
В противном случае нужно сделать eject и конфигурировать Webpack на возможность импорта файлов из директории вне корня проекта и вложенных в него папок.

Следует учитывать, что создатели Webpack не рекомендуют делать импорты вне корня проекта, так как это может привести к увеличению размера конечной сборки и дублированию использованных пакетов NodeJS.


Кратко об источнике проблемы:

При сборке проекта Webpack не применяет плагины Babel к файлам, которые находятся вне корня проекта, поэтому jsx в таких файлах не транспилируется в JavaScript.


Используем Craco для решения проблемы:

Craco (Create React App Configuration Override) - инструмент для изменения конфигурации проекта, созданного с помощью create-react-app. Позволяет менять конфигурации Style, ESLint, Babel, TypeScript, Webpack, Jest, Devserver.

Для демонстрации создадим новый проект:

npx create-react-app test

Далее установим Craco и плагин для него react-app-alias-ex:

cd test
npm install @craco/craco --save
npm install react-app-alias-ex --save-dev 

В файле package.json в разделе scripts заменим react-scripts на craco

"start": "craco start",
"build": "craco build",
"test":  "craco test",

В корне проекта создадим файл craco.config.js с содержимым:

const { CracoAliasPlugin } = require( 'react-app-alias-ex' );

module.exports = {
  plugins: [
    {
      plugin: CracoAliasPlugin,
      options: {}
    }
  ]
}

В корне проекта создадим файл jsconfig.paths.json с содержимым:

{
    "compilerOptions": {
      "paths": {
        "widgets/*": ["d:/dev/projects/mycomp/*"]
      }
    }
}

В корне проекта создадим файл jsconfig.json с содержимым:

{
    "extends": "./jsconfig.paths.json",
    "compilerOptions": {
    }
}

В файле src/App.js импортируем желаемый файл:

import { Slick } from 'widgets/Slick';
// ...
Learn React { Slick() }

P.S. Все описанные действия и конфигурации взяты из документации к Craco, тестировал на своей машине - всё работает.

P.P.S. Данный ответ не был бы возможен без статьи на Хабре, потому что когда я пытался решить Вашу проблему в день, когда Вы его задали - гугл упорно не выдавал мне никакой информации о Craco и это при том, что я сразу понимал откуда растёт корень проблемы, а эта статья вышла спустя 2 дня после Вашего вопроса.
Удачно совпало.