Skip to content

环境配置

TIP

vue3.0 采用 Monorepo 管理项目,代码采用 ts 编写,rollup 打包

一、安装依赖

依赖说明
typescript支持 ts
rollup打包工具
rollup-plugin-typescript2rollup 和 ts 的 桥梁
@rollup/plugin-node-resolve解析 node 第三方模块
@rollup/plugin-json支持引入 json
execa开启子进程方便执行命令
sh
mkdir demo
cd demo
yarn init -y

yarn add typescript rollup rollup-plugin-typescript2 @rollup/plugin-node-resolve @rollup/plugin-json execa -D

tsc --init

二、目录结构

sh
├─packages             # N个repo
  └─reactivity        # 响应式目录
  package.json
      └─src
          index.ts
  └─shared            #公共方法目录
  package.json
      └─src
  index.ts
└─scripts              # 打包命令
  build.js         # 全部打包
|  |  dev.js           # 单个打包
  package.json        # 配置运行命令
  rollup.config.js    # rollup配置文件
  tsconfig.json       # ts配置文件 更改为esnext
  yarn.lock

三、代码文件

  • 配置模块名称和打包选项
  • packages/reactivity/package.json
json
{
  "name": "@vue/reactivity", // 模块名称
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "module": "dist/reactivity.esm-bundler.js",
  "buildOptions": {
    // 打包选项
    "name": "VueReactivity", // 打包模块的全局变量名称
    "formats": [
      // 打包的输出格式
      "cjs",
      "esm-bundler",
      "global"
    ]
  }
}
  • packages/shared/package.json
json
{
  "name": "@vue/shared",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "module": "dist/shared.esm-bundler.js",
  "buildOptions": {
    "name": "VueShared",
    "formats": ["cjs", "esm-bundler"]
  }
}
  • package.json
json
{
  "private": true, //私有项目
  "workspaces": [
    // 工作目录
    "packages/*"
  ],
  "scripts": {
    // 打包脚本
    "dev": "node scripts/dev.js",
    "build": "node scripts/build.js"
  }
}
  • scripts/build.js
js
// 把packages 目录下的所有包都进行打包
// 读取文件
const fs = require("fs");
// 开启子进程 进行打包, 最终还是使用rollup来进行打包
const execa = require("execa");

// 1.读取packages下面的所有文件,并过滤出文件夹
const targets = fs
  .readdirSync("packages")
  .filter((f) => fs.statSync(`packages/${f}`).isDirectory());
// 2. 定义构建函数:开启子进程,构建rollup打包命令
async function build(target) {
  // 当子进程打包的信息共享给父进程 rollup  -c --environment TARGET:shared
  await execa("rollup", ["-c", "--environment", `TARGET:${target}`], {
    stdio: "inherit",
  });
}
// 3.定义并行打包函数:循环进行依次打包,最终返回promise.all的执行结果
function runParallel(targets, iteratorFn) {
  const res = [];
  for (const item of targets) {
    const p = iteratorFn(item);
    res.push(p);
  }
  return Promise.all(res);
}
// 4.并行打包
runParallel(targets, build);
  • scripts/dev.js
js
// 只针对把packages下具体的某个包打包
// 读取文件
const fs = require("fs");
// 开启子进程 进行打包, 最终还是使用rollup来进行打包
const execa = require("execa");

// 1.手动控制需要打包的目录
const target = "reactivity";
// 2. 定义构建函数:开启子进程,构建rollup打包命令
async function build(target) {
  // 当子进程打包的信息共享给父进程 rollup  -c --environment TARGET:shared
  await execa("rollup", ["-cw", "--environment", `TARGET:${target}`], {
    stdio: "inherit",
  });
}

// 3.单个打包
build(target);
  • rollup.config.js
js
// rollup 的配置文件
import path from "path";
import json from "@rollup/plugin-json";
import resolvePlugin from "@rollup/plugin-node-resolve";
import ts from "rollup-plugin-typescript2";

// 1.找到packages
const packagesDirs = path.resolve(__dirname, "packages");
// 2.找到具体要打包的基准目录
const packagesDir = path.resolve(packagesDirs, process.env.TARGET);
// 3.定义针对某个模块的拼接函数
const resolve = (p) => path.resolve(packagesDir, p);
// 4.找到package.json
const pkg = require(resolve("package.json"));
// 5.拿到具体文件夹名称
const name = path.basename(packagesDir);
// 6.定义打包类型的映射表,根据你提供的formats 来格式化需要打包的内容
const outputConfig = {
  "esm-bundler": {
    file: resolve(`dist/${name}.esm-bundler.js`),
    format: "es",
  },
  cjs: {
    file: resolve(`dist/${name}.cjs.js`),
    format: "cjs",
  },
  global: {
    file: resolve(`dist/${name}.global.js`),
    format: "iife",
  },
};
// 7.拿到自己包在package.json中定义的选项
const options = pkg.buildOptions;
// 8.定义函数用于创建rollup的配置文件
function createConfig(format, output) {
  // 选项覆盖和配置
  output.name = options.name;
  output.sourcemap = true;

  // 生成rollup的配置文件
  return {
    input: resolve(`src/index.ts`),
    output,
    plugins: [
      // 解析json
      json(),
      // ts配置
      ts({
        tsconfig: path.resolve(__dirname, "tsconfig.json"),
      }),
      // 解析第三方模块
      resolvePlugin(),
    ],
  };
}
// 9.导出rollup的最终配置文件
export default options.formats.map((format) =>
  createConfig(format, outputConfig[format])
);
  • tsconfig.json
js
{
  "compilerOptions": {
    "target": "ESNEXT",
    "module": "ESNEXT",
    "strict": false,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
	"moduleResolution": "node",
	"baseUrl": ".",
	"paths": {
		"@vue/*":[
			"packages/*/src"
		]
	}
  }
}

四、执行命令

sh
# 单个编译
yarn run dev

# 全部编译
yarn run build

Released under the MIT License.