Monorepo + Turbo (6)

vite 热加载

Vite 服务器的文件监听器默认会监听 root 目录,同时会跳过 .git/node_modules/,以及 Vite 的 cacheDirbuild.outDir 这些目录。当监听到文件更新时,Vite 会应用 HMR 并且只在需要时更新页面。

监听 node_modules 中的文件

目前没有可行的方式来监听 node_modules 中的文件。若要了解更多详情和可能的临时替代方案,你可以关注 issue #8619
注意这里作者遇到一个问题如果你排除的包中有CommonJS规范的依赖应该配合include在强制编译为 ES 模块 比如 weixin-js-sdk

复制代码
    optimizeDeps: {
      // 排除workspace依赖的预构建,确保使用最新版本
      exclude: ['@cmpay/utils', '@cmpay/components'],
      // 包含weixin-js-sdk, 因为utils中使用了weixin-js-sdk
      include: ['weixin-js-sdk']
    },

修改目录结构

创建 vitePlugins 插件

复制代码
/**
 * Vite 插件:监听 node_modules 中的特定模块
 * 解决 Vite Issue #8619 - 无法监听 node_modules 中特定依赖的问题
 * @param {string[]} modules - 需要监听的模块名数组
 */
export const pluginWatchNodeModules = modules => {
  // 将模块名合并为管道分隔的字符串,用于正则表达式的负向前瞻
  const pattern = `/node_modules\\/(?!${modules.join("|")}).*/`

  return {
    name: "watch-node-modules",
    configureServer: server => {
      server.watcher.options = {
        ...server.watcher.options,
        // 忽略除了指定模块外的所有 node_modules 内容
        ignored: [new RegExp(pattern), "**/.git/**"]
      }
    }
  }
}

页面中使用

复制代码
import { defineConfig } from "vite"
import uni from "@dcloudio/vite-plugin-uni"
import { pluginWatchNodeModules } from "monorepo-utils"
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [uni(), pluginWatchNodeModules(["monorepo-utils", "monorepo-ui"])],
  optimizeDeps: {
    // 排除workspace依赖的预构建,确保使用最新版本
    exclude: ["monorepo-utils", "monorepo-ui"]
  }
})

会报错 因为vite是node执行加载的是cjs模块

既然是cjs为啥可以使用import

请注意,即使项目未使用原生 Node ESM(例如 package.json 中的 "type": "module"),Vite 也支持在配置文件中使用 ES 模块语法。 在这种情况下,配置文件会在加载前自动进行预处理。

tsup 打包

tsup 是一个用于打包web脚本的轻量级工具,它基于 esbuild,旨在提供快速且简单的打包体验。tsup 支持多种输出格式,如 CommonJS、ES 模块、UMD 等

需要先安装它,我们先npm init,初始化基本项目项目环境,然后进行安装

复制代码
npm i tsup -D
# Or Yarn
yarn add tsup --dev
# Or pnpm
pnpm add tsup -D

在根目录下手动建一个tsup.config.ts文件,这个就是tsup的配置文件,这里我列出我的配置文件

复制代码
// packages/utils/tsup.config.ts
export default {
  entry: ["src/index.js"], // 入口文件
  format: ["esm", "cjs"], // 输出格式:esm(ES模块)、cjs(CommonJS)
  clean: true // 清理输出目录
}

修改配置文件

复制代码
{
  "name": "monorepo-utils",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "tsup",
    "dev": "tsup --watch"
  },
  "exports": {
    ".": {
      "import": "./dist/index.mjs",
      "require": "./dist/index.js"
    }
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "devDependencies": {
    "tsup": "^8.5.1"
  }
}

要先启动monorepo-utils 在启动项目比较繁琐 流程不好控制 所以使用Turbo

接入Turbo加速构建(速度与激情版)

复制代码
pnpm add turbo -D -w     # 给项目装上氮气加速

配置turbo.json(超速秘籍)

复制代码
{
  "$schema": "https://turbo.net.cn/schema.json",
  "tasks": {
    "dev": {
      "cache": false,
      "persistent": true,
      "with": ["monorepo-utils#dev"]
    },
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**"],
      "inputs": ["$TURBO_DEFAULT$", "!README.md", "env/**"]
    }
  }
}

tasks:定义可执行的 Turbo 任务集合

cache:是否启用任务缓存,false 表示每次都重新执行

persistent:是否为长期运行任务(如 dev / watch)

with:启动当前任务时,同时启动指定包的同名任务

dependsOn:任务依赖,^build 表示先执行依赖包的 build

outputs:声明构建产物目录,用于缓存命中

inputs:哪些文件变更会触发任务重新执行

TURBO_DEFAULT:Turbo 默认监控的输入文件集合

!README.md:排除 README.md 变更触发任务

env/**:env 目录变化会触发任务重新执行

复制代码
{
  "scripts": {
    "turbo:dev": "turbo dev",
    "turbo:build": "turbo build"
  }
}

首次构建(假装在加载):

复制代码
pnpm build # 这可能是你最后一次看到完整构建进度条

看我本地运行的效果,6.16s 完事。

修改后构建(真实速度):

复制代码
pnpm build # Turbo的缓存让构建像开了写轮眼👁

再 build 一把,196ms 光速完事。

复制代码
# 只跑一个包
pnpm turbo run dev --filter=app
# 看任务图
pnpm turbo run build --graph
相关推荐
fanruitian7 小时前
uniapp android开发 测试板本与发行版本
前端·javascript·uni-app
rayufo7 小时前
【工具】列出指定文件夹下所有的目录和文件
开发语言·前端·python
RANCE_atttackkk7 小时前
[Java]实现使用邮箱找回密码的功能
java·开发语言·前端·spring boot·intellij-idea·idea
2501_944525548 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 支出分析页面
android·开发语言·前端·javascript·flutter
李白你好9 小时前
Burp Suite插件用于自动检测Web应用程序中的未授权访问漏洞
前端
刘一说10 小时前
Vue 组件不必要的重新渲染问题解析:为什么子组件总在“无故”刷新?
前端·javascript·vue.js
徐同保11 小时前
React useRef 完全指南:在异步回调中访问最新的 props/state引言
前端·javascript·react.js
刘一说11 小时前
Vue 导航守卫未生效问题解析:为什么路由守卫不执行或逻辑失效?
前端·javascript·vue.js
一周七喜h12 小时前
在Vue3和TypeScripts中使用pinia
前端·javascript·vue.js
weixin_3954489112 小时前
main.c_cursor_0202
前端·网络·算法