前言
最近在写一个前端工具库,刚开始用webpack搭建,但是偶然间发现rollup的介绍,发现rollop更满足我的需求。这篇文章介绍了用rollup搭建一个简单版的js工具库。
需求
代码层面
1.编写:支持ES6语法(支持异步) 对传参有要求
2.提交:提交代码有规范
3.测试:代码测试-单元测试
4.注释:生成相应的文档说明
功能层面:
1.使用:主流浏览器使用;eg:chrome,firefox
2.js方法
3.引用:会引用了其它的库
显然,在打包时,我们第一时间会想到的就是webpack,但是我在实际中发现有更适合我的需求的打包框架,就是rollup。下面我们来看看他们的区别。
webpack VS Rollup
1.入口文件
webpack和rollup都需要一个配置文件,来指定入口,输出,插件等
webpack | rollup | |
---|---|---|
相对路径 | 不支持,使用path.resolve | 支持 |
这只是其中一个简单的区别,我们再来看看以下几个区别
2.死代码消除(tree-shaking)
当我们打开一个网页,如图,只有页面加载完相关资源(eg:js,图片)页面才会显示出来。如果我们需要加载的资源体积越小,当然我们打开页面的时间就会缩短。如何缩小我们需要资源的大小呢,tree-shaking就是其中一种方法,通过它减少在项目里没有使用的代码,来减少我们打开页面的时间。
我们再来看看对于相同的代码webpack和rollup打包的结果
相同的代码 | webpack | rollup |
---|---|---|
执行时间 | 71ms | 17ms |
文件大小 | 389KB | 262KB |
主要原因就是rollup使用了tree-shaking,利用了es6模块特性,促使了mudle进行静态分析,在uglify阶段删除了无用代码。
至于什么是es6规范呢,如下:
- 只能作为模块顶层的语句出现(import和export语句只能出现在代码顶层)
- import的模块只能是字符串变量,不能使用字符串和变量
- 引入模块不能再进行修改
// 情况1
let str = '只能作为模块顶层的语句出现';
import { sum} from 'util' ;
// 情况2
import { 's'+'um'} from 'util';
//情况3
import {sum} from 'util'
sum=1;// Syntax Error : 'a' is read-only;
3.实时加载
webpack:使用webpack-dev-server插件
rollup:rollup-plugin-serve+rollup-plugin-livereload 。
webpack实时加载的定制型更强,比如添加中间件,指定运行使用的文件。
更多的比较可去查看。
总结一下:
webpack
生态圈丰富 (文档更完整,插件库丰富)
拆分代码,按需加载 利用插件支持tree-shaking(webpack 2以上)
webpack会产生很多额外的代码,
打包文件较大 执行较慢 可读性弱
适用涉及到css html 静态资源处理 复杂的代码拆分合并或者 应用
rollup
插件生态相对较弱 把所有资源放在同一个地方,一次性加载 利用tree-shaking缩小包体积
一般不会产生额外的代码,执行更快,可读性更强
rollup多适用于基础库
我们再来梳理一下我们的需求:
1.只需要实现js常用方法 --rollup
2.语法:支持类型 --TypeScript
3.规范:编码规范 --ESLint&Prettier
4.提交:提交有要求 --Husky&commitlint
5.质量:测试用例 --jest
下面开始我们的项目搭建啦
初始化项目
a.创建文件夹 rollup-demo
b.npm init -y 初始化
c.安装 rollup和每次打包清除dist目录插件 npm i rollup rollup-plugin-clear -D
d.创建入口文件src/main.js
function fun1(){
function fun2(){
return 'no'
}
return 'yes'
}
fun1()
console.log(fun1())
function Useless(){
console.log(1111)
}
e.在根目录下创建rollup.config.js
'use strict';
import clear from 'rollup-plugin-clear';
export default {
input: 'src/main.ts',
output: {
file: 'dist/bundle.js',
format: 'umd', //打包文件格式
},
plugins: [
clear({targets: ['dist']}), //清除dist目录
],
};
f.在package下添加命令
"build": "rollup -c rollup.config.js",
执行npm run build
一个简单的rollup打包项目完成了。
使用ts
为什么使用ts呢,ts是静态类型,js是动态类型;静态类型对阅读代码是友好的;同时IDE提供的大量便捷支持和TS本身的语法检查和代码提示自动补全让开发者提高效率,方便重构等。当然,TypeScript 只是为 JavaScript 中本身就存在的使用方式提供了对应的类型标注,所有在 TypeScript 中能够使用的开发模式,在 JavaScript 中一定是本身就存在的。
a. 安装依赖库
typescript:编译 typescript 语法的基础库
rollup-plugin-typescript2:结合 rollup 编译 typescript 的 plugins
npm i rollup-plugin-typescript2 typescript -D
b. rollup.config.js配置
rollup.config.js
import ts from "rollup-plugin-typescript2";
export default {
input: "./src/main.ts",
plugins: [
ts({
useTsconfigDeclarationDir: true
}),
]
}
useTsconfigDeclarationDir:指定生成声明文件存放目录。
c.配置 tsconfig.json
{
"compilerOptions": {
"target": "es5",// 编译目标
"module":"es2015",// 模块类型
"lib": ["es2015", "es2016", "es2017"],// 导入库类型定义
"strict": true,// 严格模式
"sourceMap": true,// 生成定义sourceMap
"strictNullChecks": true, // 不允许把null、undefined赋值给其他类型的变量
"declaration": true,// 生成定义文件
"declarationDir": "dist/types",//类型声明文件位置 自动创建声明文件(.d.ts)
"noUnusedLocals": true, // 未使用变量报错
"outDir": "./dist", // 编译输出目录
"typeRoots": [ //typeRoots 用来指定默认的类型声明文件查找路径,默认为 node_modules/@types
"node_modules/@types"
]
}
}
** ESLint & Prettier**
ESLint 对应的是代码语法质量规则,Prettier 对应的是格式化规则。**
ESLint 是一个插件化的 javascript 代码检测工具,它可以用于检查常见的 JavaScript 代码错误,也可以进行代码风格检查,这样我们就可以根据自己的喜好指定一套 ESLint 配置,然后应用到所编写的项目上,从而实现辅助编码规范的执行,有效控制项目代码的质量。
prettier 是代码格式化工具。它通过解析代码并使用自己的规则重新打印它,并考虑最大行长来强制执行一致的样式,并在必要时包装代码。支持 JavaScript
、 Flow
、 TypeScript
、 CSS
、 SCSS
、 Less
、 JSX
、 Vue
、 GraphQL
、 JSON
、 Markdown
等语言,可以结合 ESLint 和 Prettier,检测代码中潜在问题的同时,还能统一团队代码风格,从而促使写出高质量代码,来提升工作效率。
a.安装依赖
- eslint:eslint 核心库,负责整个 eslint 的调度工作
- @typescript-eslint/parser:ESLint的解析器,用于解析typescript,从而检查和规范Typescript代码
- @typescript-eslint/eslint-plugin:ESLint插件,包含了各类定义好的检测 typescript 代码的规范
- prettier:prettier 核心库
- eslint-config-prettier:解决 ESLint 中的样式规范和 prettier 中样式规范的冲突,以 prettier 的样式规范为准,使 ESLint 中的样式规范自动失效
- eslint-plugin-prettier:将 prettier 的规范作为 ESLint 规范来使用
npm i eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin prettier eslint-config-prettier eslint-plugin-prettier -D
b.创建 .eslintrc.js
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 2019,
sourceType: 'module',
},
extends: [
'plugin:@typescript-eslint/recommended',
'prettier/@typescript-eslint',
'plugin:prettier/recommended',
],
env: {
es6: true,
node: true,
},
rules: {
"no-undef": "error",
"eqeqeq": "error",
"no-console": "error"
},
};
c.创建.prettierrc.js
module.exports = {
arrowParens: 'avoid',
bracketSpacing: false,
endOfLine: 'lf',
jsxBracketSameLine: false,
jsxSingleQuote: false,
printWidth: 100,
proseWrap: 'preserve',
semi: true,
singleQuote: true,
// tabWidth: 4,
useTabs: false,
trailingComma: 'es5',
};
提交代码规范 Husky & lint-staged & Commitlint
**Husky **是一个 git hook 辅助工具,能够在 git 文件状态变更时,执行一些操作。husky能够防止不规范代码被commit、push、merge等等
**lint-staged **能监测到所有提交变动的文件,对其执行一系列命令,如 prettier 对不符合规范的代码进行 fix。
**commitlint **顾名思义就是进行提交代码 git commit -m 'xxxxx' 时,检查提交记录 message 的,commitlint 能够抵挡住不符合规范的 message 记录,如 git commit -m 'add eslint' 这就是一个不符合规范的 commit ,因为他没有加上对应的 commit type 类别,add eslint 对应的类别应该是 chore (构建过程或辅助工具的变动)
**a.安装依赖 **
- husky:git hook 辅助工具
- lint-staged:监测变动文件并执行命令
- @commitlint/cli:commitlint 核心工具库
- @commitlint/config-conventional:一些 commitlint 规则预设
npm i husky lint-staged -D
npm i @commitlint/cli @commitlint/config-conventional -D
b.创建huskyrc.js
module.exports = {
hooks: {
'commit-msg': 'commitlint -e $HUSKY_GIT_PARAMS',
'pre-commit': 'lint-staged',// 在 pre-commit commit 前的阶段,执行 lint-staged 中的命令。
},
};
c.创建 lint-staged.config.js
module.exports = {
'{src,test}/**/*.ts': [
'npm run lint',
'git add'
]
};
d.创建commitlint.config.js
module.exports = {
extends: [
"@commitlint/config-conventional"
],
rules: {// 自定义配置
'subject-case': [2, 'always', ['upper-case']]
}
};
**jest测试
**Jest 是用来创建、执行和构建测试用例的一个 JavaScript 测试 库。可以在任何项目中安装使用它,如 Vue/React/Angular/Node/TypeScript 等。
简单总结一下,Jest 具有以下优点:
- 测试用例并行执行,更高效
- 强大的 Mock 功能
- 内置的代码覆盖率检查,不需要在引入额外的工具
- 集成 JSDOM,可以直接进行 DOM 相关的测试
- 开箱即用,几乎不需要额外配置
- 可以直接对 ES Module Import 的代码测试
- 有快照测试功能,可对 React 等框架进行 UI 测试
a.安装依赖
- jest:集成测试框架
- @types/jest: jest 的类型定义包,在 typescript 环境下使用 jest 需要用到
- ts-jest:测试 typescript 代码的转换工具
npm i jest @types/jest ts-jest -D
b.创建 jest.config.js
module.exports = {
// 测试目录
roots: ['<rootDir>/test'],
// 对 ts tsx 文件使用 ts-jest 进行运行测试
transform: {
'.(ts|tsx)': 'ts-jest',
},
// 测试环境
testEnvironment: 'node',
// 测试文件匹配
testRegex: '(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$',
collectCoverage: true,
// 不计入覆盖率中
coveragePathIgnorePatterns: ['/node_modules/', '/test/'],
// 覆盖率达标阈值,不达标即测试失败,抛出 error
coverageThreshold: {
global: {
branches: 90,
functions: 95,
lines: 95,
statements: 95,
},
},
};
c.在根目录下创建 test/main.test.ts
import Sum from '../src/main'
test('sum is right', () => {
expect(Sum(1, 2)).toBe(10);
});
**d.package.json 加上新的 script 指令 "test": "jest" **
**
总结
本篇文章讲解了webpack和rollup的区别,用rollup搭建了一个简单版js库,也使用了TS,ESLint和Prettier 规范代码规范和提交代码的规范和使用jest来保障代码的质量。代码已上传到github。https://github.com/turning1998/baselib