为了账号安全,请及时绑定邮箱和手机立即绑定

“ package.json”不在“ rootDir”下

“ package.json”不在“ rootDir”下

繁花不似锦 2021-04-26 13:14:29
我正在尝试导入package.json我的TypeScript应用程序:import packageJson from '../package.json';我的tsconfig.json包含以下内容:{  "compilerOptions": {    "rootDir": "./src/"    "outDir": "./dist/",    "baseUrl": ".",    "resolveJsonModule": true  }}问题是当我编译它时,我得到error TS6059: File '/path/to/package.json' is not under 'rootDir' '/path/to/app/src/'. 'rootDir' is expected to contain all source files.我不知道我理解这个问题,因为这两个./src/与/.dist具有相同的父..,所以打字稿可能只是独自离开import '../package.json'和它的工作无论从rootDir或outDir。无论如何,我尝试了以下方法,但结果却不尽人意:remove-rootDir编译有效,但dist将包含dist/src,我不需要删除outDir-然后src被.js文件污染(.js.map如果sourceMap是,则为true)add-@ts-ignore编译停止导入的文件../package.json该限制的解决方法是什么,将生成的文件保留在中dist,并允许从的父目录导入rootDir?
查看完整描述

3 回答

?
ibeautiful

TA贡献1993条经验 获得超5个赞

这是可能的,事实证明,这并不困难

解决方案之所以不明显是因为Typescript依赖rootDir来决定输出的目录结构(请参阅Typescript的bossman中的此注释),并且只能导入输出或包依赖项中包含的代码。

  • 如果设置rootDir为项目的根目录,则将其package.json发射到的根目录outDir并可以将其导入。但是随后,您的编译src文件将写入outDir/src

  • 如果设置rootDirsrc,则其中的文件将编译为的根outDir。但是现在编译器将无处可放package.json,因此它发出“错误,因为项目似乎配置错误”(老板的话)。

解决方案:使用单独的Typescript子项目

一个打字稿项目被规定tsconfig文件,是自包含的,并有效地通过它的边界rootDir。这是一件非常好的事情,因为它符合封装原则

您可以在各自的目录中和各自的tsconfig中拥有多个项目(例如,主库和一组lib)。它们之间的依赖关系使用Typescript项目引用在tsconfig文件中声明。

我承认,术语“项目”是一个可怜的项目,直觉上是指整个项目,但是在这种情况下已经采用了“模块”和“包”。将它们视为“子项目”,这将更有意义。

我们将src目录和包含的根目录package.json视为单独的项目。每个tsconfig文件都有其自己的文件。

给src 目录自己的项目。


./src/tsconfig.json:


{

  "compilerOptions": {

    "rootDir": ".",

    "outDir": "../dist/",

    "resolveJsonModule": true

  },

  "references": [      // this is how we declare a dependency from

    { "path": "../" }  // this project to the one at the root dir`

  ]

}   

给根目录自己的项目。


./tsconfig.json:


{

  "compilerOptions": {

    "rootDir": ".",

    "outDir": ".",  // if out path for a file is same as its src path, nothing will be emitted

    "resolveJsonModule": true,

    "composite": true  // required on the dependency project for references to work

  },

  "files": [         // by whitelisting the files to include, TS won't automatically

    "package.json"   // include all source below root, which is the default.

  ]

}

跑去tsc --build src 瞧瞧!


这将构建src项目。因为它声明了对根项目的引用,所以它也会构建该项目,但前提是该项目已过时。因为根tsconfig与dir具有相同的目录,所以outDirtsc只会对package.json配置为编译的一个文件不执行任何操作。

这对于monorepos来说很棒

您可以通过将模块/库/子项目放在它们自己的子目录中并为其提供自己的tsconfig来隔离它们。


您可以使用Project References显式管理依赖项,也可以模块化构建:


从链接的文档中:


您可以大大缩短构建时间

期待已久的功能是用于TypeScript项目的智能增量构建。在3.0中,您可以将--build标志与一起使用tsc。实际上,这是一个新的入口点,tsc它的行为更像是构建协调器,而不是简单的编译器。


运行tsc --build(tsc -b简称)将执行以下操作:


查找所有引用的项目

检测它们是否最新

以正确的顺序构建过时的项目

不必担心对在命令行上传递的文件进行排序-tsc如果需要,将对它们进行重新排序,以便始终先构建依赖项。


强制组件之间的逻辑分离


以更好的新方式组织代码。


这也很容易:


src/tsconfig.json


即使您根本没有代码,此tsconfig仍可以放在所有常用设置中(其他设置将从那里继承),并且将使您可以轻松tsc --build src地构建整个项目(并--force从头开始构建它)。


{

  "compilerOptions": {

    "rootDir": ".",

    "outDir": "../build/",

    "resolveJsonModule": true,

    "composite": true

  },

  // this root project has no source of its own

  "files": [],

  // but building this project will build all of the following:

  "references": [

    { "path": "./common" }

    { "path": "./projectA" }

    // include all other sub-projects here  

  ]

}

src/common/tsconfig.json


由于common没有引用,因此导入仅限于其目录和中的目标npm_modules。我相信,您甚至可以通过赋予它自己来限制后者package.json。


    {

     "compilerOptions": {

        "rootDir": ".",

        "outDir": "../../build/common",

        "resolveJsonModule": true,

        "composite": true

      }

    }

src/projectA/tsconfig.json


由于声明了引用,所以projectA可以导入common。


    {

      "compilerOptions": {

        "rootDir": ".",

        "outDir": "../../build/libA",

        "resolveJsonModule": true,

        "composite": true

      },

      "references": [

        { "path": "../common" }

      ]

    }


查看完整回答
反对 回复 2021-05-06
?
翻阅古今

TA贡献1780条经验 获得超5个赞

目前不可能。Typescript编译器尝试保留您的目录结构。


例如,您的项目如下所示:


src/

  shared/

    index.ts

  index.ts

package.json

tsconfig.json

您tsconfig.json包含:


{

  "compilerOptions": {

    "outDir": "./build",

    "module": "commonjs",

    "target": "es6",

    "moduleResolution": "node",

    "emitDecoratorMetadata": true,

    "experimentalDecorators": true,

    "noImplicitAny": true,

    "sourceMap": true,

    "resolveJsonModule": true,

    "esModuleInterop": true

  },

  "include": [

    "src/**/*"

  ]

}

如您所见,该文件不包含rootDir属性,但是当您调用tsc命令编译该项目时,输出将如下所示:


build/

  shared/

    index.js

  index.js

输出不包含src文件夹,因为在我的代码中,我只是导入并在src文件夹内部使用,例如:


src/index.ts


import someName from './shared';

然后,build/index.js将如下所示:


...

const shared_1 = __importDefault(require("./shared"));

...

如您所见- require("./shared"),这意味着它可以很好地与build文件夹结构配合使用。


导入“外部”模块时出现“问题”


import packageJson from '../package.json';

那么,“后退”动作-“ ../”会发生什么?如果您希望您的输出结构为:


build/

  package.json

  index.js

然后,他们如何配合使用const packageJson = __importDefault(require("../package.json"));。然后,Typescript编译器尝试保持项目结构:


build/

  package.json

  src/

    index.js

对于monorepo项目,我认为您需要为每个库创建声明文件,然后references在tsconfig文件中使用设置结束。前任:


在该./lib01文件夹中,lib导入./lib02其代码。Tsconfig文件将类似于:

{

  "compilerOptions": {

    "declarationDir": "dist",

    "rootDir": "src"

  },

  "include": ["src/**/*"],

  "references": [ // here

    {

      "path": "../lib02"

    }

  ]

}

lib02的 tsconfig.json

 {

   "compilerOptions": {

    "declarationDir": "dist",

    "rootDir": "src",

    "composite": true // importance.

  }

 }


查看完整回答
反对 回复 2021-05-06
  • 3 回答
  • 0 关注
  • 401 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信