VSCode 应该如何配置以支持 Lerna Monorepo?
How Should VSCode Be Configured To Support A Lerna Monorepo?
我有一个 lerna 包含很多包的 monorepo。
我正在努力实现以下目标:
- 确保 VSCode 提供从一个包到另一个包的正确导入建议(基于包名称,而不是相对路径)。
- 确保我可以 'Open Definition' 这些导入之一并被带到该文件的 src。
对于 1. 我的意思是,如果我在 package-a 中导航代码并开始键入 package-b 导出的函数,我会得到一个建议,该建议将触发添加导入:`import { example } 来自 'package-b'.
对于 2。我的意思是,如果我 alt/click 在 'package-b' 导出的函数的名称上,同时从导入它的不同包中导航文件,我将被带到 '/packages/namespace/package/b/src/file-that-contains-function.js',
我的 (lerna) monorepo 结构是标准的,例如这里有一个 'components' 包,发布为 @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
请注意,每个组件都由一个目录表示,以便它可以在必要时包含其他组件。在此示例中,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
然而,其中 none 是合适的,因为它们将呈现为从导入文件到导入文件的相对路径。在这种情况下,以下导入是正确的导入:
import { Button } from '@namespace/components'
向项目的 jsconfig.json
添加排除项对建议路径没有影响,甚至不会删除 /es/*
:
中的建议
{
"compilerOptions": {
"target": "es6",
},
"exclude": [
"**/dist/*",
"**/coverage/*",
"**/lib/*",
"**/public/*",
"**/es/*"
]
}
使用 "compilerOptions" 显式添加路径也无法在文件之间建立正确的关系:
{
"compilerOptions": {
"target": "es6",
"baseUrl": ".",
"paths": {
"@namespace/components/*": [
"./packages/namespace-components/src/*.js"
]
}
},
}
目前 Cmd/Clicking 从不同的包导入时无法打开任何内容(未找到定义)。
我应该如何配置 VSCode 以便:
- VSCode 使用命名空间包作为导入值自动建议从 monorepo 中的其他包导入。
- 使用 'Open Definition' 将我带到该文件的 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
延伸:
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
在你的情况下,我会使用 lerna in combination with yarn workspaces。
当 运行 yarn install
时,您的所有包都链接到全局 node_modules
文件夹中的 @namespace
下。这样,您就可以获得 IntelliSense。
我在这里设置了一个示例存储库:https://github.com/flolude/Whosebug-lerna-monorepo-vscode-intellisense
您只需将 "useWorkspaces": "true"
添加到您的 lerna.json
lerna.json
{
"packages": ["packages/*"],
"version": "0.0.0",
"useWorkspaces": "true"
}
剩下的只是恰当的命名:
global package.json
{
"name": "namespace",
// ...
}
package.json of your component package
{
"name": "@namespace/components",
"main": "src/index.js",
// ...
}
package.json of the package that imports the components
{
"name": "@namespace/components",
"main": "src/index.js",
"dependencies": {
"@namespace/components":"0.0.0"
}
// ...
}
然后您可以进行以下操作:
import { Component1 } from '@namespace/components';
// your logic
自动从 @namespace
导入
不幸的是,我找不到使用 Javascript Monorepo 在 VSCode 中完成这项工作的方法。但是您可以做一些事情:
- 使用打字稿(tutorial, other tutorial)
- 使用module-alias
- 将
import {} from '@namespace/components'
添加到文件顶部
- 使用 Auto Import 扩展
编辑:VSCode 的最新版本已损坏。
我终于设法让它可靠地工作了。您需要为 monorepo 中的每个包创建一个单独的 jsconfig.js
,例如:
{monorepo root}/packages/some-package/jsconfig.json
:
{
"compilerOptions": {
"target": "es6",
"jsx": "preserve",
"module": "commonjs"
},
"include": ["src/**/*.js"],
"exclude": ["src/index.js"]
}
请注意,我已经排除了 src/index.js
文件,因此它不会作为导入建议从该包中提供。
此设置似乎实现了:
- Intellisense 从包而不是使用相对路径导入建议。
- 转到 monorepo 中其他包源的定义。
VSCode 最近有点不稳定,但它似乎在起作用。
请注意,这适用于 JavaScript-only monorepo(不是 Typescript)。
我有一个 lerna 包含很多包的 monorepo。
我正在努力实现以下目标:
- 确保 VSCode 提供从一个包到另一个包的正确导入建议(基于包名称,而不是相对路径)。
- 确保我可以 'Open Definition' 这些导入之一并被带到该文件的 src。
对于 1. 我的意思是,如果我在 package-a 中导航代码并开始键入 package-b 导出的函数,我会得到一个建议,该建议将触发添加导入:`import { example } 来自 'package-b'.
对于 2。我的意思是,如果我 alt/click 在 'package-b' 导出的函数的名称上,同时从导入它的不同包中导航文件,我将被带到 '/packages/namespace/package/b/src/file-that-contains-function.js',
我的 (lerna) monorepo 结构是标准的,例如这里有一个 'components' 包,发布为 @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
请注意,每个组件都由一个目录表示,以便它可以在必要时包含其他组件。在此示例中,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
然而,其中 none 是合适的,因为它们将呈现为从导入文件到导入文件的相对路径。在这种情况下,以下导入是正确的导入:
import { Button } from '@namespace/components'
向项目的 jsconfig.json
添加排除项对建议路径没有影响,甚至不会删除 /es/*
:
{
"compilerOptions": {
"target": "es6",
},
"exclude": [
"**/dist/*",
"**/coverage/*",
"**/lib/*",
"**/public/*",
"**/es/*"
]
}
使用 "compilerOptions" 显式添加路径也无法在文件之间建立正确的关系:
{
"compilerOptions": {
"target": "es6",
"baseUrl": ".",
"paths": {
"@namespace/components/*": [
"./packages/namespace-components/src/*.js"
]
}
},
}
目前 Cmd/Clicking 从不同的包导入时无法打开任何内容(未找到定义)。
我应该如何配置 VSCode 以便:
- VSCode 使用命名空间包作为导入值自动建议从 monorepo 中的其他包导入。
- 使用 'Open Definition' 将我带到该文件的 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
延伸:
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
在你的情况下,我会使用 lerna in combination with yarn workspaces。
当 运行 yarn install
时,您的所有包都链接到全局 node_modules
文件夹中的 @namespace
下。这样,您就可以获得 IntelliSense。
我在这里设置了一个示例存储库:https://github.com/flolude/Whosebug-lerna-monorepo-vscode-intellisense
您只需将 "useWorkspaces": "true"
添加到您的 lerna.json
lerna.json
{
"packages": ["packages/*"],
"version": "0.0.0",
"useWorkspaces": "true"
}
剩下的只是恰当的命名:
global package.json
{
"name": "namespace",
// ...
}
package.json of your component package
{
"name": "@namespace/components",
"main": "src/index.js",
// ...
}
package.json of the package that imports the components
{
"name": "@namespace/components",
"main": "src/index.js",
"dependencies": {
"@namespace/components":"0.0.0"
}
// ...
}
然后您可以进行以下操作:
import { Component1 } from '@namespace/components';
// your logic
自动从 @namespace
导入
不幸的是,我找不到使用 Javascript Monorepo 在 VSCode 中完成这项工作的方法。但是您可以做一些事情:
- 使用打字稿(tutorial, other tutorial)
- 使用module-alias
- 将
import {} from '@namespace/components'
添加到文件顶部 - 使用 Auto Import 扩展
编辑:VSCode 的最新版本已损坏。
我终于设法让它可靠地工作了。您需要为 monorepo 中的每个包创建一个单独的 jsconfig.js
,例如:
{monorepo root}/packages/some-package/jsconfig.json
:
{
"compilerOptions": {
"target": "es6",
"jsx": "preserve",
"module": "commonjs"
},
"include": ["src/**/*.js"],
"exclude": ["src/index.js"]
}
请注意,我已经排除了 src/index.js
文件,因此它不会作为导入建议从该包中提供。
此设置似乎实现了:
- Intellisense 从包而不是使用相对路径导入建议。
- 转到 monorepo 中其他包源的定义。
VSCode 最近有点不稳定,但它似乎在起作用。
请注意,这适用于 JavaScript-only monorepo(不是 Typescript)。