web-dev-qa-db-ja.com

複数のpackage.jsonファイルを持つ1つのプロジェクト

私は現代のJS開発に比較的慣れていないので、この状況について助けやアドバイスが必要です。

状況:IE8(React 0.14)をサポートするReact-TypeScript-Reduxプロジェクトがあります。現在、私たちはIE11とReact 16にアップグレードしていますが、IE8はサポートされるべきです。

要件:ビルドごとに異なるパッケージや構成ファイルを使用することで、ブラウザーバージョン間のプロジェクトメンテナンスを削減します。

問題:これまでに行った調査から、選択したツールで同じプロジェクト内で異なるpackage.jsonファイルとnode_modulesフォルダーを使用することは不可能と思われます:npm、Webpack 、React、Redux、TypeScript。 Yarnは複数のpackage.jsonファイルをサポートしているようですが、可能であればnpmからの移行を避けたいと思います。

現在のプロジェクト構造:

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

IE8サブフォルダーをpackage.jsonフォルダーとnode_modulesフォルダーで紹介し、そのフォルダーをビルドタスクで何らかの方法で参照することでしたが、ビルド時にnpmに参照するように指示する方法がわかりません。

提案されたプロジェクト構造:

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

ウェブ上で見つかったさまざまなことを試してみました、resolve.modules: [__dirname + "/ie8/node_modules"]しかし、うまくいかないようです。または、Cannot find name 'require'エラーはいくつかのファイルで、TypeScript 2.8.3は代わりに2.3.4のターミナル出力で参照されます。これがないと、プロジェクトはIE11用の構成でビルドされます。

だから、それは不可能だと確信して誰かに教えてもらえますか? これ は、私がこれまでに見つけた最も近い答えですが、最終的には聞こえません。あるいは、このようなプロジェクト構造は必要なものをサポートすることができますか、プロジェクトを2つに分けることが最善策です?

前もって感謝します。

14
skrunic

OK、それで、さらにいくつかの研究の後、私はつまずきました Lerna これは私が望むものをすることをほとんど可能にします(これまで見たものから)。次のような特定のプロジェクトツリーのセットアップが必要です。

_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
_

次に、components/index.jsxで、グローバル変数に基づいて異なるバージョンのコマンドが必要であることを指定しました。

_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');
}
_

注:これはおそらく悪い習慣ですが、現時点ではビルドに異なるReactバージョンを含めることができる唯一の方法です。プロジェクト全体を変更した後、このアプローチでどのような問題が発生するかを確認する必要がありますこのモデルに。

Webpack.config.jsで、2つのエクスポートを構成しました-1つは現代用、もう1つはレガシー用です。それぞれが異なるエントリindex.jsxファイルを指し、webpack.DefinePluginを使用してグローバル変数を「レガシー」または「モダン」に設定し、解決する共通コンポーネントモジュールへのパスを指定します:['node_modules', path.resolve(__dirname, 'components')]

単一のプロジェクト出力のwebpack.configは次のようになります。

_{
        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/
                }
            ]
        }  
    }
_

気軽にコメントしたり、問題を指摘したりできますが、これが将来誰かに役立つことを願っています! :)

14
skrunic