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

相关推荐
真滴book理喻13 分钟前
Vue(四)
前端·javascript·vue.js
程序员_三木37 分钟前
Three.js入门-Raycaster鼠标拾取详解与应用
开发语言·javascript·计算机外设·webgl·three.js
开心工作室_kaic2 小时前
springboot476基于vue篮球联盟管理系统(论文+源码)_kaic
前端·javascript·vue.js
川石教育2 小时前
Vue前端开发-缓存优化
前端·javascript·vue.js·缓存·前端框架·vue·数据缓存
搏博2 小时前
使用Vue创建前后端分离项目的过程(前端部分)
前端·javascript·vue.js
温轻舟2 小时前
前端开发 之 12个鼠标交互特效上【附完整源码】
开发语言·前端·javascript·css·html·交互·温轻舟
web135085886352 小时前
2024-05-18 前端模块化开发——ESModule模块化
开发语言·前端·javascript
LCG元4 小时前
javascript页面设计案例【使用HTML、CSS和JavaScript创建一个基本的互动网页】
javascript
技术程序猿华锋4 小时前
Gemini 2.0 Flash 体验版实测:日常视觉识别的最佳选择,关键在于其API Key现在是免费调用
开发语言·javascript·ecmascript·googlecloud·gemini
TttHhhYy4 小时前
uniapp+vue开发app,蓝牙连接,蓝牙接收文件保存到手机特定文件夹,从手机特定目录(可自定义),读取文件内容,这篇首先说如何读取,手机目录如何寻找
开发语言·前端·javascript·vue.js·uni-app