axios源码打包关于rollup.config.js文件分析

axios 项目下的rollup.config.js文件

js 复制代码
const lib = require("./package.json");
const outputFileName = "axios";
const name = "axios";
const namedInput = "./index.js";
const defaultInput = "./lib/axios.js";
js 复制代码
export default async () => {
  const year = new Date().getFullYear();
  const banner = `// Axios v${lib.version} Copyright (c) ${year} ${lib.author} and contributors`;

  return [
    // browser ESM bundle for CDN
    ...buildConfig({
      input: namedInput, //'./index.js'
      output: {
        file: `dist/esm/${outputFileName}.js`, //outputFileName = 'axios;
        format: "esm", //-f, --format <format>   输出类型(amd、cjs、es、iife、umd、system)
        preferConst: true,
        exports: "named", //--exports <mode>    指定导出模式(auto、default、named、none)
        banner, //--banner <text>   在产物顶部插入的代码(位于包装器之外)
      },
    }),
    // Browser UMD bundle for CDN
    ...buildConfig({
      input: defaultInput,
      es5: true,
      output: {
        file: `dist/${outputFileName}.js`,
        name,
        format: "umd",
        exports: "default",
        banner,
      },
    }),

    // Browser CJS bundle
    ...buildConfig({
      input: defaultInput,
      es5: false,
      minifiedVersion: false,
      output: {
        file: `dist/browser/${name}.cjs`,
        name,
        format: "cjs",
        exports: "default",
        banner,
      },
    }),

    // Node.js commonjs bundle
    {
      input: defaultInput,
      output: {
        file: `dist/node/${name}.cjs`,
        format: "cjs",
        preferConst: true,
        exports: "default",
        banner,
      },
      plugins: [autoExternal(), resolve(), commonjs()],
    },
  ];
};

buildConfig 函数

  • 接收一个参数,返回一个数组
js 复制代码
const buildConfig = ({
  es5,
  browser = true,
  minifiedVersion = true,
  alias,
  ...config
}) => {
  // 输出的文件名称已经路径
  const { file } = config.output;

  // path.extname() 方法返回 path 的扩展名,即 path 的最后一部分中从最后一次出现的 .(句点)字符到字符串的结尾。
  const ext = path.extname(file);

  // path.basename() 方法返回 path 的最后一部分
  const basename = path.basename(file, ext);
  const extArr = ext.split(".");
  extArr.shift();

  const build = ({ minified }) => ({
    input: namedInput, // ./index.js
    ...config,
    output: {
      ...config.output,
      // path.dirname() 方法返回 path 的目录名
      file: `${path.dirname(file)}/${basename}.${(minified
        ? ["min", ...extArr]
        : extArr
      ).join(".")}`,
    },
    plugins: [
      aliasPlugin({
        entries: alias || [],
      }),
      json(),
      resolve({ browser }),
      commonjs(),

      minified && terser(),
      minified && bundleSize(),
      ...(es5
        ? [
            babel({
              babelHelpers: "bundled",
              presets: ["@babel/preset-env"],
            }),
          ]
        : []),
      ...(config.plugins || []),
    ],
  });

  const configs = [build({ minified: false })];

  if (minifiedVersion) {
    configs.push(build({ minified: true }));
  }

  return configs;
};

umd 模块

UMDAMD + CommonJS 的结合体,同时还兼容了 script 标签引入,对组件库或框架库来说,解决了以前一套代码无法多端使用的难题。UMD 模块可借助 Rollup 工具来完成。

dist\axios.js

dist\axios.js.map

dist\axios.min.js

dist\axios.min.js.map

js 复制代码
(function (global, factory) {
  typeof exports === "object" && typeof module !== "undefined"
    ? (module.exports = factory())
    : typeof define === "function" && define.amd
    ? define(factory)
    : ((global =
        typeof globalThis !== "undefined" ? globalThis : global || self),
      (global.axios = factory()));
})(this, function () {
  "use strict";
  var axios = createInstance(defaults$1);

  // Expose Axios class to allow class inheritance
  axios.Axios = Axios$1;

  // Expose Cancel & CancelToken
  axios.CanceledError = CanceledError;
  axios.CancelToken = CancelToken$1;
  axios.isCancel = isCancel;
  axios.VERSION = VERSION;
  axios.toFormData = toFormData;

  // Expose AxiosError class
  axios.AxiosError = AxiosError;

  // alias for CanceledError for backward compatibility
  axios.Cancel = axios.CanceledError;

  // Expose all/spread
  axios.all = function all(promises) {
    return Promise.all(promises);
  };
  axios.spread = spread;

  // Expose isAxiosError
  axios.isAxiosError = isAxiosError;

  // Expose mergeConfig
  axios.mergeConfig = mergeConfig;
  axios.AxiosHeaders = AxiosHeaders$1;
  axios.formToJSON = function (thing) {
    return formDataToJSON(
      utils$1.isHTMLForm(thing) ? new FormData(thing) : thing
    );
  };
  axios.getAdapter = adapters.getAdapter;
  axios.HttpStatusCode = HttpStatusCode$1;
  axios["default"] = axios;

  return axios;
});

可直接在 script 引入使用

也可例如 require 来使用

js 复制代码
requirejs.config({
  baseUrl: "modules/",
});
require(["tools_umd"], function (tools) {
  console.log("tools", tools);
});

CommonJS(browser) 模块文件使用

dist\browser\axios.cjs

dist\browser\axios.cjs.map

js 复制代码
axios.default = axios;

module.exports = axios;
js 复制代码
if (pathname === "/index.html") {
  pipeFileToResponse(res, "./client.html");
} else if (pathname === "/axios.js") {
  //
  pipeFileToResponse(res, "../dist/esm/axios.js", "text/javascript");
} else if (pathname === "/axios.js.map") {
  pipeFileToResponse(res, "../dist/esm/axios.js.map", "text/javascript");
}
js 复制代码
function pipeFileToResponse(res, file, type) {
  if (type) {
    res.writeHead(200, {
      "Content-Type": type,
    });
  }

  fs.createReadStream(path.join(path.resolve(), "sandbox", file)).pipe(res);
}
html 复制代码
<script src="/axios.js"></script>
<script>
  // 执行axios
</script>

## CommonJS(node) 模块

module.exports && require

dist\node\axios.cjs

dist\node\axios.cjs.map

js 复制代码
//axios.cjs
(function (global, factory) {

  // 
  typeof exports === "object" && typeof module !== "undefined"
    ? (module.exports = factory())

    // 这段代码检查require.js是否存在,这是一个JavaScript依赖管理库。
// 如果'define'不是未定义的,并且它是一个函数,并且'amd'(异步模块定义)也被定义,那么代码假设require.js正在运行。
    : typeof define === "function" && define.amd
    ? define(factory)
    : ((global =
        typeof globalThis !== "undefined" ? globalThis : global || self),
      (global.axios = factory()));
})(this, function () {
  "use strict";
  var axios = createInstance(defaults$1);

  // Expose Axios class to allow class inheritance
  axios.Axios = Axios$1;

  // Expose Cancel & CancelToken
  axios.CanceledError = CanceledError;
  axios.CancelToken = CancelToken$1;
  axios.isCancel = isCancel;
  axios.VERSION = VERSION;
  axios.toFormData = toFormData;

  // Expose AxiosError class
  axios.AxiosError = AxiosError;

  // alias for CanceledError for backward compatibility
  axios.Cancel = axios.CanceledError;

  // Expose all/spread
  axios.all = function all(promises) {
    return Promise.all(promises);
  };
  axios.spread = spread;

  // Expose isAxiosError
  axios.isAxiosError = isAxiosError;

  // Expose mergeConfig
  axios.mergeConfig = mergeConfig;
  axios.AxiosHeaders = AxiosHeaders$1;
  axios.formToJSON = function (thing) {
    return formDataToJSON(
      utils$1.isHTMLForm(thing) ? new FormData(thing) : thing
    );
  };
  axios.getAdapter = adapters.getAdapter;
  axios.HttpStatusCode = HttpStatusCode$1;
  axios["default"] = axios;

  return axios;
});

module.exports = factory() 是一种常见的模块导出模式,尤其在 CommonJS 环境中。

这种模式通常用于将模块的内部函数或对象导出,以便在模块外部使用。

这里的factory()通常是一个返回特定对象或函数的表达式,该对象或函数随后被赋值给module.exports

ES Modules 模块的文件使用

dist\esm\axios.js

dist\esm\axios.js.map

dist\esm\axios.min.js

dist\esm\axios.min.js.map

一个 JS 文件中,export 可以有无限个,但 export default 只能有一个。

js 复制代码
const {
  Axios,
  AxiosError,
  CanceledError,
  isCancel,
  CancelToken,
  VERSION,
  all,
  Cancel,
  isAxiosError,
  spread,
  toFormData,
  AxiosHeaders,
  HttpStatusCode,
  formToJSON,
  getAdapter,
  mergeConfig,
} = axios$1;

export {
  Axios,
  AxiosError,
  AxiosHeaders,
  Cancel,
  CancelToken,
  CanceledError,
  HttpStatusCode,
  VERSION,
  all,
  axios$1 as default,
  formToJSON,
  getAdapter,
  isAxiosError,
  isCancel,
  mergeConfig,
  spread,
  toFormData,
};
//# sourceMappingURL=axios.js.map
js 复制代码
if (pathname === "/index.html") {
  pipeFileToResponse(res, "./client.html");
} else if (pathname === "/axios.js") {
  // text/javascript
  pipeFileToResponse(res, "../dist/esm/axios.js", "application/javascript");
} else if (pathname === "/axios.js.map") {
  pipeFileToResponse(res, "../dist/esm/axios.js.map", "application/javascript");
}
js 复制代码
function pipeFileToResponse(res, file, type) {
  if (type) {
    res.writeHead(200, {
      "Content-Type": type,
    });
  }

  fs.createReadStream(path.join(path.resolve(), "sandbox", file)).pipe(res);
}
html 复制代码
<script type="module" src="/axios.js"></script>
<script type="module">
  import axios from "/axios.js";
  // 执行axios
</script>

AMD 模块

注意,AMD 只适用于浏览器,虽然也支持 Node,但不如 Node 自家的 CJS

相关推荐
前端青山4 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
从兄5 小时前
vue 使用docx-preview 预览替换文档内的特定变量
javascript·vue.js·ecmascript
清灵xmf6 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询
薛一半7 小时前
PC端查看历史消息,鼠标向上滚动加载数据时页面停留在上次查看的位置
前端·javascript·vue.js
过期的H2O28 小时前
【H2O2|全栈】JS进阶知识(四)Ajax
开发语言·javascript·ajax
MarcoPage8 小时前
第十九课 Vue组件中的方法
前端·javascript·vue.js
你好龙卷风!!!8 小时前
vue3 怎么判断数据列是否包某一列名
前端·javascript·vue.js
shenweihong10 小时前
javascript实现md5算法(支持微信小程序),可分多次计算
javascript·算法·微信小程序
巧克力小猫猿10 小时前
基于ant组件库挑选框组件-封装滚动刷新的分页挑选框
前端·javascript·vue.js
嚣张农民10 小时前
一文简单看懂Promise实现原理
前端·javascript·面试