【问题标题】:In NPM workspaces Typescript fails to compile. In the rest of monorepository Typescript compiles correctly在 NPM 工作区中,Typescript 无法编译。在 monorepository 的其余部分中,Typescript 可以正确编译
【发布时间】:2021-08-21 07:07:50
【问题描述】:

我们已经将我们的项目重构为一个单一的存储库(NPM 工作区),并将其结构如下:

 |-- apps          
   |-- native         <-- Not Workspace
   |-- web            <-- Not Workspace
 |-- common        
   |-- models         <-- Workspace
   |-- connectors     <-- Workspace
   |-- store          <-- Workspace
   |-- types          <-- Workspace
   |-- utils          <-- Workspace
 -- package-lock.json
 -- package.json

我们的 nativeweb 应用使用来自 common 的代码,并且不会在它们之间共享代码。

root package.json
-----------------
{
  "name": "@secret/client",
  "version": "1.0.0",
  "private": true,
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "workspaces": [
    "./common/*"
  ]
}

问题

编译 Typescript 文件时,只有common 文件夹中的 Typescript 文件编译失败并抛出 Parsing error: Unexpected token 错误。 nativeweb 中的其余 Typescript 文件可以正确编译。

Webpack 模块.rules

[
  { parser: { requireEnsure: false } },
  {
    oneOf: [
      ...irrelevantRulesIntentionallyHidden,
      {
        test: /\.(js|mjs|jsx|ts|tsx)$/,
        include: 'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp',
        loader: 'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp\\apps\\web\\node_modules\\babel-loader\\lib\\index.js',
        options: {
          customize: 'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp\\apps\\web\\node_modules\\babel-preset-react-app\\webpack-overrides.js',
          presets: [
            [
              'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp\\apps\\web\\node_modules\\babel-preset-react-app\\index.js',
              [Object]
            ]
          ],
          babelrc: false,
          configFile: false,
          cacheIdentifier: 'development:babel-plugin-named-asset-import@0.3.7:babel-preset-react-app@10.0.0:react-dev-utils@11.0.4:react-scripts@4.0.3',
          plugins: [
            [
              'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp\\apps\\web\\node_modules\\babel-plugin-named-asset-import\\index.js',
              [Object]
            ],
            'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp\\apps\\web\\node_modules\\react-refresh\\babel.js'
          ],
          cacheDirectory: true,
          cacheCompression: false,
          compact: false,
          sourceType: 'unambiguous'
        }
      },
      {
        test: /\.(js|mjs)$/,
        exclude: /@babel(?:\/|\\{1,2})runtime/,
        loader: 'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp\\apps\\web\\node_modules\\babel-loader\\lib\\index.js',
        options: {
          babelrc: false,
          configFile: false,
          compact: false,
          presets: [
            [
              'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp\\apps\\web\\node_modules\\babel-preset-react-app\\dependencies.js',
              [Object]
            ]
          ],
          cacheDirectory: true,
          cacheCompression: false,
          cacheIdentifier: 'development:babel-plugin-named-asset-import@0.3.7:babel-preset-react-app@10.0.0:react-dev-utils@11.0.4:react-scripts@4.0.3',
          sourceMaps: true,
          inputSourceMap: true,
          sourceType: 'unambiguous'
        },
        include: 'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp'
      },
    ] 
  }
]

ESLintWebpackPlugin

{
  key: 'ESLintWebpackPlugin',
  options: {
    extensions: [ 'js', 'mjs', 'jsx', 'ts', 'tsx' ],
    emitError: true,
    emitWarning: true,
    failOnError: true,
    formatter: 'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp\\apps\\web\\node_modules\\react-scripts\\node_modules\\react-dev-utils\\eslintFormatter.js',
    eslintPath: 'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp\\apps\\web\\node_modules\\eslint\\lib\\api.js',
    context: 'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp',
    cache: true,
    cacheLocation: 'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp\\apps\\web\\node_modules\\.cache\\.eslintcache',
    cwd: 'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp\\apps\\web',
    resolvePluginsRelativeTo: 'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp\\apps\\web\\node_modules\\react-scripts\\config',
    baseConfig: {
      extends: [
        'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp\\apps\\web\\node_modules\\eslint-config-react-app\\base.js'
      ],
      rules: {}
    },
    overrideConfig: {
      rules: {
        '@typescript-eslint/no-unused-vars': [ 0 ],
        'no-use-before-define': [ 0 ],
        'no-useless-escape': [ 0 ],
        'jsx-a11y/anchor-is-valid': [ 0 ],
        'unicode-bom': [ 0 ],
        'react/button-has-type': [ 2, [Object] ],
        'react/jsx-no-literals': [ 2, [Object] ]
      },
      plugins: [ 'react' ]
    },
    ignore: true
  },
  run: [Function: bound run] AsyncFunction
}

ForkTsCheckerWebpackPlugin

{
    eslint: false,
    eslintOptions: {},
    tsconfigPath: undefined,
    compiler: undefined,
    started: undefined,
    elapsed: undefined,
    cancellationToken: undefined,
    isWatching: false,
    checkDone: false,
    compilationDone: false,
    diagnostics: [],
    lints: [],
    eslintVersion: undefined,
    startAt: 0,
    nodeArgs: [],
    options: {
      typescript: 'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp\\apps\\web\\node_modules\\typescript\\lib\\typescript.js',
      async: true,
      checkSyntacticErrors: true,
      resolveModuleNameModule: undefined,
      resolveTypeReferenceDirectiveModule: undefined,
      tsconfig: 'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp\\apps\\web\\tsconfig.json',
      reportFiles: [Array],
      silent: true,
      formatter: undefined
    },
    ignoreDiagnostics: [],
    ignoreLints: [],
    ignoreLintWarnings: false,
    reportFiles: [
      '../**/src/**/*.{ts,tsx}',
      '**/src/**/*.{ts,tsx}',
      '!**/src/**/__tests__/**',
      '!**/src/**/?(*.)(spec|test).*',
      '!**/src/setupProxy.*',
      '!**/src/setupTests.*'
    ],
    logger: Object [console] {...}, <--- too long to paste
    typescriptPath: 'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp\\apps\\web\\node_modules\\typescript\\lib\\typescript.js',
    typescriptVersion: '4.2.3',
    tsconfig: 'C:\\_git\\Secret\\src\\Secret.WebClient\\ClientApp\\apps\\web\\tsconfig.json',
    compilerOptions: {},
    vue: { compiler: 'vue-template-compiler', enabled: false },
    useTypescriptIncrementalApi: true,
    measureTime: false
  }

示例:common/connectors/package.json

{
  "name": "@secret/connectors",
  "version": "1.0.0",
  "private": true,
  "description": "",
  "main": "index.js",
  "dependencies": {
    "@types/lodash": "^4.14.165",
    "@types/react": "^17.0.3",
    "lodash": "^4.17.20",
    "react-redux": "^7.2.3",
    "typescript": "^4.2.3"
  },
  "devDependencies": {
    "eslint-plugin-react": "^7.23.1",
    "tslint": "^5.20.1",
    "tslint-react": "^4.1.0"
  }
}

有人有这方面的经验吗?您认为可能的解决方案是什么?

【问题讨论】:

  • 查看本文的 Webpack 部分,如果有帮助请告诉我。我们遇到了类似的情况,我们不得不告诉 Webpack 和 TypeScript 来解析源文件,而不是在构建时使用来自 npm 工作区的符号链接。 medium.com/@NiGhTTraX/…
  • @evelynhathaway 谢谢你的链接。我尝试在 create-react-app 部分实施建议的 tsconfig-paths-webpack-plugin 和其他一些解决方案,但无济于事。

标签: typescript npm webpack eslint monorepo


【解决方案1】:

问题已解决

ForkTsCheckerWebpackPlugin create-react-app (CRA) 使用中有一个错误。将其更新到最新版本(在撰写本文时 6.2.10)并使用此 CRA 覆盖解决了该问题:

// Use newer version of ForkTSCheckerWebpackPlugin to type check
// files across the monorepo.
const forkTsCheckerWebpackPlugin = config.plugins.findIndex(
  (p) => p.reportFiles
);
if (forkTsCheckerWebpackPlugin !== -1) {
  config.plugins.splice(
    forkTsCheckerWebpackPlugin,
    1,
    new ForkTSCheckerWebpackPlugin({
      issue: {
        // The exclude rules are copied from CRA.
        exclude: [
          {
            file: "**/src/**/__tests__/**",
          },
          {
            file: "**/src/**/?(*.)(spec|test).*",
          },
          {
            file: "**/src/setupProxy.*",
          },
          {
            file: "**/src/setupTests.*",
          },
        ],
      },
    })
  );
}

解决方案:@NiGhTTraX https://github.com/NiGhTTraX/ts-monorepo/issues/74

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-01
    • 1970-01-01
    • 2017-12-09
    • 1970-01-01
    • 2016-12-18
    • 2017-12-06
    相关资源
    最近更新 更多