Skip to content

鼓励作者:欢迎 star 或打赏犒劳

Rollup 打包配置

在 Monorepo 项目中配置 Rollup 打包,同时也是重构 tampermonkey-scripts 项目的踩坑和总结,如需完整代码,可以查看该项目源码

Rollup 是一个用于 JavaScript 的模块打包工具,常用于类库的打包,其打包速度快、体积小

配置 Rollup 打包

在 Monorepo 项目中,每一个子包都是独立的项目,所以需要在每个子包中配置 Rollup 打包,而每个子包的基础配置都是相同的,所以我们可以把 Rollup 的一些公共配置抽离出来,然后在每个子包中引入,从而实现代码的复用

同时为了方便管理和简化使用,可以把公共配置抽离到一个单独的子包中,并将其安装为公共依赖

初始化 rollup-config 子包

sh
npm init -w shared/rollup-config -y

# 删除 package.json 中的 workspaces 属性
npm pkg delete workspaces

修改 pnpm-workspace.yaml

内容如下:

yaml
packages:
  - 'packages/*'
  - 'shared/*'

修改 package.json

如果仅在 Monorepo 项目中使用,可以将 private 属性设置为 true,防止被发布到 npm

jsonc
{
  "name": "@femm/shared-rollup-config",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "main": "src/index.js"
  // 其他配置可以根据需要自行添加
}

安装依赖

rollup 为公共依赖(每一个子包都需要使用 rollup 命令)

sh
# 安装 rollup
pnpm add -Dw rollup

rollup 插件为 rollup-config 子包的私有依赖

sh
pnpm -F "shared/rollup-config" add @rollup/plugin-terser rollup-plugin-postcss rollup-plugin-swc3 rollup-plugin-userscript-metablock

编写公共配置

创建 src/index.js,内容如下:

js
import path from 'node:path'
import { defineConfig } from 'rollup'
import postcss from 'rollup-plugin-postcss'
import { swc } from 'rollup-plugin-swc3'
import terser from '@rollup/plugin-terser'
import metablock from 'rollup-plugin-userscript-metablock'

export function createRollupConfig({ pkg, plugins = [] }) {
  const file = path.resolve(
    '../../',
    process.env.BUILD === 'development' ? 'dist-dev' : 'dist',
    `${pkg.name}.user.js`,
  )

  return defineConfig({
    input: 'src/index.ts',
    output: {
      file,
      format: 'iife',
    },
    plugins: [
      ...plugins,
      // 处理 CSS
      postcss({ minimize: true }),
      // 处理 JavaScript 和 TypeScript
      swc({
        jsc: { target: 'es5' },
      }),
      // 删除注释
      terser({
        mangle: {
          keep_fnames: true,
        },
        compress: {
          defaults: false,
        },
        format: {
          ascii_only: true,
          beautify: true,
          indent_level: 2,
        },
      }),
      // 注入脚本元数据
      metablock({
        override: {
          /* https://greasyfork.org/zh-CN/help/meta-keys */
          version: pkg.version,
          author: 'maomao1996',
          homepage: 'https://github.com/maomao1996/tampermonkey-scripts',
          supportURL: 'https://github.com/maomao1996/tampermonkey-scripts/issues',
          license: 'MIT',
        },
      }),
    ],
  })
}

在其他子包中使用 rollup-config 子包

安装 rollup-config 子包

sh
pnpm add -Dw @femm/shared-rollup-config

在子包中创建 rollup.config.js,内容如下:

js
import { createRollupConfig } from '@femm/shared-rollup-config'

import pkg from './package.json' assert { type: 'json' }

export default createRollupConfig({ pkg })

修改子包的 package.json,内容如下:

jsonc
{
  "name": "kill-watermark",
  "version": "0.0.2",
  "private": true,
  "type": "module",
  "scripts": {
    "build": "rollup -c",
    "dev": "rollup --environment BUILD:development -c --watch"
  }
}
  • --environment BUILD:development 表示注入 BUILD 环境变量,值为 development
  • -c 表示使用配置文件
  • --watch 表示监听文件变化

修改主包的 package.json

jsonc
{
  // ... 省略其他配置
  "scripts": {
    "build": "pnpm -r build",
    "dev": "pnpm --stream --parallel -r dev",
  }
  // ... 省略其他配置
}

相关资料

配置 TypeScript

安装 TypeScript

sh
pnpm add -Dw typescript

方案一:配置统一的 tsconfig.json

在主包中创建 tsconfig.json,内容如下:

json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "lib": ["DOM", "ES2022"],

    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,

    "strict": true,
    "skipLibCheck": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": ["packages/**/*.ts", "shared/**/*.ts", "types/*.d.ts"]
}

方案二:在每个子包中配置 tsconfig.json

为了方便管理和简化使用,同样将公共的 tsconfig.json 配置封装成一个子包中,并将其安装为公共依赖

创建 tsconfig 子包

sh
npm init -w shared/tsconfig -y

# 删除 package.json 中的 workspaces 属性
npm pkg delete workspaces

修改 tsconfig 子包的 package.json

json
{
  "name": "@femm/shared-tsconfig",
  "version": "1.0.0",
  "private": true
}

tsconfig 子包中创建 tsconfig.json 文件,内容如下:

json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "lib": ["DOM", "ES2022"],

    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,

    "strict": true,
    "skipLibCheck": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true
  }
}

在主包中安装 tsconfig 子包

sh
pnpm add -Dw @femm/shared-tsconfig

在每个子包中创建 tsconfig.json 文件,内容如下:

json
{
  "extends": "@femm/shared-tsconfig"
}

在所有子包中共享 TypeScript 类型

在 TypeScript 项目中,其会自动加载 node_modules/@types 中的类型,所以我们可以把类型放到 node_modules/@types 中,从而在所有子包中共享

创建 types 子包

sh
npm init -w shared/types -y

# 删除 package.json 中的 workspaces 属性
npm pkg delete workspaces

修改 pnpm-workspace.yaml,内容如下:

yaml
packages:
  - 'packages/*'
  - 'types'

修改 types 子包的 package.json

jsonc
{
  "name": "@types/shared-types",
  "version": "1.0.0",
  "private": true,
  "types": "./index.d.ts"
}

WARNING

子包的 name 必须要以 @types/ 开头,否则 TypeScript 无法自动加载

编写 index.d.ts

ts
declare const unsafeWindow: Window

在主包中安装 types 子包

sh
pnpm add -Dw @types/shared-types

相关资料

参考了 tsconfig/bases | GitHub 的相关代码

如有转载或 CV 的请标注本站原文地址