rollup打包js库

前言

最近在写一个前端工具库,刚开始用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就是其中一种方法,通过它减少在项目里没有使用的代码,来减少我们打开页面的时间。

tree.png

我们再来看看对于相同的代码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 是代码格式化工具。它通过解析代码并使用自己的规则重新打印它,并考虑最大行长来强制执行一致的样式,并在必要时包装代码。支持 JavaScriptFlowTypeScriptCSSSCSSLessJSXVueGraphQLJSONMarkdown 等语言,可以结合 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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351

推荐阅读更多精彩内容