1. 框架选型
1.1 为什么选择Nuxt3
-
首先从服务器端渲染 (SSR)角度出发,Nuxt毋庸置疑是前端开发的首选。能够提供 SEO 友好的页面加载,增强搜索引擎可见性,提升首次加载性能。
-
其次,很多网站是需要静态部署,那么Nuxt完全支持静态网站生成 (SSG),用于部署和分发不要太方便,仅仅执行
nuxt generate,就可以生成静态版本。 -
第三,nuxt是自动基于文件结构生成路由,简化了路由管理,Nuxt的路由基于vue-router,根据
pages/目录中创建的每个组件的文件名生成路由,减少了配置。
以上三点,是八青妹选择Nuxt的主要理由。当然,nuxt的强大不仅如此,可看看Nuxt官网首页的列举,中文网的截图如下:
1.2 为什么选择Monorepo 方式
在很多年前,八青妹有个刻骨铭心的经历,就是我们的项目都是从一个基线项目复制过来,这个基线项目具备其他项目所需的基础功能,某次基线的一个隐藏bug(没有测试出来,但是在生产过程中暴露)突然出现,一下子懵了,这就需要将所有从基线衍生的每个项目都重新打开进行修改,重复改了很多相同的代码😭。
后来,有了代码仓,组件封装后上传到代码仓,每个项目就通过内部代码仓去拉取组件代码。每个需要的项目中都去安装一遍,如果有改动,就更新代码仓。这样做确实节省了重复改很多相同代码的工作量。但是如果你负责的项目很多,每次这个组件都安装一遍,多了的话,就会心疼自己的磁盘空间啦😭。
Monorepo可以完美解决上面的两个痛点。
A monorepo is a single repository containing multiple distinct projects, with well-defined relationships. ——来自monorepo.tools/
Monorepo的这种代码管理策略就是上述说的:monorepo 是包含多个不同项目的单一存储库,它们之间有明确的关系。
越来越多的企业采用monorepo 管理他们的代码了。就浅浅的举一个例子,如果你看过Vue3源码也许会知道她也是采用了monorepo的方式进行代码管理吧罒ω罒。
1.3 pnpm
升级下包管理工具,pnpm的好处很多技术贴都提到过,浓缩为下面两点:
- 安装速度最快
- 节约磁盘空间
直接升级:
npm install pnpm -g
在八青妹升级pnpm的时候遇到了一个问题,就是我的pnpm无法更新到最新版本。一直说是当前最新版本了。
Run "pnpm setup" to create it automatically, or set the global-bin-dir setting, or the PNPM_HOME env variable. The global bin directory should be in the PATH.
后来排查后才知道,八青妹使用volta管理node版本,在node20版本中pnpm最新的包就是8x,安装下node最新的版本,或者不需要切换版本工具了,就卸载volta,安装了node23,pnpm也就可以顺利升级到9x。
1.4 Nuxt Tailwind
有标题称"TailwindCSS是2024 年前端最优的 CSS 框架",哈哈哈,最优的永远是用起来最顺手的,虽然标题很夸张,但是这个框架确实是各个项目用的越来越多。
如果你的项目中样式需要高度可定制且需要响应式设计,那么TailwindCSS天生就是用来做这两件事的。
优秀的人总是相互吸引,NuxtTailwind是由 Nuxt 开发的官方 Nuxt 模块,为整合 Nuxt Layers 提供了良好支持。 查看tailwindcss-nuxtjs
2. 构建项目
2.1 创建相关主体结构
首先,在本地创建一个文件夹,例如名称为monorepo-nuxt
cd monorepo-nuxt
进入到该项目的目录中,使用pnpm初始化一下
pnpm init
创建一个文件pnpm-workspace.yaml,可以在项目终端使用如下命令行创建目录,或手动添加。
touch pnpm-workspace.yaml
在pnpm-workspace.yaml中填充如下代码:
packages:
- packages/*
在项目中创建一个文件夹packages,可以在项目终端使用如下命令行创建目录,或手动添加。
mkdir packages
再进入到packages目录下,创建一个文件夹app1,创建一个文件夹app2,再创建一个文件夹ui。
cd packages
mkdir app1 app2 ui
创建了三个目录,设定app开头的是我们的主项目,ui为主项目共用的ui库。
2.2 完善下ui库
现在去ui目录下创建一个nuxt模块tailwindcss的样式框架。首先还是先创建nuxt基本框架,在提示whick package manager would you like to use?下选择pnpm。在当前目录下安装依赖包,引入nuxtjs/tailwindcss模块,初始化tailwindcss,步骤如下:
cd ui
pnpm dlx nuxi@latest init .
pnpm i
npx nuxi module add @nuxtjs/tailwindcss
npx tailwindcss init
会在ui目录下看到有个tailwind.config.js的文件。接下来,我们要做的一些改动就是为了让这个ui库就只是ui库。
- 1.删除文件夹public、server
- 2.删除文件app.vue
- 3.在
packages.json中进行修改,修改名称name和main
"name": "@monorepo-nuxt/ui",
"main": "./nuxt.config.ts",
- 4.创建目录components,在该目录下新建一个名称为
Hello.vue的组件
<template>
<h1 class="text-3xl font-bold underline">
Hello world!
</h1>
</template>
"components/ 目录是你放置所有 Vue 组件的地方,Nuxt 会自动导入该目录中的所有组件(以及您可能使用的任何模块注册的组件)",换句话就是,只要你在该目录下创建的文件,就已经是组件了,别客气,直接当组件拿来用。
2.3 在app1项目中调用ui库
进入app1项目,初始化nuxt:
cd ../app1
pnpm dlx nuxi@latest init .
pnpm i
nuxt主项目已经创建好,需要引入ui组件库,需要做的事情如下:
- 1.在app1/nuxt.config.ts下增加extends项
extends: ["@monorepo-nuxt/ui"]
通过在nuxt.config.ts 文件中添加 extends 属性来扩展图层,这是Nuxt 3 的核心功能之一。
- 2.在app1/package.json下引入ui包,上面已经将ui包的名称改为
@monorepo-nuxt/ui
"devDependencies": {
"@monorepo-nuxt/ui": "workspace:^"
}
- 3.调用下ui包中的组件库,修改app1/app.vue
<template>
<div>
<Hello></Hello>
</div>
</template>
进入到app1目录,安装下新增加的包,运行下项目:
pnpm i
pnpm dev
页面效果如下所示:
2.4 图示梳理
最后,八青妹用图示的方式梳理下上述创建ui组件包和引入的步骤:
3. 自定义扩展
通过上述步骤,app1 现在已经继承了 ui Layer,但是如果app1和app2大部分使用的是ui库中设置的tailwindcss,但是主题颜色不一致的情况,该怎么自定义呢?
这就需要在app1中创建tailwind.config.js文件,在该文件中自定义所需的设置:
export default {
theme: {
colors: {
'app': 'dark'
}
}
}
如果在ui文件包下tailwind.config.js文件中设置的内容如下:
export default {
theme: {
colors: {
'app': 'blue',
'ui': 'green',
'welcome': 'purple'
}
}
};
那么app1中的tailwind设定将会替换掉ui包中tailwind的匹配项。也就是在app1调用tailwind样式时,将会遵循:
colors: {
'app': 'dark',
'ui': 'green',
'welcome': 'purple'
}
4. 总结
八青妹本篇文章介绍的是一个非常基础的案例,如何去创建一个共用的库和如何去引用,并在公用库的基础上去拓展。这个例子绝对是monorepo中应用非常简单的了,但是来介绍monorepo的代码策略应该是清晰的。