本文主要是通过分析vue2Leaflet项目中的rollup.config.js文件简单学习一下rollup的使用。
最近公司要求封装一个基于vue+leaflet的地图通用组件,根据查找资料确定在Vue2Leaflet 的基础上进行拓展封装(有兴趣的可以点击这里查看和使用)。
使用过程中,我发现该组件是用rollup进行模块打包的。虽然我的webpack还没有很明白,但是还是决定继续沿用这个rollup进行打包。因为在查过资料后
如果你需要代码拆分(Code Splitting),或者你有很多静态资源需要处理,再或者你构建的项目需要引入很多CommonJS模块的依赖,那么 webpack 是个很不错的选择。
如果您的代码库是基于 ES2015 模块的,而且希望你写的代码能够被其他人直接使用,你需要的打包工具可能是 Rollup 。
也就是说对于应用建议使用 webpack,对于类库建议使用 Rollup。
Rollup.js是一个模块打包工具,可以帮助你从一个入口文件开始,将所有使用到的模块文件都打包到一个最终的发布文件中(极其适合构建一个工具库,这也是选择用rollup来打包的原因)。
Rollup.js有两个重要的特性,其中一个就是它使用ES6的模块标准,这意味着你可以直接使用import
和export
而不需要引入babel(当然,在现在的项目中,babel可以说是必用的工具了)。
Rollup.js一个重要特性叫做'tree-shaking',这个特性可以帮助你将无用代码(即没有使用到的代码)从最终的生成文件中删去。(这个特性是基于ES6模块的静态分析的,也就是说,只有export而没有import的变量是不会被打包到最终代码中的)
废话这么多,下面直接通过分析vue2Leaflet项目中的rollup.config.js文件简单学习一下rollup的使用,以便后面新增配置。下面先介绍一下基本使用方法。
配置文件是一个ES6模块,它对外暴露一个对象,这个对象包含了一些Rollup需要的一些选项。通常,我们把这个配置文件叫做rollup.config.js
,它通常位于项目的根目录。
rollup.config.js文件中有这样一段代码。
import vue from 'rollup-plugin-vue'; // 解析vue文件的插件
import replace from 'rollup-plugin-replace'; // 变量替换,可以将动态设置的变量提取出来在配置文件中设置
import node from 'rollup-plugin-node-resolve'; // 帮助 Rollup 查找外部模块,然后安装
import cjs from 'rollup-plugin-commonjs'; // 插件将CommonJS模块转换为 ES2015 提供给 Rollup 处理
import copy from 'rollup-copy-plugin'; // 直接复制文件和文件夹。
import babel from 'rollup-plugin-babel'; // 大家都理解,方便使用 javascript 的新特性,es新特性的解析
import json from 'rollup-plugin-json'; // 读取解析json
import postcss from 'rollup-plugin-postcss'; // 提取样式文件(sass 或者 less 等)添加浏览器前缀 以及压缩
import fs from 'fs';
const baseFolder = './src/';
const componentFolder = 'components/';
const mixinFolder = 'mixins/';
const components = fs.readdirSync(baseFolder + componentFolder);
const mixins = fs.readdirSync(baseFolder + mixinFolder); // 这里是用fs.readdirSync读取文件夹所有文件
const mapEntry = (f, ext, folder) => ({
input: baseFolder + folder + f,
external: ['vue', 'leaflet'],
output: {
format: 'esm',
file: `dist/${folder}${f.replace(ext, 'js')}`
},
plugins: [
json(),
babel({
exclude: 'node_modules/**'
}),
replace({ 'process.env.NODE_ENV': 'production' }),
node({
extensions: ['.vue', '.js']
}),
cjs(),
vue({
css: true,
compileTemplate: true
})
]
});
export default [
...components.map(f => mapEntry(f, 'vue', componentFolder)), // 整个文件夹循环执行mapEntry方法处理
...mixins.map(f => mapEntry(f, 'js', mixinFolder)),
{
input: './src/utils/utils.js',
external: ['vue', 'leaflet'],
output: {
format: 'esm',
file: `dist/utils/utils.js`
},
plugins: [
json(),
cjs(),
babel({
exclude: 'node_modules/**'
}),
copy({
'src/index.js': 'dist/vue2-leaflet.es.js'
})
]
},
{
input: 'src/index.js',
external: ['vue', 'leaflet'],
output: {
format: 'umd',
name: 'Vue2Leaflet',
file: 'dist/vue2-leaflet.min.js',
globals: {
vue: 'Vue',
leaflet: 'L'
}
},
plugins: [
replace({ 'process.env.NODE_ENV': 'production' }),
node({
// 并非你要解析的所有文件都是.js文件,解析vue和js 文件
extensions: ['.vue', '.js']
}),
cjs(),
json(),
vue({
css: true,
compileTemplate: true
}),
babel({
exclude: 'node_modules/**'
})
]
}
];
上面代码的引入的插件的主要作用已经在注释中声明了,如果要了解更多插件的作用可以访问这篇文章。
下面分析一下核心的代码:
{
input: './src/utils/utils.js', // 输入
external: ['vue', 'leaflet'], // 外部引用 防止将某些 import 的包(package)打包到
// bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖
output: { // 输出
format: 'esm', // 输出的文件格式
file: `dist/utils/utils.js` // 输出的文件
},
plugins: [ // 利用插件处理 (插件作用见上方注释)
json(),
cjs(),
babel({
exclude: 'node_modules/**' // 排除node_modules文件夹下的文件
}),
copy({
'src/index.js': 'dist/vue2-leaflet.es.js' // 将index完全复制为dist/vue2-leaflet.es.js
})
]
},
当然这都是一些基本功能,高级功能我这边暂时都还没有使用,大概看了一下,也是准备什么时候用到再去具体分析。
其实rollup的还是比较容易学的,文档也很清晰。
中文的 官方文档
通过阅读官方文档的 使用配置文件(Using config files) 章节,就很容易理解配置和使用相关内容了,很明了,我觉得不用再多说了,所以我这里就不贫了,大家可以自己去看一哈。