zoukankan      html  css  js  c++  java
  • Rollup的基本使用

    Rollup的基本使用

    rollup.js是一个模块打包工具,可以使项目从一个入口文件开始,将所有使用到的模块文件都打包到一个最终的发布文件中,Rollup极其适合构建一个工具库,Vue.js源码就是通过Rollup打包构建的。

    描述

    rollup对代码模块使用新的标准化格式,这些标准都包含在JavaScriptES6版本中,而不是以前的特殊解决方案,如CommonJSAMD等,也就是说rollup使用ES6的模块标准,这意味着我们可以直接使用importexport而不需要引入babel,当然,在现在的项目中,babel可以说是必用的工具,此外rollup实现了另一个重要特性叫做tree-shaking,这个特性可以帮助你将无用代码,即没有使用到的代码自动去掉,这个特性是基于ES6模块的静态分析的,也就是说,只有export而没有import的变量是不会被打包到最终代码中的。

    示例

    我的一个小油猴插件就是通过rollup打包的,GreasyFork地址为https://greasyfork.org/zh-CN/scripts/405130,全部源码地址为https://github.com/WindrunnerMax/TKScript,使用npm run build即可打包构建,package.json文件与rollup.config.js文件配置如下。

    {
      "name": "TKScript",
      "version": "1.0.0",
      "description": "Tampermonkey",
      "scripts": {
        "build": "rollup -c"
      },
      "author": "Czy",
      "license": "MIT",
      "devDependencies": {
        "@babel/core": "^7.10.4",
        "@babel/preset-env": "^7.10.4",
        "install": "^0.13.0",
        "npm": "^6.14.5",
        "rollup": "^2.18.2",
        "rollup-plugin-babel": "^4.4.0",
        "rollup-plugin-postcss": "^3.1.2",
        "rollup-plugin-uglify": "^6.0.4",
        "rollup-plugin-userscript-metablock": "^0.2.5"
      }
    }
    
    import postcss from "rollup-plugin-postcss";
    import babel from "rollup-plugin-babel";
    // import { uglify } from "rollup-plugin-uglify";
    import metablock from "rollup-plugin-userscript-metablock";
    
    const config = {
        postcss: {
            minimize: true,
            extensions: [".css"],
        },
        babel: {
            exclude: ["node_modules/**"],
            presets: [
                [
                    "@babel/env", {
                        modules: false,
                        targets: "last 2 versions, ie >= 10"
                    }
                ]
            ]
        },
    
    }
    
    export default [{
        input: "./src/copy/src/index.js",
        output: {
            file: "./dist/copy.js",
            format: "iife",
            name: "copyModule"
        },
        plugins: [
            postcss(config.postcss),
            babel(config.babel),
            // uglify(),
            metablock({
                file: "./src/copy/meta.json"
            })
        ]
    },{
        input: "./src/site-director/src/index.js",
        output: {
            file: "./dist/site-director.js",
            format: "iife",
            name: "linkModule"
        },
        plugins: [
            postcss(config.postcss),
            babel(config.babel),
            // uglify(),
            metablock({
                file: "./src/site-director/meta.json"
            })
        ]
    }];
    

    使用方法

    安装

    • 全局安装: npm install rollup -g
    • 项目安装: npm install rollup --save-devyarn add rollup -D

    命令行工具

    • -i, --input <filename>: 要打包的文件(必须)。
    • -o, --file <output>: 输出的文件(如果没有这个参数,则直接输出到控制台)。
    • -f, --format <format>: 输出的文件类型。
      • amd: 异步模块定义,用于像RequestJS这样的模块加载器。
      • cjs: CommonJS, 适用于NodeBrowserify/webpack
      • es: 将软件包保存为ES模块文件。
      • iife: 一个自动执行的功能,适合作为script标签这样的,只能在浏览器中运行。
      • umd: 通用模块定义,以amdcjsiife为一体。
      • system: SystemJS加载器格式。
    • -e, --external <ids>: 将模块ID的逗号分隔列表排除。
    • -g, --globals <pairs>: 以moduleID:Global键值对的形式,用逗号分隔开任何定义在这里模块ID定义添加到外部依赖。
    • -n, --name <name>: 生成UMD模块的名字。
    • -m, --sourcemap: 生成sourcemap
    • --amd.id: AMD模块的ID,默认是个匿名函数。
    • --amd.define: 使用Function来代替define
    • --no-strict: 在生成的包中省略use strict;
    • --no-conflict: 对于UMD模块来说,给全局变量生成一个无冲突的方法。
    • --intro: 在打包好的文件的块的内部(wrapper内部)的最顶部插入一段内容。
    • --outro: 在打包好的文件的块的内部(wrapper内部)的最底部插入一段内容。
    • --banner: 在打包好的文件的块的外部(wrapper外部)的最顶部插入一段内容。
    • --footer: 在打包好的文件的块的外部(wrapper外部)的最底部插入一段内容。
    • --interop: 包含公共的模块(这个选项是默认添加的)。
    • -w, --watch: 监听源文件是否有改动,如果有改动,重新打包。
    • --silent: 不要将警告打印到控制台。
    • -h, --help: 输出帮助信息。
    • -v, --version 输出版本信息。

    配置文件

    // rollup.config.js
    export default {
      // 核心选项
      input,     // 必须
      external,
      plugins,
    
      // 额外选项
      onwarn,
    
      // danger zone
      acorn,
      context,
      moduleContext,
      legacy
    
      output: {  // 必须 (如果要输出多个,可以是一个数组)
        // 核心选项
        file,    // 必须
        format,  // 必须
        name,
        globals,
    
        // 额外选项
        paths,
        banner,
        footer,
        intro,
        outro,
        sourcemap,
        sourcemapFile,
        interop,
    
        // 高危选项
        exports,
        amd,
        indent
        strict
      },
    };
    

    input

    inputrollup -i,--input,打包入口文件路径,参数类型为String | String [] | { [entryName: string]: string }
    使用数组或者字符串作为选项值的时候的时候,默认使用的是文件的原始名称,作为文件的basename,可以在output:entryFileNames = entry-[name].js配置选项作为[name]动态参数传递进去。

    input: "./src/index.js";
    input: ["./src/index.js", "./other/index.js"];
    

    用键值对{key: value}的选项值作为参数,使用的对象的键作为文件的basename,用来在output:entryFileNames配置选项作为[name]动态参数传递进去。

    input: { main: "./src/index.js", vendor: "./other/index.js" }
    

    external

    externalrollup -e,--external, 维持包文件指定id文件维持外链,不参与打包构建 参数类型为String[] | (id: string, parentId: string, isResolved: boolean) => boolean

    • format类型为iife或者umd格式的时候需要配置output.globals选项参数以提供全局变量名来替换外部导入。
    • external是一个函数的时候,各个参数代表的含义分别是: id,所有导入的文件id,即import访问的路径;parentimport所在的文件绝对路径;isResolved,表示文件id是否已通过插件处理过。
    {
      // ...,
      external: [ 
          'some-externally-required-library',  
          'another-externally-required-library'
      ]
    }
    // or 
    {
      // ...,
      external: (id, parent, isResolved) => {
        return true; 
      }
    }
    

    plugins

    可以提供rollup很多插件选项,参数类型为Plugin | (Plugin | void)[]

    {
      // ...,
      plugins: [
          resolve(), 
          commonjs(), 
          isProduction && (await import("rollup-plugin-terser")).terser()
     ]
    }
    

    onwarn

    拦截警告信息,如果没有提供,警告将被复制并打印到控制台,警告是至少有一个codemessage属性的对象,我们可以控制如何处理不同类型的警告。

    onwarn (warning) {
      // 跳过某些警告
      if (warning.code === 'UNUSED_EXTERNAL_IMPORT') return;
    
      // 抛出异常
      if (warning.code === 'NON_EXISTENT_EXPORT') throw new Error(warning.message);
    
      // 控制台打印一切警告
      console.warn(warning.message);
    }
    

    许多警告也有一个loc属性和一个frame,可以定位到警告的来源。

    onwarn ({ loc, frame, message }) {
      // 打印位置(如果适用)
      if (loc) {
        console.warn(`${loc.file} (${loc.line}:${loc.column}) ${message}`);
        if (frame) console.warn(frame);
      } else {
        console.warn(message);
      }
    }
    

    acorn

    这是danger zone,修改rollup解析js配置,rollup内部使用的acorn库解析js, acorn库提供了解析js的相关配置api,一般很少需要修改。在下面这个例子中,这个acorn-jsx插件和使用babel并不是同一个意思,这个插件的左右是让acornjs解析器能认识jsx语法,经过rollup打包后展示的还是jsx语法,而babel会直接修改jsx结构成为普通js语法。

    import jsx from "acorn-jsx";
    
    export default {
      // ...
      acornInjectPlugins: [
          jsx()
      ]
    };
    

    context

    默认情况下,模块的上下文,即顶级的this的值为undefined,在极少数情况下,可能需要将其更改为其他内容,例如window

    moduleContext

    context一样,但是每个模块可以是id:context对的对象,也可以是id=>context函数。

    legacy

    为了增加对诸如IE8之类的旧版环境的支持,通过剥离更多可能无法正常工作的现代化的代码,其代价是偏离ES6模块环境所需的精确规范。

    output

    output是输出文件的统一配置入口, 包含很多可配置选项 参数类型为Object | Array,单个输出为一个对象,要输出多个,可以是一个数组。

    output.file

    output.filerollup -o,--file,必填,对于单个文件打包可以使用该选项指定打包内容写入带路径的文件,参数类型为String

    output: {
        file: "./dist/index.js" 
    }
    

    output.format

    output.formatrollup -f,--format,必填,打包格式类型 ,配置可选项有amdcjsesiifeumdsystem,选项说明同命令行配置选项,参数类型为String

    output: { 
        format: "iife"
    }
    

    output.name

    output.formatrollup -f,--format生成包名称,参数类型为String

    export default {
      // ...,
      output: {
        name: "bundle"
      }
    };
    

    output.globals

    output.globalsrollup -g,--globals,配合配置external选项指定的外链在umdiife文件类型下提供的全局访问变量名参数类型,参数类型为{ [id: String]: String } | ((id: String) => String)

    export default {
      // ...,
      globals: {
        jquery: "$"
      }
    };
    

    output.paths

    它获取一个ID并返回一个路径,或者id: path对的Object,在提供的位置,这些路径将被用于生成的包而不是模块ID,从而允许从CDN加载依赖关系。

    // app.js
    import { selectAll } from 'd3';
    selectAll('p').style('color', 'purple');
    // ...
    
    // rollup.config.js
    export default {
      input: 'app.js',
      external: ['d3'],
      output: {
        file: 'bundle.js',
        format: 'amd',
        paths: {
          d3: 'https://d3js.org/d3.v4.min'
        }
      }
    };
    
    // bundle.js
    define(['https://d3js.org/d3.v4.min'], function (d3) {
    
      d3.selectAll('p').style('color', 'purple');
      // ...
    
    });
    

    output.banner

    字符串前置到文件束bundlebanner选项不会破坏sourcemaps,参数类型为String

    export default {
      // ...,
      output: {
          banner: "/* library version " + version + " */",
      }
    };
    

    output.footer

    字符串前置到文件束bundlefooter选项不会破坏sourcemaps,参数类型为String

    export default {
      // ...,
      output: {
          footer: "/* follow me on Github! */",
      }
    };
    

    output.intro

    类似于output.banner,如果说bannerfooter是在文件开始和结尾添加字符串,那么introoutro就是在被打包的代码开头和结尾添加字符串了。

    export default {
      // ...,
      output: {
          intro: "/* library version " + version + " */",
      }
    };
    

    output.outro

    类似于output.footer,如果说bannerfooter是在文件开始和结尾添加字符串,那么introoutro就是在被打包的代码开头和结尾添加字符串了。

    export default {
      // ...,
      outro: {
          footer: "/* follow me on Github! */",
      }
    };
    

    output.sourcemap

    sourcemaprollup -m,--sourcemap, --no-sourcemap,如果true,将创建一个单独的sourcemap文件,如果inline, sourcemap将作为数据URI附加到生成的output文件中。

    output.sourcemapFile

    生成的包的位置,如果这是一个绝对路径,sourcemap中的所有源代码路径都将相对于它,map.file属性是sourcemapFile的基本名称basename,因为sourcemap的位置被假定为与bundle相邻,如果指定outputsourcemapFile不是必需的,在这种情况下,将通过给bundle输出文件添加.map后缀来推断输出文件名,一般应用场景很少,在特殊场景需要改变sourcemap的指向文件地址时才会用到。

    output.interop

    是否添加interop块,默认情况下interop: true,为了安全起见,如果需要区分默认和命名导出,则rollup会将任何外部依赖项default导出到一个单独的变量,这通常只适用于您的外部依赖关系,例如与Babel,如果确定不需要它,则可以使用interop: false来节省几个字节。

    output.exports

    使用什么导出模式,默认为auto,它根据entry模块导出的内容猜测你的意图。

    • default: 如果使用export default...仅仅导出一个文件,那适合用这个。
    • named: 如果导出多个文件,适合用这个。
    • none: 如果不导出任何内容,例如正在构建应用程序,而不是库,则适合用这个。

    output.amd

    打包amd模块相关定义。

    • amd.id: 用于AMD/UMD软件包的ID
    • amd.define: 要使用的函数名称,而不是define

    output.indent

    是要使用的缩进字符串,对于需要缩进代码的格式amdiifeumd,也可以是false无缩进或true默认自动缩进。

    output.strict

    truefalse,默认为true,是否在生成的非ES6软件包的顶部包含usestrict pragma,严格来说ES6模块始终都是严格模式,所以应该没有很好的理由来禁用它。

    每日一题

    https://github.com/WindrunnerMax/EveryDay
    

    参考

    https://www.rollupjs.com/
    https://segmentfault.com/a/1190000010628352
    https://github.com/JohnApache/rollup-usage-doc
    
  • 相关阅读:
    wex5 实战 框架拓展之2 事件派发与data刷新
    wex5 实战 框架拓展之1 公共data组件(Data)
    wex5 实战 HeidiSQL 导入Excel数据
    wex5 实战 手指触屏插件 hammer的集成与优劣
    wex5 实战 登陆帐号更换与用户id一致性
    wex5 实战 用户点评与提交设计技巧
    wex5 实战 省市县三级联动与地址薄同步
    wex5 实战 wex5与js的组件关系与执行顺序(父子与先后)
    wex5 实战 单页模式下的多页面数据同步
    [BZOJ]4237: 稻草人
  • 原文地址:https://www.cnblogs.com/WindrunnerMax/p/14422971.html
Copyright © 2011-2022 走看看