使用mono-repo实现跨项目组件共享 (4)

这个例子中admin-site和customer-site需要的antd版本都是3.1.0,但是common需要的版本却是4.9.4,如果使用lerna bootstrap --hoist来进行提升,lerna会提升用的最多的版本,也就是3.1.0到顶层,然后把子项目的node_modules里面的antd都删了。也就是说common去访问antd的话,也会拿到3.1.0的版本,这可能会导致common项目工作不正常。

这时候就需要介绍yarn workspace 了,他可以解决前面说的版本不一致的问题,lerna bootstrap --hoist会把所有子项目用的最多的版本移动到顶层,而yarn workspace 则会检查每个子项目里面依赖及其版本,如果版本不一样则会留在子项目自己的node_modules里面,只有完全一样的依赖才会提升到顶层。

还是以上面这个antd为例,使用yarn workspace的话,会把admin-site和customer-site的3.1.0版本移动到顶层,而common项目下会保留自己4.9.4的antd,这样每个子项目都可以拿到自己需要的依赖了。

yarn workspace使用也很简单,yarn 1.0以上的版本默认就是开启workspace的,所以我们只需要在顶层的package.json加一个配置就行:

// 顶层package.json { "workspaces": [ "packages/*" ] }

然后在lerna.json里面指定npmClient为yarn,并将useWorkspaces设置为true:

// lerna.json { "npmClient": "yarn", "useWorkspaces": true }

使用了yarn workspace,我们就不用lerna bootstrap来安装依赖了,而是像以前一样yarn install就行了,他会自动帮我们提升依赖,这里的yarn install无论在顶层运行还是在任意一个子项目运行效果都是一样的。

启动子项目

现在我们建好了三个子项目,要启动CRA子项目,可以去那个目录下运行yarn start,但是频繁切换文件夹实在是太麻烦了。其实有了lerna的帮助我们可以直接在顶层运行,这需要用到lerna的这个功能:

lerna run [script]

比如我们在顶层运行了lerna run start,这相当于去每个子项目下面都去执行yarn run start或者npm run start,具体是yarn还是npm,取决于你在lerna.json里面的这个设置:

"npmClient": "yarn"

如果我只想在其中一个子项目运行命令,应该怎么办呢?加上--scope就行了,比如我就在顶层的package.json里面加了这么一行命令:

// 顶层package.json { "scripts": { "start:aSite": "lerna --scope @mono-repo-demo/admin-site run start" } }

所以我们可以直接在顶层运行yarn start:aSite,这会启动前面说的管理员站点,他其实运行的命令还是lerna run start,然后加了--scope来指定在管理员子项目下运行,@mono-repo-demo/admin-site就是我们管理员子项目的名字,是定义在这个子项目的package.json里面的:

// 管理员子项目package.json { "name": "@mono-repo-demo/admin-site" }

然后我们实际运行下yarn start:aSite吧:

image-20201231155954580

看到了我们熟悉的CRA转圈圈,说明到目前为止我们的配置还算顺利,哈哈~

创建公共组件

现在项目基本结构已经有了,我们建一个公共组件试一下效果。我们就用antd创建一个交水费的表单吧,也很简单,就一个姓名输入框,一个查询按钮。

// packages/common/components/WaterForm.js import { Form, Input, Button } from 'antd'; const layout = { labelCol: { span: 8, }, wrapperCol: { span: 16, }, }; const tailLayout = { wrapperCol: { offset: 8, span: 16, }, }; const WaterForm = () => { const onFinish = (values) => { console.log('Success:', values); }; const onFinishFailed = (errorInfo) => { console.log('Failed:', errorInfo); }; return ( <Form {...layout} initialValues={{ remember: true, }} onFinish={onFinish} onFinishFailed={onFinishFailed} > <Form.Item label="姓名" rules={[ { required: true, message: '请输入姓名', }, ]} > <Input /> </Form.Item> <Form.Item {...tailLayout}> <Button type="primary" htmlType="submit"> 查询 </Button> </Form.Item> </Form> ); }; export default WaterForm; 引入公共组件

这个组件写好了,我们就在admin-site里面引用下他,要引用上面的组件,我们需要先在admin-site的package.json里面将这个依赖加上,我们可以去手动修改他,也可以使用lerna命令:

lerna add @mono-repo-demo/common --scope @mono-repo-demo/admin-site

这个命令效果跟你手动改package.json是一样的:

image-20201231161945744

然后我们去把admin-site默认的CRA圈圈改成这个水费表单吧:

image-20201231162333590

然后再运行下:

image-20201231162459416

嗯?报错了。。。如果我说这个错误是我预料之中的,你信吗

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwgfdd.html