Objectif
J'ai donc un projet avec cette structure:
- ionic-app
- fonctions de base de feu
- partagé
L'objectif est de définir des interfaces et des classes communes dans le shared
module.
Restrictions
Je ne veux pas télécharger mon code sur npm pour l'utiliser localement et je n'envisage pas du tout de télécharger le code. Il devrait fonctionner à 100% hors ligne.
Alors que le processus de développement devrait fonctionner hors ligne, les modules ionic-app
et firebase-functions
vont être déployés sur firebase (hébergement et fonctions). Par conséquent, le code du shared
module devrait y être disponible.
Ce que j'ai essayé jusqu'à présent
- J'ai essayé d'utiliser les références de projet en dactylographie, mais je ne l'ai pas approché du travail
- Je l'ai essayé en l'installant comme module npm comme dans la deuxième réponse de cette question
- Cela semble bien fonctionner au début, mais pendant la génération, j'obtiens une erreur comme celle-ci lors de l'exécution
firebase deploy
:
- Cela semble bien fonctionner au début, mais pendant la génération, j'obtiens une erreur comme celle-ci lors de l'exécution
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)
Question
Avez-vous une solution pour créer un module partagé à l'aide de la configuration de scripts de saisie ou de NPM?
Veuillez ne pas marquer ceci comme un doublon → J'ai essayé n'importe quelle solution que j'ai trouvée sur StackOverflow.
Information additionnelle
Configuration pour partagé:
// 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"
}
}
Configuration pour les fonctions:
// 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"
}
}
Soution actuelle
J'ai ajouté un script npm au module partagé, qui copie tous les fichiers (sans index.js) dans les autres modules. Cela a le problème, que j'archive le code en double dans SCM, et que j'ai besoin d'exécuter cette commande à chaque changement. De plus, l'EDI le traite simplement comme des fichiers différents.
la source
Une autre solution possible, si vous utilisez git pour gérer votre code, est d'utiliser
git submodule
. En utilisant,git submodule
vous pouvez inclure un autre référentiel git dans votre projet.Appliqué à votre cas d'utilisation:
git submodule add <shared-git-repository-link>
intérieur de vos projets principaux pour lier le référentiel partagé.Voici un lien vers la documentation: https://git-scm.com/docs/git-submodule
la source
Si je comprends bien votre problème, la solution est plus complexe qu'une seule réponse et cela dépend en partie de vos préférences.
Approche 1: copies locales
Vous pouvez utiliser Gulp pour automatiser la solution de travail que vous avez déjà décrite, mais IMO n'est pas très facile à maintenir et augmente considérablement la complexité si à un moment donné un autre développeur entre en jeu.
Approche 2: Monorepo
Vous pouvez créer un référentiel unique contenant les trois dossiers et les connecter pour qu'ils se comportent comme un seul projet. Comme déjà répondu ci-dessus, vous pouvez utiliser Lerna . Cela nécessite un peu de configuration, mais une fois terminé, ces dossiers se comporteront comme un seul projet.
Approche 3: Composants
Traitez chacun de ces dossiers comme un composant autonome. Jetez un oeil à Bit . Il vous permettra de configurer les dossiers en tant que parties plus petites d'un projet plus important et vous pouvez créer un compte privé qui ne couvrira ces composants que pour vous. Une fois initialement configuré, il vous permettra même d'appliquer des mises à jour aux dossiers séparés et le parent qui les utilise recevra automatiquement les mises à jour.
Approche 4: Forfaits
Vous avez spécifiquement dit que vous ne vouliez pas utiliser npm, mais je veux le partager, car je travaille actuellement avec une configuration telle que décrite ci-dessous et fait un travail parfait pour moi:
npm
ouyarn
pour créer un package pour chaque dossier (vous pouvez créer des packages de portée pour les deux afin que le code ne soit disponible que si cela vous concerne).Fonctionne comme un charme et lorsque les packages sont liés par des liens symboliques pour le développement local, cela fonctionne entièrement hors ligne et d'après mon expérience - chaque dossier est évolutif séparément et très facile à entretenir.
Remarque
Les packages «enfants» sont déjà précompilés dans mon cas car ils sont assez gros et j'ai créé des tsconfigs séparés pour chaque package, mais la belle chose est que vous pouvez le changer facilement. Dans le passé, j'ai utilisé à la fois du tapuscrit dans le module et des fichiers compilés, ainsi que des fichiers js bruts, donc le tout est très, très polyvalent.
J'espère que cela t'aides
***** MISE À JOUR **** Pour continuer sur le point 4: je m'excuse, ma mauvaise. Peut-être que je me suis trompé parce que, pour autant que je sache, vous ne pouvez pas créer de lien symbolique pour un module s'il n'est pas téléchargé. Néanmoins, le voici:
firebase-functions
pour cela. Vous le compilez ou utilisez des ts bruts, selon vos préférences.firebase-functions
tant que dépendance.tsconfig.json
, ajoutez"paths": {"firebase-functions: ['node_modules/firebase-functions']"}
resolve: {extensions: ['ts', 'js'], alias: 'firebase-functions': }
De cette façon, vous référencez toutes vos fonctions exportées à partir du
firebase-functions
module simplement en utilisantimport { Something } from 'firebase-functions'
. Webpack et TypeScript le lieront au dossier des modules de noeud. Avec cette configuration, le projet parent ne se souciera pas si lefirebase-functions
module est écrit en TypeScript ou javascript vanilla.Une fois installé, il fonctionnera parfaitement pour la production. Ensuite, pour lier et travailler hors ligne:
firebase-functions
projet et écriveznpm link
. Il créera un lien symbolique local sur votre machine et mappera le lien que vous avez défini dans package.json.npm link firebase-functions
, ce qui créera le lien symbolique et mappera la dépendance des fonctions firebase au dossier dans lequel vous l'avez créé.la source
Tous les modules npm sont installés localement et fonctionnent toujours hors ligne, mais si vous ne souhaitez pas publier vos packages publiquement pour que les gens puissent le voir, vous pouvez installer le registre npm privé.
ProGet est un serveur de référentiel privé NuGet / Npm disponible pour Windows que vous pouvez utiliser dans votre environnement de développement / production privé pour héberger, accéder et publier vos packages privés. Bien que ce soit sur Windows, mais je suis sûr qu'il existe différentes alternatives disponibles sur Linux.
Voici notre scénario de construction / déploiement.
.npmrc
qui contientregistry=https://private-npm-repository
.bundled dependencies
lequel contient tous les packages à l'intérieurnode_modules
et le serveur de production n'a jamais besoin d'accéder aux packages NPM ou NPM privés car tous les packages nécessaires sont déjà fournis.L'utilisation du référentiel privé npm présente divers avantages,
la source
L'outil que vous recherchez est
npm link
.npm link
fournit des liens symboliques vers un package npm local. De cette façon, vous pouvez lier un package et l'utiliser dans votre projet principal sans le publier dans la bibliothèque de packages npm.Appliqué à votre cas d'utilisation:
npm link
intérieur de votreshared
colis. Cela définira la destination du lien symbolique pour les futures installations.functions
package et utiliseznpm link shared
pour lier le package partagé et l'ajouter aunode_modules
répertoire.Voici un lien vers la documentation: https://docs.npmjs.com/cli/link.html
la source