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编写现代化模块 #7

Open
bosens-China opened this issue Aug 12, 2019 · 0 comments
Open

使用rollup编写现代化模块 #7

bosens-China opened this issue Aug 12, 2019 · 0 comments
Labels
工具相关 工程化相关的东西

Comments

@bosens-China
Copy link
Owner

之所有选用 rollup 是因为它可以减少打包体积和提高构建速度,下面介绍不会详细讲解配置,你可以自行查阅官方文档

ES6 已经出现很久了,但是为了兼容以前的浏览器,我们还是需要使用各种构建工具,例如 webpack,在使用的时候很方便,可以通过 babel 转换 es6 的语法,比如下面导入一个模块

import moduleName from 'module';

不过编写一个现代化模块呢,预定目标应该有三点

  1. 支持 typescript,将 ES6 代码转化为 ES5 环境使用
  2. 支持构建工具和script type="module"的导入
  3. 支持 umd 格式引用

就以下面这段代码为演示,实现上述的目标

export default (arr = []) => {
  return Array.from(arr).length;
};

准备

npm init -y
npm i rollup -D
cd.>rollup.config.js
md src
cd.>src/index.js

这样就创建好我们想要的基本结构了,将上面例子复制到 index.js 文件下。

rollup可以通过命令行也可以通过脚本来调用,这里在package.jsonscripts字段,通过脚本调用

  "scripts": {
    "build": "rollup -c"
  }

-c是指配置文件,默认就是rollup.config.js所以不需要额外配置了

编写第一个例子

rollup.config.js

export default {
  input: "./src/index.js",
  output: [
    {
      file: "dist/index.esm.browser.js",
      format: "es",
      sourcemap: true
    }
  ]
};

上面配置信息input指的是入口文件,output 是出口文件,file是输出的文件路径,sourcemap是是否输出 map 文件,他可以方便调试错误,在开发模块中应该是必须的,format是指输出的格式

  • amd
    异步模块定义,用于像 RequireJS 这样的模块加载器
  • cjs
    CommonJS,适用于 Node 和 Browserify/Webpack
  • es
    将软件包保存为 ES 模块文件
  • iife
    一个自动执行的功能,适合作为<\script>标签。(如果要为应用程序创建一个捆绑包,您可能想要使用它,因为它会使文件大小变小。)
  • umd
    通用模块定义,以 amd,cjs 和 iife 为一体

执行npm run build

dist/index.esm.browser.js

var index = (arr = []) => {
  return Array.from(arr).length;
};

export default index;
//# sourceMappingURL=index.esm.browser.js.map

可以看到生成的信息十分简洁,上面说到要同时支持umd 格式和 import 导入,import可以通过es的形式来供构建工具和script type="module"使用,下面就来定义一下 umd 格式

export default {
  input: "./src/index.js",
  output: [
    {
      file: "dist/index.esm.browser.js",
      format: "es",
      sourcemap: true
    },
    {
      file: "dist/index.js",
      format: "umd",
      sourcemap: true,
      name: "index"
    }
  ]
};

注意使用umd或者iife必须指定 name 字段,他决定了暴露在全局作用下的变量名,再次执行可以看到index.js的信息了。

babel

上面完成了需求的第一步,不过对于 es6 的代码,并没有转化为 es5 的形式,只是将语法转换了,Array.from依旧存在,下面使用babel来完成需求

npm i @babel/core @babel/preset-env  core-js rollup-plugin-babel rollup-plugin-node-resolve rollup-plugin-commonjs -D

babel.config.js

module.exports = {
  presets: [
    [
      "@babel/preset-env",
      {
        useBuiltIns: "usage",
        corejs: 3,
        modules: false
      }
    ]
  ]
};

上面代码的useBuiltInsusage是 babel7 的实验性特性,他支持按需加载

rollup.config.js

import babel from "rollup-plugin-babel";
import resolve from "rollup-plugin-node-resolve";
import commonjs from "rollup-plugin-commonjs";
export default {
  input: "./src/index.js",
  output: [
    {
      file: "dist/index.esm.browser.js",
      format: "es",
      sourcemap: true
    },
    {
      file: "dist/index.js",
      format: "umd",
      sourcemap: true,
      name: "index"
    }
  ],
  plugins: [
    commonjs(),
    resolve(),
    babel({
      exclude: [/\/core-js\//],
      runtimeHelpers: true,
      sourceMap: true,
      extensions: [".js", ".jsx", ".es6", ".es", ".mjs", ".ts"]
    })
  ]
};

再次执行可以看到Arrar.from已经被babel转换为 ES5 的环境了

typescript

这个我们用babel提供给我们的@babel/preset-typescript即可完成,不过为了支持typescript一些其他扩展语法,我们还需要安装一些插件

npm i @babel/preset-typescript @babel/plugin-transform-typescript @babel/plugin-syntax-dynamic-import @babel/plugin-proposal-class-properties -D

babel.config.js

module.exports = {
  presets: [
    [
      "@babel/preset-env",
      {
        useBuiltIns: "usage",
        corejs: 3,
        modules: false
      }
    ],
    ["@babel/preset-typescript"]
  ],
  plugins: [
    "@babel/plugin-transform-typescript",
    "@babel/plugin-syntax-dynamic-import",
    "@babel/plugin-proposal-class-properties"
  ]
};

修改一下 src/index.jsindex.tsrollup.config.jsinput字段

export default (arr: Array<any> = []): number => {
  return Array.from(arr).length;
};

再次执行npm run build,成功输出

优化

  1. 输出代码没有被压缩
  2. 每次输出的时候文件夹没有被删除

上面两个问题,可以通过插件来解决

npm i rollup-plugin-terser rollup-plugin-clear -D

rollup.config.js

import babel from "rollup-plugin-babel";
import clear from "rollup-plugin-clear";
import resolve from "rollup-plugin-node-resolve";
import commonjs from "rollup-plugin-commonjs";
import { terser } from "rollup-plugin-terser";
export default {
  input: "./src/index.ts",
  output: [
    {
      file: "dist/index.esm.browser.js",
      format: "es",
      sourcemap: true
    },
    {
      file: "dist/index.js",
      format: "umd",
      sourcemap: true,
      name: "index"
    }
  ],
  plugins: [
    clear({
      targets: ["dist"]
    }),
    resolve(),
    commonjs(),
    terser(),
    babel({
      exclude: [/\/core-js\//],
      runtimeHelpers: true,
      sourceMap: true,
      extensions: [".js", ".jsx", ".es6", ".es", ".mjs", ".ts"]
    })
  ]
};

这样基本的模块的基本功能就编写完成了

@bosens-China bosens-China added 工具相关 工程化相关的东西 and removed 工具相关 labels Dec 18, 2019
@bosens-China bosens-China changed the title 使用rollup编写一个现代化的模块 使用rollup编写现代化模块 Dec 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
工具相关 工程化相关的东西
Projects
None yet
Development

No branches or pull requests

1 participant