一个项目有多个 package.json 文件

IT技术 node.js reactjs typescript webpack-2
2021-04-01 12:16:45

我对现代 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 的配置构建。

那么,有人可以肯定地告诉我这是不可能的或提供一些指导吗?是迄今为止我找到的最接近的答案,但听起来不是最终答案。或者,像这样的项目结构是否可以支持所需的内容或将项目分成两个是最好的选择?

提前致谢。

1个回答

好的,所以经过一些更多的研究后,我偶然发现了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 中,我根据全局变量为不同版本指定了 require 命令:

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 中,我配置了两个导出 - 一个用于现代,一个用于遗留。每个指向不同的入口 index.jsx 文件,使用 webpack.DefinePlugin 将全局变量设置为“legacy”或“modern”,并指定通用组件module的路径来解析:['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/
                }
            ]
        }  
    }

随时发表评论或指出问题,但我希望这会在将来对某人有所帮助!:)

我正在尝试将整个 react 应用程序导入到我的 rails 应用程序中,这意味着不止一个 package.json 因为我将整个 react 应用程序粘贴到我的 javascript/packs 文件夹中 当然它不会像这样工作,但我不确定如何清理它我看到你使用了 components/index.jsx 中的条件块来选择但在我的情况下我需要使用两个文件中列出的所有包显然我不知道我在做什么你能提供任何建议吗
2021-05-28 12:16:45