使用rollup打包JS的方法步骤


Posted in Javascript onDecember 05, 2018

rollup 采用 es6 原生的模块机制进行模块的打包构建,rollup 更着眼于未来,对 commonjs 模块机制不提供内置的支持,是一款更轻量的打包工具。rollup 比较适合打包 js 的 sdk 或者封装的框架等,例如,vue 源码就是 rollup 打包的。而 webpack 比较适合打包一些应用,例如 SPA 或者同构项目等等。

创建项目

目录结构是这样的:

hey-rollup/
├── dist
│  ├── bundle-name.js
│  └── bundle-name.min.js
├── example
│  ├── dist
│  │  └── example.js
│  ├── index.html
│  └── index.js
├── package-lock.json
├── package.json
├── rollup.config.js
├── src
│  └── index.js
└── test
  └── index.js

你可以在你的终端中执行下面的命令来安装此项目

# cd /path/to/your/projects
git clone https://github.com/daixwu/hey-rollup.git

安装 Rollup

通过下面的命令安装Rollup:

npm install --save-dev rollup

创建配置文件

在 hey-rollup 文件夹中创建一个新文件 rollup.config.js。之后在文件中添加下面的内容:

export default {
 input: "src/main.js",
 output: {
  file: "dist/js/main.min.js",
  format: "umd",
  name: 'bundle-name'
 }
};

下面是每一个配置选项都做了些什么:

  • input —— 要打包的文件
  • output.file —— 输出的文件 (如果没有这个参数,则直接输出到控制台)
  • output.format —— Rollup 输出的文件类型 (amd, cjs, es, iife, umd)
    • amd ? 异步模块定义,用于像 RequireJS 这样的模块加载器
    • cjs ? CommonJS,适用于 Node 和 Browserify/Webpack
    • es ? 将软件包保存为 ES 模块文件
    • iife ? 一个自动执行的功能,适合作为 <script> 标签。(如果要为应用程序创建一个捆绑包,您可能想要使用它,因为它会使文件大小变小。)
  • umd ? 通用模块定义,以 amd,cjs 和 iife 为一体
  • output.name --生成包名称,代表你的 iife/umd 包,同一页上的其他脚本可以访问它(iife/umd 没有 name 会报错的)

搭配 babel 7

rollup 的模块机制是 ES6 Modules,但并不会对 es6 其他的语法进行编译。因此如果要使用 es6 的语法进行开发,还需要使用 babel 来帮助我们将代码编译成 es5。

这种强需求,rollup 当然提供了解决方案。

安装模块

rollup-plugin-babel 将 rollup 和 babel 进行了完美结合。

npm install --save-dev rollup-plugin-babel@latest

创建 .babelrc

{
  "presets": [
   [
    "@babel/preset-env",
    {
     "modules": false
    }
   ]
  ]
}

更新 rollup.config.js

import babel from "rollup-plugin-babel";

export default {
 plugins: [
  babel({
   exclude: 'node_modules/**',
  }),
 ],
};

为了避免转译第三方脚本,我们需要设置一个 exclude 的配置选项来忽略掉 node_modules 目录

babel 7 必要模块

npm install --save-dev @babel/core

npm install --save-dev @babel/preset-env

ESLint 检查

在你的代码中使用 linter 无疑是十分好的决定,因为它会强制执行一致的编码规范来帮助你捕捉像是漏掉了括弧这种棘手的 bug。

在这个项目中,我们将会使用 ESLint。

安装模块

为了使用 ESLint,我们将要安装 ESLint Rollup plugin

npm install --save-dev rollup-plugin-eslint

生成一个 .eslintrc.json

为了确保我们只获取我们想要的错误,我们需要首先配置 ESLint。这里可以通过下面的代码来自动生成大多数配置:

./node_modules/.bin/eslint --init

更新 rollup.config.js

接下来,import ESLint 插件并将它添加到 Rollup 配置中:

import eslint from 'rollup-plugin-eslint';

export default {
 plugins: [
  eslint({
   exclude: [
    throwOnError: true,
    throwOnWarning: true,
    include: ['src/**'],
    exclude: ['node_modules/**']
   ]
  }),
 ],
};

eslint插件有两个属性需要说明:throwOnError 和 throwOnWarning 设置为 true 时,如果在 eslint 的检查过程中发现了 error 或warning,就会抛出异常,阻止打包继续执行(如果设置为false,就只会输出eslint检测结果,而不会停止打包)

兼容 commonjs

npm 生态已经繁荣了多年,commonjs 规范作为 npm 的包规范,大量的 npm 包都是基于 commonjs 规范来开发的,因此在完美支持 es6 模块规范之前,我们仍旧需要兼容 commonjs 模块规范。

rollup 提供了插件rollup-plugin-commonjs ,以便于在 rollup 中引用 commonjs 规范的包。该插件的作用是将 commonjs 模块转成 es6 模块。

rollup-plugin-commonjs 通常与 rollup-plugin-node-resolve 一同使用,后者用来解析依赖的模块路径。

安装模块

npm install --save-dev rollup-plugin-commonjs rollup-plugin-node-resolve

更新 rollup.config.js

import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';

export default {
 plugins: [
  resolve({
   jsnext: true,
   main: true,
   browser: true,
  }),
  commonjs(),
  babel({
   exclude: 'node_modules/**',
  }),
 ],
};

注意: jsnext 表示将原来的 node 模块转化成 ES6 模块,main 和 browser 则决定了要将第三方模块内的哪些代码打包到最终文件中。

替代环境变量

安装模块

rollup-plugin-replace 本质上是一个用来查找和替换的工具。它可以做很多事,但对我们来说只需要找到目前的环境变量并用实际值来替代就可以了。(例如:在 bundle 中出现的所有 ENV 将被 "production" 替换)

npm install --save-dev rollup-plugin-replace

更新 rollup.config.js

配置很简单:我们可以添加一个 key:value 的配对表,key 值是准备被替换的键值,而 value 是将要被替换的值。

import replace from "rollup-plugin-replace";

export default {
 plugins: [
  replace({
   ENV: JSON.stringify(process.env.NODE_ENV || "development")
  })
 ]
};

在我们的配置中找到每一个 ENV 并用 process.env.NODE_ENV 去替换,SON.stringify 用来确保值是双引号的,不像 ENV 这样。

压缩 bundle

添加 UglifyJS 可以通过移除注上释、缩短变量名、重整代码来极大程度的减少 bundle 的体积大小 —— 这样在一定程度降低了代码的可读性,但是在网络通信上变得更有效率。

安装插件

用下面的命令来安装rollup-plugin-uglify :

npm install --save-dev rollup-plugin-uglify

更新 rollup.config.js

接下来,让我们在 Rollup 配置中添加 Uglify 。然而,为了在开发中使代码更具可读性,让我们来设置只在生产环境中压缩混淆代码:

import uglify from "rollup-plugin-uglify";

export default {
 plugins: [
  process.env.NODE_ENV === "production" && uglify()
 ]
};

这里使用了短路计算策略,只有在 NODE_ENV 设置为 production 时加载 uglify()。

完整配置

最后附上我的 rollup.config.js 配置

import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import { eslint } from 'rollup-plugin-eslint';
import babel from 'rollup-plugin-babel';
import replace from 'rollup-plugin-replace';
import { uglify } from 'rollup-plugin-uglify';

const packages = require('./package.json');

const ENV = process.env.NODE_ENV;

const paths = {
  input: {
    root: ENV === 'example'
      ? 'example/index.js'
      : 'src/index.js',
  },
  output: {
    root: ENV === 'example'
      ? 'example/dist/'
      : 'dist/',
  },
};

const fileNames = {
  development: `${packages.name}.js`,
  example: `example.js`,
  production: `${packages.name}.min.js`
};

const fileName = fileNames[ENV];

export default {
  input: `${paths.input.root}`,
  output: {
    file: `${paths.output.root}${fileName}`,
    format: 'umd',
    name: 'bundle-name'
  },
  plugins: [
    resolve(),
    commonjs(),
    eslint({
      include: ['src/**'],
      exclude: ['node_modules/**']
    }),
    babel({
      exclude: 'node_modules/**',
      runtimeHelpers: true,
    }),
    replace({
      exclude: 'node_modules/**',
      ENV: JSON.stringify(process.env.NODE_ENV),
    }),
    (ENV === 'production' && uglify()),
  ],
};

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
User Scripts: Video Download by User Scripts
May 14 Javascript
url 特殊字符 传递参数解决方法
Jan 01 Javascript
setTimeout与setInterval在不同浏览器下的差异
Jan 24 Javascript
本地图片预览(支持IE6/IE7/IE8/Firefox3)经验总结
Mar 25 Javascript
javascript 手动给表增加数据的小例子
Jul 10 Javascript
JS中for循序中延迟加载动态效果的具体实现
Aug 18 Javascript
javascript实现回车键提交表单方法总结
Jan 10 Javascript
带有定位当前位置的百度地图前端web api实例代码
Jun 21 Javascript
Angular2 Service实现简单音乐播放器服务
Feb 24 Javascript
vue教程之toast弹框全局调用示例详解
Aug 24 Javascript
基于Vue实现后台系统权限控制的示例代码
Aug 29 Javascript
JS实现判断移动端PC端功能
Feb 21 Javascript
微信小程序入门之广告条实现方法示例
Dec 05 #Javascript
Vue实现本地购物车功能
Dec 05 #Javascript
node和vue实现商城用户地址模块
Dec 05 #Javascript
解决node-sass偶尔安装失败的方法小结
Dec 05 #Javascript
用WebStorm进行Angularjs 2开发(环境篇:Windows 10,Angular-cli方式)
Dec 05 #Javascript
详解angularjs4部署文件过大解决过程
Dec 05 #Javascript
jQuery的ztree仿windows文件新建和拖拽功能的实现代码
Dec 05 #jQuery
You might like
10个实用的PHP代码片段
2011/09/02 PHP
用PHP实现Ftp用户的在线管理
2012/02/16 PHP
解析wamp5下虚拟机配置文档
2013/06/27 PHP
php定时计划任务与fsockopen持续进程实例
2014/05/23 PHP
使用PHPExcel操作Excel用法实例分析
2015/03/26 PHP
限制复选框最多选择项的实现代码
2016/05/30 Javascript
深入学习Bootstrap表单
2016/12/13 Javascript
vue中用动态组件实现选项卡切换效果
2017/03/25 Javascript
JavaScript使用readAsDataUrl方法预览图片
2017/05/10 Javascript
详解HTTPS 的原理和 NodeJS 的实现
2017/07/04 NodeJs
面包屑导航详解
2017/12/07 Javascript
Bootstrap popover 实现鼠标移入移除显示隐藏功能方法
2018/01/24 Javascript
vue-for循环嵌套操作示例
2019/01/28 Javascript
layer.open回调获取弹出层参数的实现方法
2019/09/10 Javascript
解决vue使用vant下拉框van-dropdown-item 绑定title值不变问题
2020/08/05 Javascript
vue 使用post/get 下载导出文件操作
2020/08/07 Javascript
electron踩坑之remote of undefined的解决
2020/10/06 Javascript
ES6字符串的扩展实例
2020/12/21 Javascript
[48:22]VGJ.S vs VG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python 模拟员工信息数据库操作的实例
2017/10/23 Python
Python实现扣除个人税后的工资计算器示例
2018/03/26 Python
Django学习教程之静态文件的调用详解
2018/05/08 Python
如何用Python实现简单的Markdown转换器
2018/07/16 Python
tensorflow入门:TFRecordDataset变长数据的batch读取详解
2020/01/20 Python
Python爬虫库BeautifulSoup的介绍与简单使用实例
2020/01/25 Python
通过python-pptx模块操作ppt文件的方法
2020/12/26 Python
大学生军训自我评价分享
2013/11/09 职场文书
房产销售经理职责
2013/12/20 职场文书
促销活动总结怎么写
2014/06/25 职场文书
北京离婚协议书范文2014
2014/09/29 职场文书
党委书记群众路线对照检查材料思想汇报
2014/10/04 职场文书
2015年销售员工作总结范文
2015/04/07 职场文书
交通安全月活动总结
2015/05/08 职场文书
春节随笔
2015/08/15 职场文书
家长必看:义务教育,不得以面试 评测等名义选拔学生
2019/07/09 职场文书
神州牡丹园的导游词
2019/11/20 职场文书