在实际项目开发中无论 M 端、PC 端,或多或少都有一个 utils 文件目录去管理项目中用到的一些常用的工具方法,比如:时间处理、价格处理、解析url参数、加载脚本等,其中很多是重复、基础、或基于某种业务场景的工具,存在项目间冗余的痛点以及工具方法规范不统一的问题。
构建工具库底层架构大概需要哪些功能的支持:
在对底层架构设计的基础上,首先需要把用到的依赖库简单熟悉一下:
• rollup(工具库打包构建核心包)
• rollup-plugin-livereload(rollup 插件,热更新,方便本地 debugger 开发)
• rollup-plugin-serve(rollup 插件,本地服务代理,方便在本地 html 中调试工具)
• rollup-plugin-terser(rollup 插件,代码压缩混淆)
• rollup-plugin-visualizer(rollup 插件,可视化并分析 Rollup bundle,以查看模块占用)
• @rollup/plugin-babel(rollup 插件,rollup 的 babel 插件,ES6 转 ES5)
• @rollup/plugin-commonjs(rollup 插件,用来将 CommonJS 模块转换为 ES6,这样它们就可以包含在 Rollup 包中)
• @rollup/plugin-json(rollup 插件,它将.json 文件转换为 ES6 模块)
• @rollup/plugin-node-resolve(rollup 插件,它使用节点解析算法定位模块,用于在节点模块中使用第三方 node_modules 包)
• @rollup/plugin-typescript(rollup 插件,对 typescript 的支持,将 typescript 进行 tsc 转为 js)
• typescript(使用 ts 开发工具库)
• tslib(TypeScript 的运行库,它包含了 TypeScript 所有的帮助函数)
• @typescript-eslint/eslint-plugin(TypeScript 的 eslint 插件,约束 ts 书写规范)
• @typescript-eslint/parser(ESLint 解析器,它利用 TypeScript ESTree 来允许 ESLint 检测 TypeScript 源代码)
• typedoc(TypeScript 项目的文档生成器)
• gulp(使用 gulp 构建文档系统)
• gulp-typedoc(Gulp 插件来执行 TypeDoc 工具)
• browser-sync(文档系统热更新)
• jest(一款优雅、简洁的 JavaScript 测试框架)
• @types/jest(Jest 的类型定义)
• ts-jest(一个支持源映射的 Jest 转换器,允许您使用 Jest 来测试用 TypeScript 编写的项目)
• @babel/preset-typescript(TypeScript 的 Babel 预设)
• eslint(代码规范约束)
• @babel/core(@rollup/plugin-babel 依赖的 babel 解析插件)
• @babel/plugin-transform-runtime(babel 转译依赖)
• @babel/preset-env(babel 转译依赖)
• chalk(控制台字符样式)
• rimraf(UNIX 命令 rm -rf 用于 node)
• cross-env(跨平台设置 node 环境变量)
新建一个文件夹 utils-demo,执行 npm init,过程会询问构建项目的基本信息,按需填写即可:
npm init
创建工具库业务开发 src 文件目录,明确怎样规划工具库包,里面放置的是工具库开发需要的业务代码:
要对 typescript 代码进行解析支持需要安装对 ts 支持的依赖,以及对开发的工具的一些依赖包:
yarn add typescript tslib rollup rollup-plugin-livereload rollup-plugin-serve rollup-plugin-terser rollup-plugin-visualizer
@rollup/plugin-babel @rollup/plugin-commonjs @rollup/plugin-json @rollup/plugin-node-resolve @rollup/plugin-typescript
@babel/core @babel/plugin-transform-runtime @babel/preset-env rimraf lodash chalk@^4.1.2 -D
这里遇到一个坑,关于最新 chalk5.0.0 不支持在 nodejs 中 require()导入,所以锁定包版本 chalk@^4.1.2
要对 typescript 进行解析和编译还需要配置 tsconfig.json,该文件中指定了用来编译这个项目的根文件和编译选项,在项目根目录,使用 tsc --init 命令快速生成 tsconfig.json 文件(前提全局安装 typescript)
npm i typescript -g
tsc --init
初始化 tsconfig 完成之后,根目录自动生成 tsconfig.json 文件,需要对其进行简单的配置,以适用于 ts 项目,其中具体含义可以参考tsconfig.json官网
生成rollup配置项函数核心代码:
const moduleName = camelCase(name) // 当format为iife和umd时必须提供,将作为全局变量挂在window下:window.moduleName=...
const banner = generateBanner() // 包说明文案
// 生成rollup配置文件函数
const generateConfigs = (options) => {
const { input, outputFile } = options
console.log(chalk.greenBright(`获取打包入口:${input}`))
const result = []
const pushPlugins = ({ format, plugins, ext }) => {
result.push({
input, // 打包入口文件
external: [], // 如果打包出来的文件有项目依赖,可以在这里配置是否将项目依赖一起打到包里面还是作为外部依赖
// 打包出口文件
output: {
file: `${outputFile}${ext}`, // 出口文件名称
sourcemap: true, // // 是否生成sourcemap
format, // 打包的模块化格式
name: moduleName, // 当format为iife和umd时必须提供,将作为全局变量挂在window下:window.moduleName=...
exports: 'named' /** Disable warning for default imports */,
banner, // 打包出来的文件在最顶部的说明文案
globals: {} // 如果external设置了打包忽略的项目依赖,在此配置,项目依赖的全局变量
},
plugins // rollup插件
})
}
buildType.forEach(({ format, ext }) => {
let plugins = [...defaultPlugins]
// 生产环境加入包分析以及代码压缩
plugins = [
...plugins,
visualizer({
gzipSize: true,
brotliSize: true
}),
terser()
]
pushPlugins({ format, plugins, ext })
})
return result
}
{
"presets": [
[
"@babel/preset-env"
]
],
"plugins": ["@babel/plugin-transform-runtime"]
}
"scripts": {
"build": "rimraf lib && rollup -c ./scripts/rollup.config.js" // rollup打包
},
项目搭建到这里,不知机智的你能否发现问题:
• 我想使用该包里面 date 相关工具,要这样吗?
import { dateA, dateB, dateC } from "utils-demo"
能不能这样?
import { date } from "utils-demo"
date.dateA()
date.dateB()
date.dateC()
• 在一些使用 script 脚本引入的场景下,就仅仅需要 date 相关的工具,要这样吗?