胡乱踢 發表於 2023-3-7 16:40:00

monorepo实践:yarn workspace + vite + typescript + react

<h2 id="前言">前言</h2>
<p>最近需要用到多包管理 monorepo 开发新项目,所以提前预研一下项目搭建。</p>
<p>monorepo(monolithic repository)是一种项目架构,就是用一个仓库管理多个项目(应用,库),react和babel的源码仓库都是用这种方式在管理。</p>
<p>优缺点略过,可以参考:精读《Monorepo 的优势》。</p>
<p>因为不需要 npm 发包之类的,所以没用 lerna,就用 yarn workspace 就可以解决了,技术组合:<strong>yarn workspace + vite + typescript + react</strong>。</p>
<h2 id="使用-yarn-workspace-管理-monorepo-的依赖包">使用 yarn workspace 管理 monorepo 的依赖包</h2>
<p>通过 yarn workspace 可以管理 monorepo 的共同依赖包</p>
<p>使用命令创建一个根目录项目 <strong>workspace</strong></p>
<pre><code>yarn create vite
</code></pre>
<p>这样我们得到一个简单的基于 vite+react+ts 的脚手架项目,但其实我们只需要<strong>package.json</strong>、<strong>gitignore</strong>、<strong>tsconfig.json</strong>、<strong>tsconfig.node.json</strong>四个文件,其他的都删掉。</p>
<p>在<strong>workspace</strong>的<strong>package.json</strong>中加入配置:</p>
<pre><code>"workspaces": [
    "packages/*"
],
</code></pre>
<p>这样便可以声明我们使用 monorepo 的方式管理 packages 下的多个包。</p>
<p>在<strong>workspace</strong>根目录下创建 packages 文件夹,然后在 packages 文件夹下运行命令</p>
<pre><code>yarn create vite
</code></pre>
<p>创建多个子项目,如:@hanzilu/root、@hanzilu/mobile、@hanzilu/common。</p>
<p>此时我们直接在<strong>workspace</strong>运行命令安装 root 项目的依赖:</p>
<pre><code>yarn workspace @hanzilu/root install
</code></pre>
<p>我们会发现安装的依赖包直接安装在了<strong>workspace</strong>下的<strong>node_modules</strong>中,而不是在 @hanzilu/root 项目下。</p>
<p>在<strong>workspace</strong>下运行命令:</p>
<pre><code> yarn workspace @hanzilu/root dev
</code></pre>
<p>就可以启动 root 文件夹下的项目了。</p>
<p>不过我们不可能一个个去安装所有子项目,那么就直接在<strong>workspace</strong>下运行命令即可:</p>
<pre><code>yarn install
</code></pre>
<p>更多的一些常用命令:</p>
<ul>
<li>yarn workspaces info [--json] 显示当前各个子项目之间的依赖关系树</li>
<li>yarn workspaces add / remove / upgrade 新增、删除、更新全局依赖</li>
<li>yarn workspace add / remove / upgrade 某个子项目新增、删除、更新依赖</li>
<li>yarn worspace 执行某个项目下的命令</li>
</ul>
<h2 id="通用的-typescript-配置">通用的 typescript 配置</h2>
<p>上面的项目中并不是共用同一个 typescript 配置的,所以我们需要删除各个子项目中的<strong>tsconfig.json</strong>和<strong>tsconfig.node.json</strong>。</p>
<p>然后我们修改<strong>workspace</strong>下的<strong>tsconfig.json</strong>中 include 为:</p>
<pre><code>"include":["packages/**/src"],
</code></pre>
<p>也就是把 typescript 配置应用到这个目录下。</p>
<p>同样的<strong>tsconfig.node.json</strong>中的配置改为:</p>
<pre><code>"include": ["packages/**/vite.config.ts"]
</code></pre>
<h2 id="对本地依赖项目的处理">对本地依赖项目的处理</h2>
<p>我们使用多包管理,可能是两个不同的项目比如 @hanzilu/root 和@hanzilu/ mobile,想要使用统一的组件或者方法,这个方法在我们的 @hanzilu/common 中。</p>
<p>那么首先改造一下我们的 common 项目,在 package.json 中将添加入口:</p>
<pre><code>"main":"./src/main.tsx",
</code></pre>
<p>然后将 main.tsx 内容改为:</p>
<pre><code>const HelloWorld: React.FC = () =&gt; {
    return &lt;div className="App"&gt;HelloWorld&lt;/div&gt;;
};

export default HelloWorld;
</code></pre>
<p>现在我们的 common 就是个很简单的 HelloWorld 组件。</p>
<p>那么我们怎么去让@hanzilu/root 能够使用到这个组件呢?</p>
<p>我们就像安装依赖库一样运行命令:</p>
<pre><code>yarn workspace @hanzilu/root add @hanzilu/common@0.0.1
</code></pre>
<p>引用的时候也和依赖库一样:</p>
<pre><code>import HelloWorld from "@hanzilu/common";
</code></pre>
<p>但是到了这一步你的 typescript 提示会报错,你需要在<strong>workspace</strong>下的 tsconfig.json 加上这段配置:</p>
<pre><code>"compilerOptions": {
    //...
    "baseUrl": "./",
    "paths": {
      "@hanzilu/*": ["packages/*"]
    },
}
</code></pre>
<p>去告诉 typescript,@hanzilu/系列的包实际上是用的本地的 packages 目录下的内容。</p>
<p>至此,我们就可以正常进行项目的开发了。</p>
<h2 id="简化命令行">简化命令行</h2>
<p>在进行上面操作的时候,应该会明显感觉到命令行太长,输入太繁琐。</p>
<p>所以我们需要在 package.json 中对常用的命令,进行简化:</p>
<pre><code>"root": "yarn workspace @hanzilu/root", // 简化命令
"mobile":"yarn workspace @hanzilu/mobile",
"dev:root": "yarn root dev",// 开发root
"dev:mobile": "yarn mobile dev",
"build:root": "yarn root build", // 构建root
"build:mobile": "yarn mobile build"
</code></pre>
<h2 id="总结">总结</h2>
<p>总体而言没遇到什么大问题,挺好用的,可能也跟刚接触不知坑之深浅有关。</p>
<p>关于 react 和 vite 的部分直接省略了,如果想要了解可以查看我的这篇文章:Vite+React 搭建开发构建环境实践。</p>


</div>
<div id="MySignature" role="contentinfo">
    作者:韩子卢
<br/>
出处:https://www.cnblogs.com/vvjiang/
<br/>
本博客文章均为作者原创,转载请注明作者和原文链接。<br><br>
来源:https://www.cnblogs.com/vvjiang/p/17188539.html
頁: [1]
查看完整版本: monorepo实践:yarn workspace + vite + typescript + react