web-dev-qa-db-fra.com

Un projet avec plusieurs fichiers package.json

Je suis relativement nouveau dans le développement JS moderne et j'ai besoin d'aide ou de conseils sur la situation dans laquelle je me trouve.

Situation: Nous avons un projet React-TypeScript-Redux supportant IE8 (React 0.14). Nous passons maintenant à IE11 et React 16 mais IE8 devrait être pris en charge.

Condition: Réduisez la maintenance du projet entre les versions du navigateur en utilisant différents packages et/ou fichiers de configuration pour chaque build.

Problème: D'après les recherches que j'ai faites jusqu'à présent, il semble impossible d'utiliser différents fichiers package.json et dossiers node_modules dans le même projet avec les outils sélectionnés: npm, Webpack , React, Redux, TypeScript. Yarn semble prendre en charge plusieurs fichiers package.json mais nous aimerions éviter de migrer de npm si possible.

Structure actuelle du projet:

project_root/
  node_modules/
  src/
    components/
    utils/
    index.tsx
    components.css
  index.html
  package.json
  tsconfig.json
  webpack.config.json

Ce que je pensais pouvoir fonctionner, c'était d'introduire le sous-dossier IE8 avec son dossier package.json et node_modules, puis de référencer ce dossier pour la tâche de construction, mais maintenant je ne sais pas comment dire à npm de le référencer lors de la construction.

Structure de projet proposée:

project_root/
  ie8/
   node_modules/
   package.json
  node_modules/
  src/
    components/
    utils/
    index.tsx
    components.css
  index.html
  package.json
  tsconfig.json
  webpack.config.json

J'ai essayé différentes choses trouvées sur le Web, notamment resolve.modules: [__dirname + "/ie8/node_modules"] mais il semble que cela ne fonctionne pas ou je comprends mal ce qu'il fait parce que je reçois Cannot find name 'require' erreurs sur plusieurs fichiers et TypeScript 2.8.3 est référencé dans la sortie du terminal au lieu de 2.3.4. Sans cela, le projet se construit avec la configuration pour IE11.

Alors, quelqu'un peut-il me dire avec certitude que ce n'est pas possible ou offrir des conseils? This est la réponse la plus proche que j'ai trouvée jusqu'à présent mais ne semble pas définitive. Alternativement, une structure de projet comme celle-ci peut-elle prendre en charge ce qui est requis ou séparer le projet en deux est le meilleur pari?

Merci d'avance.

14
skrunic

OK, donc après quelques recherches supplémentaires, je suis tombé sur Lerna qui me permet surtout de faire ce que je voulais (d'après ce que j'ai vu jusqu'à présent). Cela nécessite une configuration d'arborescence de projet spécifique, comme ceci:

project_root/
  node_modules/
  packages/
    components/ // Components shared between projects
      components/
       MyComponent.jsx
      index.jsx

  legacy/
     output/
      build.js // React 0.14 build
     node_modules/
     package.json // project specific dependencies
     index.jsx // project specific entry
     .babelrc

  modern/
     output/
      build.js // React 16 build
     node_modules/
     package.json // project specific dependencies
     index.jsx // project specific entry
     .babelrc

  package.json // contains devDependencies shared between projects
  lerna.json
  webpack.config.js
  index.html

Ensuite, dans components/index.jsx, j'ai spécifié des commandes requises pour différentes versions basées sur la variable globale:

if(PROJECT_SRC == "legacy"){
    React = require('../legacy/node_modules/react');
    ReactDOM = require('../legacy/node_modules/react-dom');
} else {
    React = require('../modern/node_modules/react');
    ReactDOM = require('../modern/node_modules/react-dom');
}

Remarque: C'est probablement une mauvaise pratique, mais la seule façon pour le moment je pourrais inclure différentes versions React dans la construction. Je vais devoir voir quels problèmes surviennent avec cette approche après que tout le projet ait changé) à ce modèle.

Dans webpack.config.js, j'ai configuré deux exportations - une pour la version moderne et une pour l'héritage. Chacun pointe vers un fichier index.jsx d'entrée différent, utilise webpack.DefinePlugin pour définir la variable globale sur "hérité" ou "moderne" et spécifie le chemin d'accès au module de composants communs à résoudre: ['node_modules', path.resolve(__dirname, 'components')]

webpack.config pour une sortie de projet unique ressemble à ceci:

{
        entry: "./packages/legacy/index.jsx",
        target: "web", 
        output: 
        {
            filename: "build.js",
            path: __dirname + "/packages/legacy/dist/",
            libraryTarget: "var",
            library: "lib_name"
        },
        devtool: "source-map",
        resolve: {
            extensions: [".js", ".jsx", ".json"],
            modules: ['node_modules', path.resolve(__dirname, 'components')]
        },
        plugins: plugins_legacy,
        module: {
            loaders: [
                {
                    test: /\.jsx?$/,
                    loader: "babel-loader",
                    exclude: /node_modules/
                }
            ]
        }  
    }

N'hésitez pas à commenter ou à signaler des problèmes, mais j'espère que cela aidera quelqu'un à l'avenir! :)

14
skrunic