• 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
    
  • 相关阅读:
    ABP文档翻译--值对象
    (转)SqlServer 数据库同步的两种方式 (发布、订阅),主从数据库之间的同步
    Sql Service 的job作业新建过程
    Python --- pyinstaller --- 打包成exe并更换图标
    基于树形检测器的多标志识别
    记录 TypeError: render() got an unexpected keyword argument 'renderer' 错误
    Dockerfile 关键字
    Go new 和 make的区别
    Go的数据类型
    Mac Go 环境变量配置
  • 原文地址:https://www.cnblogs.com/WindrunnerMax/p/14422971.html
Copyright © 2020-2023  润新知