Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【入门教程】Rollup模块打包器整合

【入门教程】Rollup模块打包器整合

作者头像
前端小鑫同学
发布于 2022-12-26 04:51:40
发布于 2022-12-26 04:51:40
1.3K00
代码可运行
举报
运行总次数:0
代码可运行

Rollup 是一个用于 JavaScript 的模块打包器,它将小段代码编译成更大更复杂的东西,例如库或应用程序。它对 JavaScript 的 ES6 修订版中包含的代码模块使用新的标准化格式,而不是以前的特殊解决方案,例如 CommonJS 和 AMD。 ES 模块让您可以自由无缝地组合您最喜欢的库中最有用的单个函数。这最终将在任何地方本地实现,但 Rollup 让您今天就可以做到。————《rollupjs.org》

特点:

  1. 选用ES6标准模块化格式;
  2. 支持静态分析导入代码进行Tree-Shaking。

兼容:

  1. 支持导入CommonJs模块;
  2. 方便使用到CommonJS模块的工具,如:Node.js、webpack。

ES 模块语法:

思维导图地址:es模块语法

快速开始:

常见编译输出风格:

命名

风格

适用

iife

立即执行函数

浏览器

cjs

CommonJs

NodeJs

umd

通用模块定义

浏览器/NodeJs

编译案例演示:

rollup采用ES6标准模块化格式

定义一个待编译的ES6模块:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 文件名:main.js
const main = {
    hello: () => {
        console.log('Hello');
    },
    world: () => {
        console.log('World');
    },
};
export default main;
编译为IIFE风格:
命令示例:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rollup <入口文件> --file <输出文件> --name <输出模块名称> --format <输出模块类型>

注意:name为推荐选项,未指明打包后的模块名称,虽然打包产物可以正常加载但无法触发执行。

编译命令:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rollup .\main.js --file bundle.iife.js --name myBundle --format iife
输出产物:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 文件名:bundle.iife.js
var myBundle = (function () {
    'use strict';

    const main = {
        hello: () => {
            console.log('Hello');
            return 'Hello';
        },
        world: () => {
            console.log('World');
            return 'World';
        },
    };

    return main;

})();
在浏览器中使用:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<head>
    <script src="../bundle.iife.js"></script>
</head>

<body>
    <script>
        myBundle.hello();
    </script>
</body>
编译为CJS风格:
命令示例:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rollup <入口文件> --file <输出文件> --exports <导出模式> --format <输出模块类型>

注意:exports为推荐选项,当使用默认导出时将抛出警告,建议使用命名导出。

编译命令:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rollup .\main.js --file bundle.cjs.js --exports auto --format cjs
输出产物:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 文件名:bundle.cjs.js
'use strict';

const main = {
    hello: () => {
        console.log('Hello');
    },
    world: () => {
        console.log('World');
    },
};

module.exports = main;
在Node环境中使用:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const main = require('../bundle.cjs.js');
console.log(main.hello());
编译为UMD风格:
命令示例:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rollup <入口文件> --file <输出文件> --name <输出模块名称> --format <输出模块类型>

注意:name为必填项,缺少后将抛出异常,打包产物在没有模块加载的环境将无法使用。

编译命令:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rollup main.js --file bundle.umd.js  --name myBundle --format umd
输出产物:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 文件名:bundle.umd.js
(function (global, factory) {
    typeof exports === 'object' &amp;&amp; typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' &amp;&amp; define.amd ? define(factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.myBundle = factory());
})(this, (function () { 'use strict';

    const main = {
        hello: () => {
            console.log('Hello');
        },
        world: () => {
            console.log('World');
        },
    };

    return main;

}));
在浏览器中使用:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<head>
    <script src="../bundle.umd.js"></script>
</head>

<body>
    <div id="content"></div>
    <script>
        const output = myBundle.hello();
        document.getElementById("content").innerHTML = output
    </script>
</body>
在Node环境中使用:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const main = require('../bundle.umd.js');
console.log(main.hello());

使用配置文件:

虽然在命令行可以完成大量的编译配置,但是同样提供了通过配置文件的方式来进行简化。

使用配置文件说明:

  1. 使用ES6模块导出风格编写配置文件:建议将扩展名修改成.mjs,执行期间会快速转换为CommonJS使用。
  2. 使用CommonJs模块导出风格编写配置文件:将扩展名修改成.cjs,NodeJs13+将阻止Rollup进行转义。
  3. 使用ts来编写配置文件:需要在执行命令时指定configPlugin为typescript
典型配置文件:

下面是一个典型的使用ES6模块默认导出风格的配置,将main.js文件编译为CommonJs模块风格,输出到bundle.js中。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 文件名称:rollup.config.js
export default {
    input: 'main.js',
    output: {
        file: 'bundle.js',
        format: 'cjs',
        exports: 'auto'
    },
};
多入口,多出口配置文件:

下面是一个支持同时编译多个入口文件,且支持同时编译成多种模块风格的参考配置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export default [
  {
    input: 'main-a.js',
    output: {
      file: 'dist/bundle-a.js',
      format: 'cjs'
    }
  },
  {
    input: 'main-b.js',
    output: [
      {
        file: 'dist/bundle-b1.js',
        format: 'cjs'
      },
      {
        file: 'dist/bundle-b2.js',
        format: 'es'
      }
    ]
  }
];
异步创建配置文件:

支持我们通过异步的形式创建配置文件,例如我们的配置文件放置在云端,我们就可以通过fetch来获取不同的配置后再进行编译:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import fetch from 'node-fetch';
export default fetch('<某个远程服务或文件返回实际配置>');

// or
export default Promise.all([fetch('get-config-1'), fetch('get-config-2')]);
使用配置文件:

通过命令的config选项来指明配置文件。

显示执行
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rollup --config my.config.js
隐式执行

执行顺序:rollup.config.mjs -> rollup.config.cjs -> rollup.config.js

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rollup --config
自定义命令行选项:

在下面的配置文件中我们导入了两份提前写好的不同环境的配置文件,我们通过接收命令行传入的“configDebug”选项来选择使用哪一个配置文件进行执行。默认情况下命令行传入的选项的优先级最高,当然也可以在解析到传入的选项后进行拦截删除。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// rollup.config.js
import defaultConfig from './rollup.default.config.js';
import debugConfig from './rollup.debug.config.js';

export default commandLineArgs => {
  if (commandLineArgs.configDebug === true) {
    return debugConfig;
  }
  return defaultConfig;
};
编程提示:

Rollup附带了TypeScript类型,可以通过IDE的智能提示和JSDoc进行编写时的提示。也可以使用Rollup提供的帮助程序完成,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// rollup.config.js
import { defineConfig } from 'rollup';

export default defineConfig({
  // ...
});
Node 13+注意事项:
  1. 只能从 CommonJS 插件中获得默认导出;
  2. 无法直接导入 JSON 文件使用;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// load-package.cjs
module.exports = require('./package.json');

// rollup.config.mjs
import pkg from './load-package.cjs';
...
配置大全:

下面是摘录自rollupjs.org,的配置大全:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export default {
  // 核心输入选项
  external,
  input, // conditionally required
  plugins,

  // 高级输入选项
  cache,
  onwarn,
  preserveEntrySignatures,
  strictDeprecations,

  // danger zone
  acorn,
  acornInjectPlugins,
  context,
  moduleContext,
  preserveSymlinks,
  shimMissingExports,
  treeshake,

  // 实验性的配置
  experimentalCacheExpiry,
  perf,

  // 必需的(可以是一个数组,用于多个输出)
  output: {
    // 核心输出选项
    dir,
    file,
    format, // required
    globals,
    name,
    plugins,

    // 高级输出选项
    assetFileNames,
    banner,
    chunkFileNames,
    compact,
    entryFileNames,
    extend,
    footer,
    hoistTransitiveImports,
    inlineDynamicImports,
    interop,
    intro,
    manualChunks,
    minifyInternalExports,
    outro,
    paths,
    preserveModules,
    preserveModulesRoot,
    sourcemap,
    sourcemapExcludeSources,
    sourcemapFile,
    sourcemapPathTransform,
    validate,

    // danger zone
    amd,
    esModule,
    exports,
    externalLiveBindings,
    freeze,
    indent,
    namespaceToStringTag,
    noConflict,
    preferConst,
    sanitizeFileName,
    strict,
    systemNullSetters
  },

  watch: {
    buildDelay,
    chokidar,
    clearScreen,
    skipWrite,
    exclude,
    include
  }
};
命令行参数大全:

下面是摘录自rollupjs.org,的命令行参数大全:

简写

命令

参数

用途

-c

--config

filename

Use this config file (if argument is used but valueis unspecified, defaults to rollup.config.js)

-d

--dir

dirname

Directory for chunks (if absent, prints to stdout)

-e

--external

ids

Comma-separate list of module IDs to exclude

-f

--format

format

Type of output (amd, cjs, es, iife, umd, system)

-g

--globals

pairs

Comma-separate list of moduleID:Globalpairs

-h

--help

Show this help message

-i

--input

filename

Input (alternative to )

-m

--sourcemap

Generate sourcemap (-m inlinefor inline map)

-n

--name

name

Name for UMD export

-o

--file

output

Single output file (if absent, prints to stdout)

-p

--plugin

plugin

Use the plugin specified (may be repeated)

-v

--version

Show version number

-w

--watch

Watch files in bundle and rebuild on changes

--amd.id

id

ID for AMD module (default is anonymous)

--amd.autoId

Generate the AMD ID based off the chunk name

--amd.basePath

prefix

Path to prepend to auto generated AMD ID

--amd.define

name

Function to use in place of define

--assetFileNames

pattern

Name pattern for emitted assets

--banner

text

Code to insert at top of bundle (outside wrapper)

--chunkFileNames

pattern

Name pattern for emitted secondary chunks

--compact

Minify wrapper code

--context

variable

Specify top-level thisvalue

--entryFileNames

pattern

Name pattern for emitted entry chunks

--environment

values

Settings passed to config file (see example)

--no-esModule

Do not add __esModule property

--exports

mode

Specify export mode (auto, default, named, none)

--extend

Extend global variable defined by --name

--no-externalLiveBindings

Do not generate code to support live bindings

--failAfterWarnings

Exit with an error if the build produced warnings

--footer

text

Code to insert at end of bundle (outside wrapper)

--no-freeze

Do not freeze namespace objects

--no-hoistTransitiveImports

Do not hoist transitive imports into entry chunks

--no-indent

Don't indent result

--no-interop

Do not include interop block

--inlineDynamicImports

Create single bundle when using dynamic imports

--intro

text

Code to insert at top of bundle (inside wrapper)

--minifyInternalExports

Force or disable minification of internal exports

--namespaceToStringTag

Create proper .toStringmethods for namespaces

--noConflict

Generate a noConflict method for UMD globals

--outro

text

Code to insert at end of bundle (inside wrapper)

--preferConst

Use constinstead of varfor exports

--no-preserveEntrySignatures

Avoid facade chunks for entry points

--preserveModules

Preserve module structure

--preserveModulesRoot

Put preserved modules under this path at root level

--preserveSymlinks

Do not follow symlinks when resolving files

--no-sanitizeFileName

Do not replace invalid characters in file names

--shimMissingExports

Create shim variables for missing exports

--silent

Don't print warnings

--sourcemapExcludeSources

Do not include source code in source maps

--sourcemapFile

file

Specify bundle position for source maps

--stdin=ext

Specify file extension used for stdin input

--no-stdin

Do not read "-" from stdin

--no-strict

Don't emit "use strict";in the generated modules

编译完整版流程:

准备基础环境:

  1. 安装rollup,并使用rollup命令验证;
  2. 创建目录,准备内容;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
src
├─── main.js
└─── foo.js
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// src/main.js
import foo from './foo.js';
export default function () {
    console.log(foo);
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// src/foo.js
export default 'hello world!';
  1. 只编译,不输出到文件:

执行命令:rollup src/main.js -f cjs

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 输出内容
'use strict';

var foo = 'hello world!';

function main () {
    console.log(foo);
}

module.exports = main;
  1. 编译并输出到bundle文件:

执行命令:rollup src/main.js -o bundle.js -f cjs

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 输出内容
'use strict';

var foo = 'hello world!';

function main () {
    console.log(foo);
}

module.exports = main;
  1. 在node中使用这个bundle文件:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
node
> var myBundle = require('./bundle.js');
> myBundle();
'hello world!'

使用配置文件:

创建rollup.config.js配置文件,执行命令缩短为:rollup -c。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// rollup.config.js
export default {
  input: 'src/main.js',
  output: {
    file: 'bundle.js',
    format: 'cjs'
  }
};

使用插件:

awesome

为了安装插件需要更新项目环境:
  1. 初始化目录:npm init -y;
  2. 安装处理JSON文件的开发依赖:@rollup/plugin-json;
更新main.js,支持读取package.json:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { version } from '../package.json';

export default function () {
  console.log('version ' + version);
}
更新配置文件,配置安装的@rollup/plugin-json插件:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// rollup.config.js
import json from '@rollup/plugin-json';

export default {
  ...
  plugins: [json()]
};
再次编译并在node中使用:

编译后的产物将只包含使用到得version,体现了Tree-Shaking的作用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
'use strict';

var version = "1.0.0";

function main () {
    console.log('version ' + version);
}

module.exports = main;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
node
> var myBundle = require('./bundle.js');
> myBundle();
version 1.0.0

使用针对输出的插件:

使用rollup-plugin-terser插件对输出内容压缩:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// rollup.config.js
import json from '@rollup/plugin-json';
import { terser } from 'rollup-plugin-terser';

export default {
    input: 'src/main.js',
    output: [
        {
            file: 'bundle.js',
            format: 'cjs',
        },
        // 针对iife风格的输出处理
        {
            file: 'bundle.min.js',
            format: 'iife',
            name: 'version',
            plugins: [terser()],
        },
    ],
    plugins: [json()],
};
iife风格的输出产物将被压缩成一行:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var version=function(){"use strict";return function(){console.log("hello world!"),console.log("version 1.0.0")}}();
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-07-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
构建打包工具Rollup.js入门指南
最近在看Vue源码的时候发现一个新的打包工具Rollup.js,之前没有听说过这个工具,也不了解Rollup.js相比于常用的打包工具webpack有什么异同和优势,随后查了一下了解到Vue,React,D3,Three.js,Moment源码里都有它的身影,Rollup到底什么?这篇文章带你走进Rollup的世界。
用户1462769
2019/08/12
2.8K0
构建打包工具Rollup.js入门指南
一文快速上手Rollup,JavaScript类库打包好帮手
项目中一直用的都是webpack,前一段需要开发几个类库供其他平台使用,本来打算继续用webpack的,但感觉webpack用来开发js库,不仅繁琐而且打包后的文件体积也比较大。正好之前看vue源码,知道vue也是通过rollup打包的。这次又是开发类库的,于是就快速上手了rollup。
JowayYoung
2020/09/10
2.1K0
一文快速上手Rollup,JavaScript类库打包好帮手
rollup打包入门到实践
rollup在业务中基本很少会有接触到,通常在我们的业务中大部分接触的脚手架,或者自己搭建项目中,我们都是用webpack,无论是vue-cli,还是react-create-app他们都是基于webpack二次封装的脚手架,所以我们对rollup更陌生一点,本文是一篇关于rollup的学习笔记,希望看完在项目中有所思考和帮助。
Maic
2022/12/21
1.4K0
rollup打包入门到实践
rollup.js 初体验
近期准备写一个工具包 @kuizuo/utils,由于要将其发布到npm上,必然就要兼容不同模块(例如 CommonJS 和 ESModule),通过打包器可以很轻松的将代码分别编译成这不同模块格式。
愧怍
2022/12/27
7190
rollup.js 初体验
Rollup初探
需要注意的是参数 -f 是 --output.format 的缩写,用来指定 bundle 的类型,有以下选项:
用户1515472
2019/07/24
1.1K0
Rollup初探
使用rollup打包React Native插件并发布
我们写组件库或工具库时不可避免会用到外部库,这些外部库可能是符合 CommonJS 规范的。而 Rollup 力图实现 ES 模块的规范, 因此,加载 CommonJS 模块和使用 Node 模块位置解析逻辑都被实现为可选插件,默认情况下不在 Rollup 内核中。我们需要安装并配置 CommonJS 和 node-resolve 插件。
用户1250838
2021/05/31
2.4K0
使用roolup构建你的lib
Rollup, 和 Webpack, Parcel 都是模块打包工具(module bundler tool), 但是侧重点不同, 我们要聊的 Rollup更加适合用于构建lib 而 Webpack, Precel 更加适合开发应用。本文,将结合一个简单的例子说说如何使用Rollup构建自己的lib。
牛老师讲GIS
2021/09/10
6560
rollup打包ts+react最佳实践
前段时间系统性学习了webpack,针对于打包项目,webpack的确非常强大,也非常合适,但是用来打包组件库,就显得比较的繁琐。相较而言,使用rollup打包组件库,就显得非常的简单容易,而本文也将介绍它的基础用法。
Jou
2022/11/14
3.9K0
rollup打包ts+react最佳实践
Rollup的基本使用
rollup.js是一个模块打包工具,可以使项目从一个入口文件开始,将所有使用到的模块文件都打包到一个最终的发布文件中,Rollup极其适合构建一个工具库,Vue.js源码就是通过Rollup打包构建的。
WindRunnerMax
2021/02/25
1.4K0
前端组件/库打包利器rollup使用与配置实战
写rollup的文章是因为笔者最近要规范前端开发的业务流程和架构,并提供内部公有组件库和工具库供团队使用。在查阅大量资料并对比了webpack和rollup的优缺点之后,最终选择rollup来作为打包工具,我们最终要实现通过npm的方式安装我们的组件库和工具库:
徐小夕
2019/10/23
2.6K0
前端组件/库打包利器rollup使用与配置实战
深入了解rollup(二)常用配置
Rollup是一个JavaScript模块打包器,它可以将多个模块打包成一个单独的文件,以便在浏览器中使用。与其他打包工具相比,Rollup的主要优势在于它可以生成更小、更快的代码。在本文中,我们将深入了解Rollup的常用配置的使用方法。
can4hou6joeng4
2023/11/16
1.1K0
rollup 学习
Rollup 是一个用于 JavaScript 的模块打包工具,它将小的代码片段编译成更大、更复杂的代码。
落幕
2025/05/27
1590
rollup 学习
Rollup模块打包踩坑指南
Rollup是一个轻量级javascript模块打包器。相比于Webpack,Rollup更适合打包library。Rollup基于ES6模块,ES模块允许通过静态分析,实现tree-shaking优化,删除冗余代码。
luciozhang
2023/04/22
3.1K0
rollup快速入门
Rollup 是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码。
跑马溜溜的球
2020/12/07
3990
Rollup 基本概念及使用
Rollup是一款基于ESModule模块规范实现的JavaScript打包工具,在前端社区中赫赫有名,同时也在Vite的架构体系中发挥着重要作用。不仅是Vite生产环境下的打包工具,其插件机制也被Vite所兼容,可以说是Vite的构建基石。
xiangzhihong
2023/05/23
1.2K0
Rollup 基本概念及使用
【前端工程化】Rollup构建工具
笔者个人观点看来,想要完全掌握前端工程化,那么就得对行业现有的构建工具、流程管理、服务管理有一个全面以及深入的认识,无论是前端还是后端开发者,我们通过任意编程语言编写软件应用,这是基本能力,但作为工程师,我想那就是得具有工程化的能力,我们应该在开发工程中能够具有把控全局的能力,有业务上的视野,也得有技术上的沉淀,应该时刻思考,从程序设计、流程设计、方案设计上尽可能得去逼近符合业务场景的最佳实践。
小东同学
2022/07/29
2.1K0
【前端工程化】Rollup构建工具
关于Rollup那些事
下一代打包工具,这是rollup对自己的定位。如今的前端领域,构建工具并不缺少,每个前端工程师都用过或者听过webpack。可以看到的是像React、Vue等框架的构建工具使用的都是rollup。既然如此,这些框架为什么会选择rollup?它的特性是什么?面对不同场景,我们要怎么选择构建工具?本文将一一为你呈现。
腾讯IVWEB团队
2020/06/24
7180
【前端】:模块化 - 打包技术
ES modules export live bindings, not values, so values can be changed after they are initially imported as per.
WEBJ2EE
2020/09/01
1.5K0
【前端】:模块化 - 打包技术
webpack实战——JS打包工具
前面篇章叙述了关于webpack的许多内容,从入门,打包第一个模块,到进阶,最后到本地、生产及打包的优化。本篇则提及一下在JavaScript社区中另外的一些类似的打包工具,它们有的更加轻量、简洁,有的则更专注于某类特定场景等。通过了解这些,希望会有助于我们开发时从更多的角度和方向来认识打包工具及其发展,进而选用更加适合我们项目的打包工具。
流眸
2020/11/06
2.3K0
rollup从0到1
开发基于 typescript ES6 语法, 使用jest eslint 为校验或测试的npm包。 因为需要使用到 ts, 模块化,所以就存在模块编译打包的问题, 现有的打包工具中,webpack , Parcel 更偏向多类型资源 的web应用打包, 对于纯粹的npm工具包来说 rollup 更简单实用, 这里记录rollup的基础使用流程。
copy_left
2021/06/29
2.3K0
相关推荐
构建打包工具Rollup.js入门指南
更多 >
交个朋友
加入腾讯云官网粉丝站
蹲全网底价单品 享第一手活动信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验