Estoy tratando de compartir el código de TypeScript en una aplicación de creación y reacción en modo de no expulsión, pero me encuentro con la infame restricción de que no se permiten las importaciones fuera de src :
You attempted to import ../../common/src/lib.ts which falls outside of the project src/ directory. [...]
Para el caso que no es de TypeScript, esto se ha preguntado y respondido aquí , pero no puedo obtener ninguna de las soluciones para trabajar con TypeScript. Específicamente, los problemas con las soluciones propuestas son:
Configuración de baseDir en ts-config.json : aquí create-react-app se queja de: la baseUrl de su proyecto solo se puede configurar en src o node_modules . Create React App no admite otros valores en este momento.
Enfoques basados en react-app-rewired: más prometedores. Deshabilitar ModuleScopePlugin me ayuda a superar el error "intento de importación fuera de src", pero el problema ahora es que el cargador de archivos mecanografiados no funciona:
He verificado que el .ts en sí está bien: Copiar a ./src e importarlo desde allí funciona bien.
También agregué la carpeta ../../common/src a la lista de inclusión en ts-config.json includes
Mi suposición es que, de alguna manera, la configuración del cargador de paquetes web tiene una regla que evita que el cargador de TypeScript transpile archivos que no coinciden con los patrones de ruta esperados. ¿Cómo se puede arreglar esto usando react-app-rewired?
La vinculación de fuentes tampoco funciona, nuevamente con el mismo problema. Probablemente porque webpack resuelve internamente los enlaces simbólicos y ve el archivo en una ruta donde no se aplican las reglas normales del cargador.
Soluciones basadas en expulsión: me gustaría no expulsar por ahora, pero lo intenté y básicamente me encuentro con el mismo problema nuevamente.
También encontré otras preguntas que parecían relacionadas pero que no respondían al problema:
La reutilización de tipos de TypeScript en un repositorio mono parece ser un patrón bastante razonable. ¿Me estoy perdiendo algo o por qué la aplicación create-react-hace esto tan difícil?
Para reproducir: mi código es básicamente 100% lo que obtienes de
npx create-react-app my-app --template typescriptcon una importación externa agregada.
ACTUALIZACIÓN : dado que react-app-rewired solo se mantiene de forma pasiva y no es compatible con las versiones 2+ de CRA (estamos tres versiones principales más adelante en el momento de escribir este artículo), ya no recomendaría este enfoque.
Después de más horas de experimentar y leer sobre problemas de GitHub, finalmente tengo una solución que funciona. Muchas gracias a BirukDmitry que hizo esta publicación muy útil en GitHub . Guía paso por paso:
Instalar reaccionar-aplicación-recableado y personalizar-cra
npm i react-app-rewired customize-cra --save-dev Configure react-app-rewird con un config-overrides.js mínimo como este:
const { removeModuleScopePlugin, override, babelInclude } = require("customize-cra"); const path = require("path"); module.exports = override( removeModuleScopePlugin(), // (1) babelInclude([ path.resolve("src"), path.resolve("../common/src"), // (2) ]) );La configuración (1) es similar a lo que se necesita para evitar la limitación de importación fuera de src en general (consulte la pregunta vinculada ).
Sin embargo, la configuración (2) es crucial para habilitar la transpilación de babel (y, por lo tanto, supongo que incluye la extracción de tipo TS) para otras rutas también. Aquí es donde debe agregar las rutas desde las que desea importar.
No se necesitan adaptaciones para tsconfig.json .
Importar utilizando rutas relativas, por ejemplo, import * as mymodule from '../../common/src/mymodule' .
pregunta ¿dónde vive ../../common/src/mymodule ? es otro proyecto? Si es otro proyecto, ¿por qué no los vinculas?
dentro del proyecto de código común ejecute npm link
dentro del proyecto que usará el código común: npm link common-project
Si no hay dos proyectos diferentes. ¿Por qué tiene que estar fuera de src?
El enlace que publicaste La restricción de importaciones create-react-app fuera del directorio src y tu caso/problema son dos cosas totalmente diferentes, además de que se están tropezando mucho. déjame darte una idea de ese problema y el tuyo.
Como ya sabemos, CRA crea una aplicación de página única SPA. lo que significa que solo hay un único archivo html. todo sucede en index.html que se encuentra en <project>/public/index.html . Si compilamos el código, notaremos que el paquete final podría verse así
build --static ----js ----css ----media --index.html --...more hashed crap... public src y por defecto process.env.PUBLIC_URL se establece en "/" ¿QUÉ? 🤨 si mira déjame mostrarte. hay un viejo dicho que una imagen explica más de 1000 palabras. 
si nos fijamos en la imagen que según su ruta se encuentra en ./src/styles/imageSlack.jpg o alguna. Entonces, ¿qué pasa si lo consolamos.
¡¡QUÉ!! donde hacen eso? una cosa que puede hacer para probar mi teoría es si console.log(process.env.PUBLIC_URL) en cualquier parte de su código. ahora aquí está la gran diferencia entre esto y aquello.
Los navegadores de forma nativa no conocen Typescript.
Entonces, configura su código dentro de src y terminamos felices o seguimos el principio de separación de preocupaciones y creamos un paquete npm con el código compartido y lo importamos como cualquier otro módulo.
Puede usar craco (reemplazo de configuración de crear-reaccionar-aplicación) para anular la configuración del paquete web (resumido como parte de CRA) sin expulsar.
Además, podría usar ts-loader para hacer referencia al código ts no transpilado directamente en proyectos externos (por ejemplo, si desea hacer referencia/usar código compartido/lib como parte de un mono-repositorio).
Suponiendo que su aplicación CRA está en el directorio del client , la estructura de su proyecto es como la siguiente:
client/ |--src/ |--package.json shared/ |--package.json |--(ts files) package.json cd client yarn add -D @craco/craco ts-loadercraco.config.js en el directorio client/ (CRA)craco.config.js tenga el siguiente contenido const path = require("path"); module.exports = { webpack: { configure: webpackConfig => { // ts-loader is required to reference external typescript projects/files (non-transpiled) webpackConfig.module.rules.push({ test: /\.tsx?$/, loader: 'ts-loader', exclude: /node_modules/, options: { transpileOnly: true, configFile: 'tsconfig.json', }, }) return webpackConfig; } } };react-scripts en client/package.json con craco /* client/package.json */ "scripts": { - "start": "react-scripts start", + "start": "craco start", - "build": "react-scripts build", + "build": "craco build" - "test": "react-scripts test", + "test": "craco test" }La solución de alias para craco o rewired create-react-app es react-app-alias para sistemas como: craco , react-app- rewired, custom -cra
De acuerdo con los documentos de los sistemas mencionados, reemplace react-scripts en package.json y configure a continuación:
// config-overrides.js const {aliasWebpack, aliasJest} = require('react-app-alias') const options = {} // default is empty for most cases module.exports = aliasWebpack(options) module.exports.jest = aliasJest(options) // craco.config.js const {CracoAliasPlugin} = require('react-app-alias') module.exports = { plugins: [ { plugin: CracoAliasPlugin, options: {} } ] }Configure alias en json así:
// tsconfig.paths.json { "compilerOptions": { "baseUrl": ".", "paths": { "example/*": ["example/src/*"], "@library/*": ["library/src/*"] } } } Y agregue este archivo en la sección extends del archivo de configuración principal de mecanografiado:
// tsconfig.json { "extends": "./tsconfig.paths.json", // ... }