Objetivo
Entonces estoy teniendo un proyecto con esta estructura:
- aplicación iónica
- funciones de firebase
- compartido
El objetivo es definir interfaces y clases comunes en el shared
módulo.
Restricciones
No quiero cargar mi código a npm para usarlo localmente y no planeo cargar el código en absoluto. Debería funcionar al 100% sin conexión.
Si bien el proceso de desarrollo debería funcionar sin conexión, los módulos ionic-app
y firebase-functions
se implementarán en firebase (hosting y funciones). Por lo tanto, el código del shared
módulo debe estar disponible allí.
Lo que he intentado hasta ahora
- He intentado usar referencias de proyecto en mecanografiado, pero no lo he logrado.
- Lo probé instalándolo como un módulo npm como en la segunda respuesta de esta pregunta
- Al principio parece estar funcionando bien, pero durante la compilación, aparece un error como este cuando se ejecuta
firebase deploy
:
- Al principio parece estar funcionando bien, pero durante la compilación, aparece un error como este cuando se ejecuta
Function failed on loading user code. Error message: Code in file lib/index.js can't be loaded.
Did you list all required modules in the package.json dependencies?
Detailed stack trace: Error: Cannot find module 'shared'
at Function.Module._resolveFilename (module.js:548:15)
at Function.Module._load (module.js:475:25)
at Module.require (module.js:597:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/srv/lib/index.js:5:18)
Pregunta
¿Tiene una solución para hacer un módulo compartido usando ya sea config de script o NPM?
No marque esto como un duplicado → He intentado cualquier solución que he encontrado en StackOverflow.
Información adicional
Configuración para compartido:
// package.json
{
"name": "shared",
"version": "1.0.0",
"description": "",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
"files": [
"dist/src/**/*"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"publishConfig": {
"access": "private"
}
}
// tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"rootDir": ".",
"sourceRoot": "src",
"outDir": "dist",
"sourceMap": true,
"declaration": true,
"target": "es2017"
}
}
Configuración para funciones:
// package.json
{
"name": "functions",
"scripts": {
"lint": "tslint --project tsconfig.json",
"build": "tsc",
"serve": "npm run build && firebase serve --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "8"
},
"main": "lib/index.js",
"dependencies": {
"firebase-admin": "^8.0.0",
"firebase-functions": "^3.1.0",
"shared": "file:../../shared"
},
"devDependencies": {
"@types/braintree": "^2.20.0",
"tslint": "^5.12.0",
"typescript": "^3.2.2"
},
"private": true
}
// tsconfig.json
{
"compilerOptions": {
"baseUrl": "./",
"module": "commonjs",
"noImplicitReturns": true,
"noUnusedLocals": false,
"rootDir": "src",
"outDir": "lib",
"sourceMap": true,
"strict": true,
"target": "es2017"
}
}
Sopa actual
He agregado un script npm al módulo compartido, que copia todos los archivos (sin index.js) a los otros módulos. Esto tiene el problema, que verifico el código duplicado en SCM y que necesito ejecutar ese comando en cada cambio. Además, el IDE solo lo trata como archivos diferentes.
fuente
Otra posible solución, si está usando git para administrar su código, está usando
git submodule
. Utilizandogit submodule
puedes incluir otro repositorio git en tu proyecto.Aplicado a su caso de uso:
git submodule add <shared-git-repository-link>
dentro de su (s) proyecto (s) principal (es) para vincular el repositorio compartido.Aquí hay un enlace a la documentación: https://git-scm.com/docs/git-submodule
fuente
Si entiendo su problema correctamente, la solución es más compleja que una sola respuesta y depende en parte de su preferencia.
Enfoque 1: copias locales
Puede usar Gulp para automatizar la solución de trabajo que ya describió, pero IMO no es muy fácil de mantener y aumenta drásticamente la complejidad si en algún momento entra otro desarrollador.
Enfoque 2: Monorepo
Puede crear un único repositorio que contenga las tres carpetas y conectarlas para que se comporten como un solo proyecto. Como ya se respondió anteriormente, puede usar Lerna . Requiere un poco de configuración, pero una vez hecho, esas carpetas se comportarán como un solo proyecto.
Enfoque 3: componentes
Trate cada una de estas carpetas como un componente independiente. Echa un vistazo a Bit . Le permitirá configurar las carpetas como partes más pequeñas de un proyecto más grande y puede crear una cuenta privada que abarcará esos componentes solo para usted. Una vez configurado inicialmente, le permitirá incluso aplicar actualizaciones a las carpetas separadas y el padre que las usa obtendrá automáticamente las actualizaciones.
Enfoque 4: Paquetes
Dijiste específicamente que no quieres usar npm, pero quiero compartirlo, porque actualmente estoy trabajando con una configuración como se describe a continuación y estoy haciendo un trabajo perfecto para mí:
npm
oyarn
para crear un paquete para cada carpeta (puede crear paquetes de ámbito para ambos, de modo que el código solo estará disponible para usted, si esto le preocupa).Funciona a las mil maravillas y cuando los paquetes están enlazados para el desarrollo local, funciona completamente fuera de línea y, en mi experiencia, cada carpeta es escalable por separado y muy fácil de mantener.
Nota
Los paquetes 'secundarios' ya están precompilados en mi caso, ya que son bastante grandes y he creado tsconfigs por separado para cada paquete, pero lo hermoso es que puedes cambiarlo fácilmente. En el pasado, utilicé el mecanografiado en el módulo y los archivos compilados, y también archivos js sin formato, por lo que todo es muy, muy versátil.
Espero que esto ayude
***** ACTUALIZACIÓN **** Para continuar en el punto 4: Pido disculpas, mi mal. Tal vez me equivoqué porque, hasta donde yo sé, no puedes vincular un módulo si no está cargado. Sin embargo, aquí está:
firebase-functions
para eso. Lo compilas o usas ts sin procesar, según tu preferencia.firebase-functions
como dependencia.tsconfig.json
, agregue"paths": {"firebase-functions: ['node_modules/firebase-functions']"}
resolve: {extensions: ['ts', 'js'], alias: 'firebase-functions': }
De esta manera, hace referencia a todas sus funciones exportadas desde el
firebase-functions
módulo simplemente mediante el usoimport { Something } from 'firebase-functions'
. Webpack y TypeScript lo vincularán a la carpeta de módulos de nodo. Con esta configuración, al proyecto principal no le importará si elfirebase-functions
módulo está escrito en TypeScript o javascript vainilla.Una vez configurado, funcionará perfectamente para la producción. Luego, para vincular y trabajar sin conexión:
firebase-functions
proyecto y escribenpm link
. Creará un enlace simbólico, local a su máquina y asignará al enlace el nombre que configuró en package.json.npm link firebase-functions
, lo que creará el enlace simbólico y asignará la dependencia de las funciones de firebase a la carpeta en la que lo ha creado.fuente
Todos los módulos npm se instalan localmente y siempre funcionan sin conexión, pero si no desea publicar sus paquetes públicamente para que la gente pueda verlos, puede instalar un registro privado npm.
ProGet es un servidor de repositorio privado NuGet / Npm disponible para Windows que puede usar en su entorno privado de desarrollo / producción para alojar, acceder y publicar sus paquetes privados. Aunque está en Windows, pero estoy seguro de que hay varias alternativas disponibles en Linux.
Aquí está nuestro escenario de construcción / implementación.
.npmrc
cuál contieneregistry=https://private-npm-repository
.bundled dependencies
que contiene todos los paquetes dentronode_modules
y el servidor de producción nunca necesita acceder a NPM o paquetes privados de NPM ya que todos los paquetes necesarios ya están agrupados.El uso del repositorio privado npm tiene varias ventajas,
fuente
La herramienta que estás buscando es
npm link
.npm link
proporciona enlaces simbólicos a un paquete npm local. De esa manera, puede vincular un paquete y usarlo en su proyecto principal sin publicarlo en la biblioteca de paquetes npm.Aplicado a su caso de uso:
npm link
dentro de sushared
paquete. Esto establecerá el destino del enlace simbólico para futuras instalaciones.functions
paquete y úselonpm link shared
para vincular el paquete compartido y agregarlo alnode_modules
directorio.Aquí hay un enlace a la documentación: https://docs.npmjs.com/cli/link.html
fuente