Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup初探 #41

Open
huruji opened this issue May 23, 2018 · 0 comments
Open

Rollup初探 #41

huruji opened this issue May 23, 2018 · 0 comments

Comments

@huruji
Copy link
Owner

huruji commented May 23, 2018

1.基本操作

安装

npm i -g rollup

打包成文件

rollup src/main.js -o bundle.js -f cjs

等价于

rollup src/main.js -f cjs > bundle.js

需要注意的是参数 -f--output.format 的缩写,用来指定 bundle 的类型,有以下选项:

amd:amd规范
cjs:CommonJS规范
es:es规范
iife:立即执行函数
umd:umd规范(语法糖)

2.使用配置文件

默认文件名称为 rollup.config.js

基本使用

export default{
    input: "src/main.js",
    output: {
        file: "bundle.js",
        format: "cjs"
    }
}

打包:

rollup -c

等价于

rollup --config

使用插件

通过在配置文件中使用 plugins 字段添加插件。

如:

  • 使用 rollup-plugin-json 插件来处理json文件

  • 使用 rollup-plugin-node-resolve 插件来处理外部模块(rollup默认无法处理外部模块,也就是说无法解析打包从npm上下载使用的包,使用这个插件可以帮助我们使用)

  • 使用 rollup-plugin-commonjs 来处理导入的commonjs模块的包(rollup默认只支持ES6模块的包)

  • 使用 rollup-plugin-babel 来支持babel

import json from 'rollup-plugin-json'
import resove from 'rollup-plugin-node-resolve'
import babel from 'rollup-plugin-babel'

export default {
    input: 'src/main.js',
    output: {
        file: 'bundle.js',
        format: 'umd',
        name: 'roll',
    },
    plugins: [
        json(),
        resove(),
        babel({
            exclude: 'node_modules/**'
        })
    ]
}

处理外部引用

有时候一些外部引用的库我们并不想一并打包在我们的库中,如:lodash、react,可以在配置文件中使用 external 字段来告诉rollup不要将这些库打包

export default {
    // ...
    external: ['lodash']
}

3.使用JavaScript API

rollup提供了JavaScript接口以便于通过Node.js来使用。

rollup.rollup

此函数范湖一个Promise,解析一个bundle对象,此对象带有不同的属性与方法,官网示例:

rollup.watch

检测磁盘上单个模块改变时,重新构建bundle,使用命令行时带上 --watch 参数,这个函数会在内部使用。

4.使用实例分析

dayjs

首先我们需要知道的是dayjs需要打包的文件有dayjs核心库、dayjs的plugins、dayjs的本地化文件三类文件。

package.json 文件中看到dayjs的build script实际上执行的build文件夹下的的 index.js 文件。

build 文件夹下有 index.js 文件和 rollup.config.js 两个文件,很显然,这个 rollup.config.js 文件就是rollup的配置文件。

这个配置文件如下:

const babel = require('rollup-plugin-babel')
const uglify = require('rollup-plugin-uglify')

module.exports = (config) => {
  const { input, fileName, name } = config
  return {
    input: {
      input,
      external: [
        'dayjs'
      ],
      plugins: [
        babel({
          exclude: 'node_modules/**'
        }),
        uglify()
      ]
    },
    output: {
      file: fileName,
      format: 'umd',
      name: name || 'dayjs',
      globals: {
        dayjs: 'dayjs'
      }
    }
  }
}

这里导出的是一个接受config参数的函数,可以想到这个函数是会在 index.js 中使用的,并且从解构赋值中可以知道config参数允许外部自定义input、输出的文件名fileName、umd使用的模块名。

这里使用了 rollup-plugin-babel 来配合使用babel,使用 rollup-plugin-uglify 插件来压缩js文件。

接下来看下 index.js 文件内容:

const rollup = require('rollup')
const configFactory = require('./rollup.config')
const fs = require('fs')
const util = require('util')
const path = require('path')

const { promisify } = util

const promisifyReadDir = promisify(fs.readdir)

const formatName = n => n.replace(/\.js/, '').replace('-', '_')

async function build(option) {
  const bundle = await rollup.rollup(option.input)
  await bundle.write(option.output)
}

(async () => {
  try {
    const locales = await promisifyReadDir(path.join(__dirname, '../src/locale'))
    locales.forEach((l) => {
      build(configFactory({
        input: `./src/locale/${l}`,
        fileName: `./locale/${l}`,
        name: `dayjs_locale_${formatName(l)}`
      }))
    })

    const plugins = await promisifyReadDir(path.join(__dirname, '../src/plugin'))
    plugins.forEach((l) => {
      build(configFactory({
        input: `./src/plugin/${l}`,
        fileName: `./plugin/${l}`,
        name: `dayjs_plugin_${formatName(l)}`
      }))
    })

    build(configFactory({
      input: './src/index.js',
      fileName: './dayjs.min.js'
    }))
  } catch (e) {
    console.error(e) // eslint-disable-line no-console
  }
})()

可以看到作者将打包功能专门抽出来作为一个 build 函数,之后读取plugin、locale文件夹中的文件然后每个文件单独打包,之后打包核心模块文件dayjs文件,在这里使用 JavaScript API的作用非常明显就是实现了一个命令打包多个文件。

hyperapp

hyperapp的目的只有一个就是打包src/index.js文件,因此功能也不要太强大,所以作者直接使用命令行即可。

5.完整参数配置

rollup完整参数可以在官网查询https://rollupjs.org/guide/zh#big-list-of-options

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant