连rollup都不会,还写什么插件库!

轻量化Library打包工具

简介

本文档地址javascript

本文引用参考文档地址html

Rollup 是一个 JavaScript 模块打包器,能够将小块代码编译成大块复杂的代码,例如 library 或应用程序。java

Rollup 对代码模块使用新的标准化格式,这些标准都包含在 JavaScript 的 ES6 版本中,而不是之前的特殊解决方案,如 CommonJS 和 AMD。ES6 模块可使你自由、无缝地使用你最喜好的 library 中那些最有用独立函数,而你的项目没必要携带其余未使用的代码。ES6 模块最终仍是要由浏览器原生实现,但当前 Rollup 可使你提早体验。node

Why is rollup

Rollup 着眼于将来,采用原生的ES 标准的模块机制进行构建,将来ES 规范确定会由浏览器实现,也是JavaScript语言明确的发展方向。机制更加优于CommonJSwebpack

CommonJS 是在ES规范以前被提出的一种暂时性性解决方案,是一种特殊的传统格式,git

相比较ES模块容许进行静态分析,从而实现像 tree-shaking 的优化,并提供诸如循环引用和动态绑定等高级功能github

Tree-shaking, 也被称为 "live code inclusion," 它是清除实际上并无在给定项目中使用的代码的过程,可是它能够更加高效。web

构建工具对比

打包工具 体积 注入代码 code spliting dynamic import Tree-shaking
webpack large more
rollup small less

webpack 是一款强大的 bundle 构建工具,经过 loader机制能够处理各类类型的文件,良好的 code splittingdynamic import支持使得webpack 成为了应用程序,单页应用的全能型的的打包工具。npm

可是由于其打包体积相对较大,注入代码更多,没有良好的Tree-shaking因此在Library 的打包工做中,不如rollup打包的精简。json

配置

rollup 定位是一款轻量级的构建工具,其配置也相对很简单,可是因为不支持CommonJs,在配置rollup-plugin-commonjsCommmonJS 转化成ES 模块方式的时候,须要配置babel 转译

因为babel 7+升级改动比较大,命名空间改动,市面上的教程大部分说的不够清楚,并且基本上停留在babel 6的配置,致使一直抛(plugin commonjs) SyntaxError: Unexpected token

在后文中会着力介绍这个部分,分析babel 7+配置以及各个presetsplugins 的做用。

安装rollup

npm install --save-dev rollup
复制代码

配置文件

在项目根目录建立rollup.config.js文件。

rollup 配置比较的简洁,通常包括input,output,plugins,external

配置项参考

这是一段简单的配置文件

export default {
  input: 'src/index.js',
  output: {
    name: 'amapUpper',
    file: 'dist/amapUpper.js',
    format: 'umd' //兼容模式
  },
  external: ['@amap/amap-jsapi-loader'],// 配置引入的包是否要打包,在这里配置的会忽略掉,不打包到咱们的程序里面
  plugins: []
};
复制代码

当你的配置文件须要配置多个打包策略的时候,你还能够这样配置

export default [{
  input: 'main-a.js',
  output: {
    file: 'dist/bundle-a.js',
    format: 'cjs'
  }
}, {
  input: 'main-b.js',
  output: [
    {
      file: 'dist/bundle-b1.js',
      format: 'cjs'
    },
    {
      file: 'dist/bundle-b2.js',
      format: 'es'
    }
  ]
}]
复制代码

你还可使用多个配置文件,使用--config来使用配置文件

# pass a custom config file location to Rollup
rollup --config my.config.js
复制代码

::: danger 使用了umd模式必须指定 Name for UMD export :::

配置rollup插件

配置gollup 的plugin 相似babel 所有移植到了@rollup下,在官方提供的 一站式配置商店,能够下载所需的插件, 做用在于可维护学习被误导成本下降,更有利于长期维护。

@plugin 连接地址

插件是什么

rollup plugin 是一个遵循rollup插件规范的object,通常经过一个工厂函数返回一个对象实现

一段简单的示例:

export default function myExample () {
  return {
    name: 'my-example', // this name will show up in warnings and errors
    resolveId ( source ) {
      if (source === 'virtual-module') {
        return source; // this signals that rollup should not ask other plugins or check the file system to find this id
      }
      return null; // other ids should be handled as usually
    },
    load ( id ) {
      if (id === 'virtual-module') {
        return 'export default "This is virtual!"'; // the source code for "virtual-module"
      }
      return null; // other ids should be handled as usually
    }
  };
}
复制代码

而后在配置文件中引用该插件,在plugins中,传入执行返回的对象

import myExample from 'myExample'


plugins: [ myExample() ]
复制代码

插件对象遵循的规范

A Rollup plugin is an object with one or more of the properties, build hooks, and output generation hooks

插件执行顺序

熟悉webpack loader机制的都应该知道loader 其实是从右到左,自下而上执行的,在页头的 rollup打包js的注意点 里面提到的错误记录/错误2里面,类比webpack loader机制, 实际上是一个错误的类比,实际上rollupplugin 机制是从左往右,自上而下而下的执行顺序。

一个测试例子

// rollup.config.js
function myExample1() {
  return {
    name: 'my-example1', // this name will show up in warnings and errors
    resolveId(source) {
      console.log('111 resolve_______________-------------------------------------------');
      return null; // other ids should be handled as usually
    },
    load(id) {
      console.log('111 load_______________-------------------------------------------');
      return null; // other ids should be handled as usually
    }
  };
}
function myExample2() {
  return {
    name: 'my-example1', // this name will show up in warnings and errors
    resolveId(source) {
      console.log('222 resolve_______________-------------------------------------------');
      return null; // other ids should be handled as usually
    },
    load(id) {
      console.log('222 load_______________-------------------------------------------');
      return null; // other ids should be handled as usually
    }
  };
}


export default {
  input: 'src/index.js',
  output: {
    name: 'test',
    file: 'dist/test.js',
    format: 'umd'
  },
  plugins: [
    myExample1(),    
    myExample2()
  ]
};

复制代码

能够看到load,resolve 钩子函数都是从左往右,自上而下而下的执行顺序。

配置经常使用的插件

下面介绍正常打包中须要用到的插件,和通常配置。

  • @rollup/plugin-json rollup-plugin-json
  • @rollup/plugin-commonjs rollup-plugin-commonjs
  • @rollup/plugin-node-resolverollup-plugin-node-resolve
  • rollup-plugin-terser

首先,须要做为开发依赖安装这些插件

npm i @rollup/plugin-json -D
npm i @rollup/plugin-commonjs -D
npm i @rollup/plugin-node-resolve -D
npm i rollup-plugin-terser -D
复制代码

而后须要引用配置文件

import json from '@rollup/plugin-json';
import commonjs from '@rollup/plugin-commonjs';
import nodeResolve from '@rollup/plugin-node-resolve';
import babel from 'rollup-plugin-babel';
import { terser } from 'rollup-plugin-terser';

export default {
  ...
  plugins: [
    json(),
    terser(),
    nodeResolve(),
    commonjs(),
    babel({
      exclude: '*', // 排除node_modules 下的文件
      runtimeHelpers: true // 防止生成多个 打包helper 函数
    }),
  ]
};
复制代码

问题总结

commonjs 插件和 babel7+ 配置

在跟着 rollup 搭建打包 JS 一文配置的过程当中,用到的插件不是官方一站式插件提供的长期维护版本,遇到了 rollup-plugin-commonjs 插件打包报错的问题

针对使用了放弃维护的rollup-plugin-commonjs插件的打包抛出的这个SyntaxError,能够有两种解决方案。推荐方案二。

解决方案一 配置babel

查找了不少资料都显示,应该是babel 配置问题,主要分为:

  • babel 配置问题
  • babel 转译执行顺序问题

综合这些资料,这个报错应该是因为该commonjs 插件库 被移动到 @rollup/plugin-commonjs下维护,致使非长期维护版本缺乏某些转译后的辅助函数,属性,致使抛出异常。

因此须要babel 辅助编译以后才能正确执行commonjs 插件。

babel 配置的一些问题

因为babel 7+版本中,将babel 的各个库所有移植到了@babel/***下统一官方维护,而市面上大部分的babel教程实际上没有对这点进行详细说明,并且教程里安装babel组件的时候并无指定版本,实际上致使可能安装了7+ 版本的babel核心库,而安装了放弃维护的babel-plugins-***下的插件预设之类的。就会致使一系列的问题。

这里要注意一下这个@这个符号,这个是只有babel7才特有的,babel6都木有,市面上大量代码都是基于6的因此要特别注意,安装的时候要使用 npm install i -S @babel\cli 而不能是npm install i -S babel-cli了 这是 babel 7 的一大调整,原来的 babel-xx 包统一迁移到babel域 下 - 域由 @ 符号来标识

参阅文章开头提到的 babel 7 的使用的我的理解

配置

因为这里使用@rollup/plugin-babel,执行babel 转译 因此不须要安装@babel/cli命令行工具。

首先咱们须要安装:

  • babel核心包@babel/core
  • babel预设包@babel/preset-env
  • 统一的模块化的helper@babel/runtime
  • helper 的自动化引入工具 @babel/plugin-transform-runtime
npm i -D @babel/core
npm i -D @babel/preset-env
npm i -D @babel/runtime
npm i -D @babel/plugin-transform-runtime
复制代码

而后在项目根目录下建立.babelrc的配置文件

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": false,
        "targets": {
          "browsers": [
            "> 1%",
            "last 2 versions",
            "not ie <= 8"
          ]
        }
      }
    ]
  ],
  "plugins": ["@babel/plugin-transform-runtime"]
}
复制代码

而后若是你用的是rollup-plugin-commonjs很是期维护版本的插件的话,因为和babel有依赖关系,你须要:

commonjs插件以前引入babel插件,并配置须要匹配编译的文件,目录。和编译配置

// rollup.config.js
export default {
  input: 'src/index.js',
  output: {
    name: 'amapUpper',
    file: 'dist/amapUpper.js',
    format: 'umd'
  },
  plugins: [
    babel({
      exclude: '/node_modules/**', // 排除node_modules 下的文件
      runtimeHelpers: true // 与plugin-transform-runtime 插件对应配置,生成统一化helper。
    }),
    commonjs()
  ]
};
复制代码

解决方案二

使用rollup新的官方提供的移动后的一站式插件库里面的插件

rollup @plugin 连接地址

使用了新的插件库以后,babel仍是须要配置的,只是解决了commonjs 插件依赖babel的问题。

而babel 其实是解决各类浏览器,引擎之间的差别,而存在的。因此为了更好的支持,须要配备良好的babel配置。

this over

欢迎各位看官大佬们点赞,纠错。

相关文章
相关标签/搜索