VSCode如何配置为支持Lerna Monorepo?

Und*_*ion 10 javascript import visual-studio-code lerna monorepo

我有一个包含许多软件包的lerna monorepo。

我正在努力实现以下目标:

  1. 确保VSCode提供从一个软件包到另一个软件包的正确导入建议(基于软件包名称,而不是相对路径)。
  2. 确保我可以对这些导入之一进行“打开定义”,并带到该文件的src中。

对于1。我的意思是,如果我正在package-a中导航代码,并且开始键入package-b导出的函数,那么我会得到一条建议,该建议将触发添加import:`import {example} from'package- b'。

对于2。我的意思是,如果在我从导入了另一个包的另一个软件包中浏览文件时,按住alt或单击“ package-b”导出的函数的名称,则会进入“ / packages / namespace / package / b” /src/file-that-c​​ontains-function.js',

我的(lerna)monorepo是标准结构,例如,此处是发布为的“组件”包@namespace/components

- packages
    - components
       - package.json
       - node_modules
       - src
         - index.js
         - components
           - Button
             - index.js
             - Button.js
       - es
         - index.js
         - components
           - Button
             - index.js
             - Button.js
Run Code Online (Sandbox Code Playgroud)

请注意,每个组件都由目录表示,以便在必要时可以包含其他组件。在此示例中,将packages/components/index出口Button作为命名出口。文件被编译到软件包的/es/目录中。

默认情况下,VSCode为导入提供自动建议,但是这种结构使它感到困惑,并且,例如,如果需要使用monorepo中的其他软件包Button,则会自动建议以下所有导入路径:

  • packages/components/src/index.js
  • packages/components/src/Button/index.js
  • packages/components/src/Button/Button.js
  • packages/components/es/index.js
  • packages/components/es/Button/index.js
  • packages/components/es/Button/Button.js

但是,这些都不适合,因为它们将被呈现为从导入文件到导入文件的相对路径。在这种情况下,以下导入是正确的导入:

import { Button } from '@namespace/components'
Run Code Online (Sandbox Code Playgroud)

将排除项添加到项目的jsconfig.json路径不会对建议的路径产生影响,甚至不会删除以下位置的建议/es/*

{
  "compilerOptions": {
    "target": "es6",
  },
  "exclude": [
    "**/dist/*",
    "**/coverage/*",
    "**/lib/*",
    "**/public/*",
    "**/es/*"
  ]
}
Run Code Online (Sandbox Code Playgroud)

使用“ compilerOptions”显式添加路径也无法在文件之间建立正确的关系:

{
  "compilerOptions": {
    "target": "es6",
    "baseUrl": ".",
    "paths": {
      "@namespace/components/*": [
        "./packages/namespace-components/src/*.js"
      ]
    }
  },
}
Run Code Online (Sandbox Code Playgroud)

目前,Cmd /单击来自其他程序包的导入无法打开任何内容(未找到定义)。

我应该如何配置VSCode,以便:

  1. VSCode使用命名空间的软件包作为导入值,自动建议从monorepo中的其他软件包进行导入。
  2. 使用“打开定义”会将我带到该文件的src。

根据要求,我在根目录下有一个babel配置:

const { extendBabelConfig } = require(`./packages/example/src`)

const config = extendBabelConfig({
  // Allow local .babelrc.js files to be loaded first as overrides
  babelrcRoots: [`packages/*`],
})

module.exports = config
Run Code Online (Sandbox Code Playgroud)

延伸范围:

const presets = [
  [
    `@babel/preset-env`,
    {
      loose: true,
      modules: false,
      useBuiltIns: `entry`,
      shippedProposals: true,
      targets: {
        browsers: [`>0.25%`, `not dead`],
      },
    },
  ],
  [
    `@babel/preset-react`,
    {
      useBuiltIns: true,
      modules: false,
      pragma: `React.createElement`,
    },
  ],
]

const plugins = [
  `@babel/plugin-transform-object-assign`,
  [
    `babel-plugin-styled-components`,
    {
      displayName: true,
    },
  ],
  [
    `@babel/plugin-proposal-class-properties`,
    {
      loose: true,
    },
  ],
  `@babel/plugin-syntax-dynamic-import`,
  [
    `@babel/plugin-transform-runtime`,
    {
      helpers: true,
      regenerator: true,
    },
  ],
]

// By default we build without transpiling modules so that Webpack can perform
// tree shaking. However Jest cannot handle ES6 imports becuase it runs on
// babel, so we need to transpile imports when running with jest.
if (process.env.UNDER_TEST === `1`) {
  // eslint-disable-next-line no-console
  console.log(`Running under test, so transpiling imports`)
  plugins.push(`@babel/plugin-transform-modules-commonjs`)
}

const config = {
  presets,
  plugins,
}

module.exports = config
Run Code Online (Sandbox Code Playgroud)

flo*_*olu 11

在您的情况下,我会将lernayarn workspaces结合使用。运行时yarn install,您的所有包都链接在您@namespace的全局node_modules文件夹下。有了它,您就可以获得 IntelliSense。

我在这里设置了一个示例存储库:https : //github.com/flolude/stackoverflow-lerna-monorepo-vscode-intellisense

智能预览

你只需要添加"useWorkspaces": "true"到你的lerna.json

lerna.json

{
  "packages": ["packages/*"],
  "version": "0.0.0",
  "useWorkspaces": "true"
}
Run Code Online (Sandbox Code Playgroud)

其余的只是适当的命名:

global package.json

{
  "name": "namespace",
  // ...
}
Run Code Online (Sandbox Code Playgroud)
package.json of your component package

{
  "name": "@namespace/components",
  "main": "src/index.js",
  // ...
}
Run Code Online (Sandbox Code Playgroud)
package.json of the package that imports the components

{
  "name": "@namespace/components",
  "main": "src/index.js",
  "dependencies": {
     "@namespace/components":"0.0.0"
  }
  // ...
}
Run Code Online (Sandbox Code Playgroud)

然后您可以执行以下操作:

import { Component1 } from '@namespace/components';

// your logic
Run Code Online (Sandbox Code Playgroud)

自动导入 @namespace

不幸的是,我找不到使用 Javascript Monorepo 在 VSCode 中完成这项工作的方法。但是你可以做一些事情:

  1. 使用 Typescript(教程其他教程
  2. 使用模块别名
  3. 添加import {} from '@namespace/components'到文件顶部 将导入添加到文件
  4. 使用自动导入扩展 自动导入


Und*_*ion 3

编辑:最新版本的 VSCode 已损坏。

我终于设法让它可靠地工作。您需要jsconfig.js为 monorepo 中的每个包创建一个单独的包,例如:

  • {monorepo root}/packages/some-package/jsconfig.json:
{
  "compilerOptions": {
    "target": "es6",
    "jsx": "preserve",
    "module": "commonjs"
  },
  "include": ["src/**/*.js"],
  "exclude": ["src/index.js"]
}
Run Code Online (Sandbox Code Playgroud)

请注意,我已排除该src/index.js文件,因此不会将其作为该包中的导入建议提供。

此设置似乎可以实现:

  • Intellisense 从包中导入建议,而不是使用相对路径。
  • 转到 monorepo 中其他包的源定义。

VSCode 最近很不稳定,但它似乎正在工作。

请注意,这适用于纯 JavaScript monorepo(不适用于 Typescript)。