构建纯 js 包用 rollup,如果有 图片样式就要用 webpack 构建.
一、初始化package.json
1.执行 yarn init -y
在我们创建的项目下执行 yarn init -y ,生成 package.json 文件
2.在package.json里配置构建属性
{"private": true,"name": "my-vue3","version": "1.0.0","main": "index.js","license": "MIT","workspaces": ["packages/*"],"scripts": {"dev": "node scripts/dev.js","build": "node scripts/build.js"},"dependencies": {"@rollup/plugin-json": "^4.1.0","@rollup/plugin-node-resolve": "^13.0.0","execa": "^5.1.1","rollup": "^2.52.3","rollup-plugin-typescript2": "^0.30.0","typescript": "^4.3.4"}}
私有属性”private”: true,
工作空间:workspaces
配置构建脚本scripts。
3.配置各个包的package.json
在packages 下新建包,并进入到包路径下,执行yarn init -y 生成包的 package.json 文件
配置包的package.json
{"name": "@vue/reactivity","version": "1.0.0","main": "index.js","module": "dist/reactivity.esm-bundler.js","license": "MIT","buildOptions":{"name":"VueReactivity","formats":["cjs","global","esm-bundler"]}}
{"name": "@vue/shared","version": "1.0.0","main": "index.js","module": "dist/shared.esm-bundler.js","license": "MIT","buildOptions":{"name":"VueShared","formats":["cjs","esm-bundler"]}}
name
入口
main 和 module是入口。
main 字段 是给 node 使用的,node 引用的话会默认去 main 查找,es6或者 webpack 引用 默认查找 module 
自定义构建选项
buildOptions
name:全局模块名
formats:当前包可以打包的类型,支持哪些,比如 es6,node,全局
4.build
build.js
// 打包 packages 目录下的所有的包const fs = require('fs');const execa = require('execa'); // 开启子进程进行打包const targets = fs.readdirSync('packages').filter( f => {// 过滤文件 只保留文件夹if(!fs.statSync(`packages/${f}`).isDirectory()){return false;}return true;})console.log(targets); // [ 'reactivity', 'shared' ]// 对目标文件夹进行依次打包,并行打包,每个打包有自己的构建方法async function build(target){ // 通过环境变量将要打包的目标文件信息传递给 rollupconsole.log('target',target);await execa('rollup', ['-c', '--environment', `TARGET:${target}`],{stdio: 'inherit'}) // 当前子进程的打包信息共享给父进程}function runParallel(targets,interatorFn){const res = targets.map((item) => {const p = interatorFn(item);return p})console.log('res',res);return Promise.all(res)}runParallel(targets, build)
执行 yarn build 命令会打包packages下所的包,开启子进程并行打包
readdirSync 找到 packages 目录下所有的文件夹,然后对目标文件包依次执行构建方法
打包工具是 rollup,通过环境变量将要打包的目标文件信息传递给 rollup
rollup.config.js
// rollup 配置import path from 'path'import json from '@rollup/plugin-json';import nodeResolve from '@rollup/plugin-node-resolve'import ts from 'rollup-plugin-typescript2'// 根据环境变量中的 target 属性 获取对应模块中的 package.jsonconsole.log(process.env.TARGET, 'rollup')// 找到packages 文件夹const packagesDir = path.resolve(__dirname,'packages');// packageDir 是要打包的某个包的基准目录const packageDir = path.resolve(packagesDir,process.env.TARGET) // process.env.TARGET 从环境变量传过来的包名// 访问某个包下的文件的路径const resolve = (p) => path.resolve(packageDir,p);const pkg = require(resolve('package.json'));const name = path.basename(packageDir); // 取文件名 "module": "dist/reactivity.esm-bundler.js",// 对打包类型 做一个映射表,根据 package.json 中配置的 formates 来格式化需要打包的内容const outputConfigs = {'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' // 立即执行函数}}const options = pkg.buildOptions;function createConfig(format, output) {output.name = options.name;output.sourcemap = true; // 生成sourcemap// 生成 rollup 配置return {input: resolve('src/index.js'),output,plugin:[json(),ts({ // ts 插件tsconfig: path.resolve(__dirname, 'tsconfig.json')}),nodeResolve() // 解析第三方模块]}}// 打包定义的类型export default options.formats.map( format => createConfig(format, outputConfigs[format]));
通过 process.env.TARGE 可以获取到 要打包的目标文件。
通过 path.resolve(‘package.json’) 就可以获取到 目标文件下的 package.json 文件,就能拿到 配置信息,buildOptions name, formates 等。
首先对打包类型做一个映射表
然后根据 buildOptions 里的 formates 属性 过滤出 要打包的类型。
生成 rollup 配置。
最后导出打包信息。
5.dev
执行 yarn dev 的时候会打包单个包,
// 只针对某个具体的包进行打包const fs = require('fs');const execa = require('execa'); // 开启子进程进行打包const target = 'reactivity'// 对目标文件夹进行依次打包,并行打包,每个打包有自己的构建方法async function build(target){ // 通过环境变量将要打包的目标文件信息传递给 rollupconsole.log('target',target);await execa('rollup', ['-wc', '--environment', `TARGET:${target}`],{stdio: 'inherit'}) // 当前子进程的打包信息共享给父进程}build(target)
yarn install 产生软链接
