4-pnpm&&esbuild搭建vue项目

248 阅读2分钟

安装pnpm

npm i -g pnpm pnpm init 初始化项目

  • package.json
{
  "name": "vue3-learn-zf",
  "private": true,//私有的
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

pnpm 有一个问题安装包的依赖不会自动安装到node_modules下

创建 .npmrc shamefully-hoist = true (羞耻的提升) 原则上不应该这么用 重新 pnpm install

配置工作目录

  • 创建 pnpm-workspace.yaml (pnpm的配置文件)
  • 创建 packages目录
    • reactivity 目录(响应式)
      • src/index.ts
    • shared 目录 (共享目录)
      • src/index.ts
package:
  - 'packages/*' // 所有包都维护在 packages 目录下
  • 跟目录安装

pnpm install vue -w 才能放在根目录下

  • 安装 依赖

pnpm install esbuild typescript minimist(实现参数解析) -D -w

  • 用了ts需要去初始化配置文件

pnpm tsc --init -> 调用的是.bin目录下的 tsc 生成一个tsconfig.json文件

{
  "compilerOptions": {
    "outDir": "dist",//输出的目录
    "sourceMap": true,//为了调试方便
    "target": "es2016",//目标语法
    "module": "ESNext",//模块格式
    "moduleResolution": "node",//模块解析方式(node方式找包)
    "strict": false,//不启用严格模式
    "resolveJsonModule": true,//解析json模块
    "esModuleInterop": true,//允许通过es6语法引入commonjs模块
    "jsx": "preserve",//jsx不转义
    "lib": ["ESNext", "DOM"],//支持类库 exnext及dom
    // => 需要配置不然找不到文件
    "baseUrl": ".",//基础路径找模块都是按照当前模块去找的重要
    "path": {//映射表
      "@vue/*": ["packages/*/src"],//@vue/xxx的文件去 package/*/src文件下去找
    }
  }
}
  • 进入 reactivity/shared 进行初始化

pnpm init 打包的格式

  • node 中使用的叫 commonjs cjs
  • es6 esm-bundler(打包的时候是否打包成一整个还是单个的)
  • global script iife立即执行函数
//=> reactivity/package.json
{
  "name": "@vue/reactivity",
  "version": "1.0.0",
  //"main": "index.js",
  "module": "dist/reactivity.esm-bundler.js",//给构建工具去用的
  "unpkg": "dist/reactivity.global.js",
  "buildOptions": {//自定义属性
    "name": "VueReactivity",//全局的名字
    "formats": [// 打包支持什么格式
      "esm-browser",
      "esm-bundler",
      "cjs",
      "global"
    ]
  }
}
// shared/package.json 共享的文件包不用global了
{
  "name": "@vue/shared",
  "version": "1.0.0",
  "module": "dist/shared.esm-bundler.js",
  "buildOptions": {
    "formats": [
      "esm-bundler",//构建工具
      "cjs"//node
    ]
  }
}
  • reactivity依赖shared包
    • 在 reactivity目录 pnpm install @vue/shared@workspace --filter @vue/reactivity
    • @workspace当前的工作空间
    • --filter @vue/reactivity 到哪个目录下

打包流程

  • 加一个打包的命令
  • 根目录创建scripts文件夹
    • scripts/dev.js
const { build } = require('esbuild');
const path = require('path');
// 解析用户执行命令行的参数 node scripts/dev.js reactivity -f esm
const args = require("minimist")(process.argv.slice(2));
// console.log(args);//参数{ _: [ 'reactivity' ], f: 'esm' }

// 这个是打包的模块是哪一个
const target = args._[0] || 'reactivity';
const format = args.f || 'global';

// 找入口
const pkg = require(path.resolve(__dirname, `../packages/${target}/package.json`));
// 打包的格式
const outputFormat = format.startsWith('global') ? 'iife' : format === 'cjs' ? 'cjs': 'esm';

// 打包的出口
const outfile = path.resolve(__dirname, `../packages/${target}/dist/${target}.${format}.js`);

build({
  entryPoints: [path.resolve(__dirname, `../packages/${target}/src/index.ts`)],
  outfile,
  bundle: true,
  sourcemap: true,
  format: outputFormat,
  globalName: pkg.buildOptions?.name,
  platform: format === 'cjs'? 'node': 'browser',
  watch: {
    // 监听文件变化
    onRebuild(error) {
      if(!error) {
        console.log(`gogogo...`);
      }
    }
  }
}).then(() => {
  console.log("watch~~~~");
})
  • 根目录package.json
    • pnpm run dev
"scripts": {
  "dev": "node scripts/dev.js reactivity -f esm"
},
  • 后面的打包的看到这个就ok了 image.png
  • 在reavtivity文件夹下生成如下文件 image.png