Menu

  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay
  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay

RequireJS学习笔记

24
Feb
2016

RequireJS学习笔记

By Alex
/ in JavaScript
/ tags RequireJS, 学习笔记
0 Comments
基础知识
JS模块系统

所谓模块化,是指应用程序由一组高度解耦的、存放在不同模块中的独特功能构成。

开源框架和ES6引入了多个JavaScript模块化系统:

  1. AMD(Asynchronous Module Definition,异步模块定义),RequireJS使用的模块化系统,浏览器优先
  2. CommonJS,Node.js使用的模块化系统,主要用于服务器端JS开发的模块化支持,同步化加载
  3. ES6模块化系统,语言级别的支持
模块加载器

模块系统仅仅是一套规范,浏览器并不理解这些规范。要加载模块,需要模块加载器的配合:

  1. RequireJS,理解AMD规范
  2. SystemJS,支持多种模块系统,包括AMD, CommonJS, ES6
  3. es6-module-loader:一个支持ES6模块的垫片库
  4. Browserify,让浏览器可以使用CommonJS模块系统
RequireJS简介

RequireJS是一个JavaScript文件和模块加载器,主要用于浏览器中,也支持Node.js之类的后端JavaScript运行环境。使用RequireJS有利于提高加载速度(异步)、帮助提高代码质量(模块化)。

RequireJS是AMD规范的实现,比起同步化的CommonJS规范,AMD更加适用于浏览器环境。

RequireJS支持绝大部分浏览器,包括IE 6.0。

可以到http://requirejs.org/docs/download.html下载RequireJS。

HelloWorld

为了有效的利用RequireJS优化工具,你应当把所有内联的脚本移出HTML文件。并且,在HTML中仅仅引用require.js:

index.html
XHTML
1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>RequireJS Study</title>
<!-- data-main提示RequireJS,在其自身被加载后,立即加载js/index.js文件 -->
<script type="text/javascript" src="requirejs/require.js" data-main="js/index"></script>
</head>
<body>
</body>
</html>

如果要避免RequireJS的加载动作阻塞UI渲染,可以把 <script> 标签放到 <body> 元素的后面。

上述的index.js,是应用程序的主脚本文件。 在此文件中,你可以使用RequireJS的API来加载任何其它你所需要的JavaScript文件:

js/index.js
JavaScript
1
2
3
4
5
6
7
8
9
10
console.log( 'loading index.js' );
// 加载目标JavaScript文件
// 使用模块标识符(module IDs)代替URL。模块标识符不需要加.js后缀,因为默认情况下RequireJS把所有文件都当做JS看待,此后缀会自动添加
requirejs( [ "utils/string-utils" ], function( util ) {
    /**
     * 此回调在js/utils/string-utils.js加载完毕后执行<br>
     * 如果string-utils.js中包含对define()的调用,那么此回调直到string-utils.js的依赖也被加载后,才执行
     */
    console.log( 'utils/string-utils.js loaded' );
} );

utils/string-utils.js
JavaScript
1
2
3
4
5
console.log( 'loading utils/string-utils.js' );
// 定义此文件的依赖
define( [ 'utils/utils' ], function() {
    console.log( 'utils/utils.js loaded' );
} );

utils/utils.js
JavaScript
1
console.log( 'loading utils/utils.js' );

打开浏览器访问index.html,控制台输出如下:

Shell
1
2
3
4
5
loading index.js
loading utils/string-utils.js
loading utils/utils.js
utils/utils.js loaded
utils/string-utils.js loaded

可以很清晰的看出RequireJS加载脚本的顺序。

用法
加载JS文件

与传统的 <script> 标签不同,RequireJS采用了不同的脚本加载机制。

RequireJS总是基于 baseUrl 的相对路径加载新的JS,baseUrl通常是data-main属性指定的脚本所在目录 。data-main属性指定了脚本加载的起始点。调用下面的函数可以手工设置baseUrl:

JavaScript
1
2
3
require.config( {
    baseUrl : "/another/path"
} );

如果既没有调用上述函数,也没有设置data-main属性,那么baseUrl和引用require.js的HTML的URL所在目录一致。

RequireJS默认假设所有依赖均为JavaScript脚本,因此将模块标识符转换为URL时,它会自动添加.js后缀。

如果模块标识符具有.js后缀、以/开头、或者包含http/https,则直接当做URL处理,不使用baseUrl + ModuleID + .js方式组装出URL。

RequireJS允许从不同位置加载模块:

JavaScript
1
2
3
4
5
6
7
8
requirejs.config( {
    // 默认的,模块从js/lib目录下加载
    baseUrl : 'js/lib',
    paths : {
        // 对于app开头的模块标识符,则从js/app目录加载
        app : '../app'
    }
} );
data-main入口点

data-main属性用来指定初始执行的模块标识符,此模块类似于传统编程语言的main函数,你可以在其中对RequireJS进行配置并加载第一个业务模块。

你不能假设此模块先于DOM中后续声明的JS加载和执行,原因是RequireJS默认为 <script> 标签添加了 async 属性。在data-main后声明其它脚本(额外的入口点)标签违背了其用意,data-main只适合单个入口点的情形。

定义模块

模块通常和JS文件一一对应,但是模块可以声明依赖关系、并且避免全局NS污染。 通过依赖关系树,RequireJS允许并发的加载多个模块,提高速度。

简单的模块

包含两个变量声明的模块:

app/person.js
JavaScript
1
2
3
4
define( {
    name : "Alex",
    age : 30
} );

如果需要进行前置的初始化动作,可以使用函数式定义:

app/person.js
JavaScript
1
2
3
4
5
6
7
define( function() {
    //执行前置工作
    return {
        name : "Alex",
        age: 30
    }
} );

注意:

  1. 模块初始化函数的返回值不一定是对象,任何合法的JavaScript函数返回值都是可以的,例如函数
  2. 遵循AMD规范的模块,其代码必须完全放置在模块初始化函数中,以避免全局NS的污染
包含依赖的模块

可以在定义模块时声明其依赖,依赖加载完毕之前,模块初始化函数不会被调用:

app/person.js
JavaScript
1
2
3
4
5
6
define( [ './room', './dining-table' ], function() {
    return {
        name : "Alex",
        age : 30
    }
} );
使用依赖

依赖模块可以直接作为入参,注入到当前模块的初始化函数的入参中:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
// app/room.js
define( {
    no : '1103'
} );
// app/person.js
define( [ './room', './dining-table' ], function( room ) {
    return {
        name : "Alex",
        age : 30,
        roomNo : room.no,
    }
} );

注意,入参注入的顺序,必须和模块依赖声明顺序一致。 

定义命名模块

你可以显式的命名模块:

app/person.js
1
2
3
4
5
6
define( 'app/person', [ './room', './dining-table' ], function() {
    return {
        name : "Alex",
        age : 30
    }
} );

通常不建议这样做,模块名称应当由优化工具根据JS文件名自动生成,这样可以增强可移植性并且利于多模块的打包。

JSONP服务依赖

可以将JSONP服务作为依赖声明,此时必须将JSONP的GET参数callback的值设置为define:

JavaScript
1
2
3
require( [ "http://gmem.cc/api/data.json?callback=define" ], function( data ) {
    // data就是JSONP返回的响应内容
} );

JSONP服务的返回值必须是JSON对象,数组、数字、字符串等不支持。

取消模块定义

函数 requirejs.undef() 可以让RequireJS忘记已经定义的某个模块。该函数使用的前提是,目标模块尚未被引用。 

配置

有几种方式来指定RequireJS的配置项。首先,你可以在顶级HTML或者JS中调用 config() 函数:

XHTML
1
2
3
4
5
<script src="scripts/require.js"></script>
<script>
  require.config({
  });
</script>

在data-main入口点调用此函数也是可以的,但是要注意data-main脚本的异步加载特性。

另外,你可以在RequireJS加载前,在全局变量require中存放配置信息:

XHTML
1
2
3
4
5
<script>
    var require = {
    };
</script>
<script src="scripts/require.js"></script>
配置项列表 
配置项 说明
baseUrl 查找所有模块(除非匹配paths)对应文件时,使用的基础URL前缀。支持跨域加载
paths 用于映射不存放在baseUrl下面的模块,可以指定模块的多个备选加载位置:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
requirejs.config(
    {
        enforceDefine: true,
        paths: {
            jquery: [
                //优先从CND加载
                'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min',
                //如果失败,从本地目录加载
                'lib/jquery'
            ]
        }
    }
);
shim 为那些非标准模块(没有使用define定义,且符合AMD规范)执行依赖和导出配置
map 执行模块标识符映射,用于从不同位置加载不同模块的依赖项,对于使用多个库版本的大型项目有用:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
requirejs.config( {
    map : {
        // 支持通配符,匹配所有没有详细规定的模块
        '*' : {
            'jquery' : 'jquery-2.2.2'
        },
        // 对于新模块,加载1.7版本的jQuery依赖
        'app/newmodule' : {
            'jquery' : 'jquery-1.7'
        },
        // 对于旧模块,加载1.0版本的jQuery依赖
        'app/oldmodule' : {
            'jquery' : 'jquery-1.0'
        }
    }
} );
config 用于向某个模块传递(应用级别的)配置信息:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
requirejs.config( {
    config : {
        'bar' : {
            size : 1
        }
    }
} );
// bar.js
define( function( require, exports, module ) {
    var size = module.config().size;
} );

注意,当向一个包传递配置信息时,应该把包的主模块(Main module)作为键,而不是包ID:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
requirejs.config( {
    config : {
        'pkg/index' : { // 向包传递配置时,这里必须使用包的主模块
            apiKey : 'XJKDLNS'
        }
    },
    packages : [ {
        // 声明一个pkg包,主模块为index
        name : 'pkg',
        main : 'index'
    } ]
} );
packages 用于从CommonJS包中加载模块
nodeIdCompat  Node.js将app.js和app看做同一个模块标识符,在RequireJS中默认不是。将此配置项设置为true,可以和Node.js兼容
waitSeconds  加载一个脚本的超时秒数,默认7。设置为0则永不超时
context 用于在同一个页面加载一个模块的多个版本 
deps 声明一个依赖的数组,这些依赖在require被定义后,立即异步的加载 
callback 当deps加载完毕后执行的回调函数
enforceDefine 如果设置为true,RequireJS发现加载的JS没有调用define()且不具有可供检查的shim导出字符串值时,会抛出异常
xhtml 如果设置为true,RequireJS使用document.createElementNS()来创建script元素
urlArgs RequireJS获取资源时,使用的额外URL参数,形式: pname1=pval1&pname2=pval2  
从2.2.0版本开始,此参数可以是一个函数:
JavaScript
1
2
// id模块标识符,url依赖的URL
function(id,url){};
scriptType 脚本的MIME类型,默认text/javascript
skipDataMain 从2.1.9开始,设置为true,则不会尝试去寻找data-main属性。当RequireJS被嵌入到一个工具库中时有用 
shim配置:和非AMD兼容的脚本一起工作

shim用于描述非标准模块的特征,你可以声明非标准模块的依赖项和“导出符号”。导出符号(exports)指出非标准模块中的哪一个全局变量代表此模块:

utils/Utils.js
JavaScript
1
console.log( 'Module: Utils loaded.' );

utils/StringUtils.js
1
2
3
4
5
6
7
8
9
10
11
12
console.log( 'Module: StringUtils loaded.' );
var StringUtils = {
    /**
     *
     * @param {String} str
     * @param {String} search
     */
    indexOf: function ( str, search ) {
        return str ? str.indexOf( search ) : -1;
    }
}
var StringUtilsBase = {};

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 require.config(
    {
        baseUrl: 'js',
        shim: {
            'utils/StringUtils': {
                // 确保Utils.js先于StringUtils.js加载,尽管两者都不遵循AMD规范
                deps: [ 'utils/Utils' ],
                // 在StringUtils.js中定义的全局变量StringUtils代表模块
                exports: 'StringUtils'
            }
        }
    }
);
require( [ 'utils/StringUtils' ], function ( SU ) { //SU == StringUtils,由于exports配置
    console.log( StringUtils.indexOf );
    console.log( SU.indexOf );
} );

上述代码运行结果如下:

1
2
3
4
Module: Utils loaded.
Module: StringUtils loaded.
function ( str, search ) { return str ? str.indexOf( search ) : -1; }
function ( str, search ) { return str ? str.indexOf( search ) : -1; }

你还可以指定init配置项,这是一个函数,其返回值代表模块:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
require.config(
    {
        baseUrl: 'js',
        shim: {
            'utils/StringUtils': {
                init: function () {
                    return {
                        StringUtils: StringUtils,
                        StringUtilsBase: StringUtilsBase
                    }
                }
            }
        }
    }
);

init和exports配置项冲突,不得联用。 

package配置:从CommonJS包中加载模块

RequireJS支持CommonJS的Package规范,可以从中加载模块。每个CommonJS包可以分配一个模块名称/前缀,对于每个包,其package配置可以指定以下属性:

  1. name:包的名称,用于模块名称/前缀映射
  2. location:包的位置,此URL相对于baseUrl,除非包含http/https或者以/开始
  3. main:包中的一个模块的名称,当某个脚本对包名进行require时,会自动require此“主模块”,默认值为main

package配置的示例:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
require.config(
    {
        //这里声明了两个保
        packages: [
            "cart",
            {
                name: "store",
                main: "store" //指定主模块
            }
        ]
    }
);
require( ['cart'],function(cart){} ); //cart/main.js会被加载
错误处理

RequireJS遇到的错误一般是404,或者通信超时,RequireJ提供了几种错误处理方式:

  1. 在调用require时指定回调,举例:
    JavaScript
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    require( [ 'jquery' ], function ( $ ) {
    }, function ( err ) { //第二个参数是错误处理回调
        var failedId = err.requireModules && err.requireModules[ 0 ];//requireModules为失败的模块的列表
        if ( failedId === 'jquery' ) {
            // 取消jQuery的定义,重新配置和加载
            requirejs.undef( failedId );
            requirejs.config(
                {
                    paths: {
                        jquery: 'local/jquery'
                    }
                }
            );
            require( [ 'jquery' ], function () {
            } );
        }
    } );
  2. 使用path配置,指定模块的备选加载路径
  3. 全局错误处理回调requirejs.onError,距离:
    JavaScript
    1
    2
    3
    4
    5
    6
    7
    requirejs.onError = function (err) {
        console.log(err.requireType);
        if (err.requireType === 'timeout') {
            console.log('modules: ' + err.requireModules);
        }
        throw err;
    };
插件

RequireJS通过插件机制来扩展其功能,这些插件和require.js分开维护,需要单独下载。

text插件

用于加载文本资源,任何以 text! 开头的模块被作为纯文本看待,示例:

JavaScript
1
2
3
4
5
6
7
require(
    [ "some/module", "text!some/module.html", "text!some/module.css" ],
    function ( module, html, css ) {
        //变量html的内容是some/module.html
        //变量css的内容是some/module.css
    }
);

text插件使用XHR来加载目标模块,注意CORS问题。

domReady插件

可以在页面加载完毕后执行特定的逻辑:

JavaScript
1
2
3
4
5
6
7
8
9
10
require( [ 'domReady' ], function ( domReady ) {
    domReady( function () {
        //这里的逻辑将在页面加载完毕后执行
    } );
} );
 
//更加简洁的方式:
require( [ 'domReady!' ], function ( doc ) {
   //这里的逻辑将在页面加载完毕后执行,入参是当前document对象
} );
FAQ
函数requirejs和require有什么区别

没有任何区别,仅仅在require这个名称已经被使用的情况下,才需要使用requirejs。

← Framework7知识集锦
RubyMine知识集锦 →

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Related Posts

  • 基于Kurento搭建WebRTC服务器
  • ExtJS 4的事件系统
  • WebStorm知识集锦
  • 基于Chrome Developer Tools的JavaScript开发与调试
  • 基于AngularJS开发Web应用

Recent Posts

  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
  • A Comprehensive Study of Kotlin for Java Developers
  • 背诵营笔记
  • 利用LangChain和语言模型交互
  • 享学营笔记
ABOUT ME

汪震 | Alex Wong

江苏淮安人,现居北京。目前供职于腾讯云,专注容器方向。

GitHub:gmemcc

Git:git.gmem.cc

Email:gmemjunk@gmem.cc@me.com

ABOUT GMEM

绿色记忆是我的个人网站,域名gmem.cc中G是Green的简写,MEM是Memory的简写,CC则是我的小天使彩彩名字的简写。

我在这里记录自己的工作与生活,同时和大家分享一些编程方面的知识。

GMEM HISTORY
v2.00:微风
v1.03:单车旅行
v1.02:夏日版
v1.01:未完成
v0.10:彩虹天堂
v0.01:阳光海岸
MIRROR INFO
Meta
  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
Recent Posts
  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
    In this blog post, I will walk ...
  • A Comprehensive Study of Kotlin for Java Developers
    Introduction Purpose of the Study Understanding the Mo ...
  • 背诵营笔记
    Day 1 Find Your Greatness 原文 Greatness. It’s just ...
  • 利用LangChain和语言模型交互
    LangChain是什么 从名字上可以看出来,LangChain可以用来构建自然语言处理能力的链条。它是一个库 ...
  • 享学营笔记
    Unit 1 At home Lesson 1 In the ...
  • K8S集群跨云迁移
    要将K8S集群从一个云服务商迁移到另外一个,需要解决以下问题: 各种K8S资源的迁移 工作负载所挂载的数 ...
  • Terraform快速参考
    简介 Terraform用于实现基础设施即代码(infrastructure as code)—— 通过代码( ...
  • 草缸2021
    经过四个多月的努力,我的小小荷兰景到达极致了状态。

  • 编写Kubernetes风格的APIServer
    背景 前段时间接到一个需求做一个工具,工具将在K8S中运行。需求很适合用控制器模式实现,很自然的就基于kube ...
  • 记录一次KeyDB缓慢的定位过程
    环境说明 运行环境 这个问题出现在一套搭建在虚拟机上的Kubernetes 1.18集群上。集群有三个节点: ...
  • eBPF学习笔记
    简介 BPF,即Berkeley Packet Filter,是一个古老的网络封包过滤机制。它允许从用户空间注 ...
  • IPVS模式下ClusterIP泄露宿主机端口的问题
    问题 在一个启用了IPVS模式kube-proxy的K8S集群中,运行着一个Docker Registry服务 ...
  • 念爷爷
      今天是爷爷的头七,十二月七日、阴历十月廿三中午,老人家与世长辞。   九月初,回家看望刚动完手术的爸爸,发

  • 6 杨梅坑

  • liuhuashan
    深圳人才公园的网红景点 —— 流花山

  • 1 2020年10月拈花湾

  • 内核缺陷触发的NodePort服务63秒延迟问题
    现象 我们有一个新创建的TKE 1.3.0集群,使用基于Galaxy + Flannel(VXLAN模式)的容 ...
  • Galaxy学习笔记
    简介 Galaxy是TKEStack的一个网络组件,支持为TKE集群提供Overlay/Underlay容器网 ...
TOPLINKS
  • Zitahli's blue 91 people like this
  • 梦中的婚礼 64 people like this
  • 汪静好 61 people like this
  • 那年我一岁 36 people like this
  • 为了爱 28 people like this
  • 小绿彩 26 people like this
  • 彩虹姐姐的笑脸 24 people like this
  • 杨梅坑 6 people like this
  • 亚龙湾之旅 1 people like this
  • 汪昌博 people like this
  • 2013年11月香山 10 people like this
  • 2013年7月秦皇岛 6 people like this
  • 2013年6月蓟县盘山 5 people like this
  • 2013年2月梅花山 2 people like this
  • 2013年淮阴自贡迎春灯会 3 people like this
  • 2012年镇江金山游 1 people like this
  • 2012年徽杭古道 9 people like this
  • 2011年清明节后扬州行 1 people like this
  • 2008年十一云龙公园 5 people like this
  • 2008年之秋忆 7 people like this
  • 老照片 13 people like this
  • 火一样的六月 16 people like this
  • 发黄的相片 3 people like this
  • Cesium学习笔记 90 people like this
  • IntelliJ IDEA知识集锦 59 people like this
  • Bazel学习笔记 38 people like this
  • 基于Kurento搭建WebRTC服务器 38 people like this
  • PhoneGap学习笔记 32 people like this
  • NaCl学习笔记 32 people like this
  • 使用Oracle Java Mission Control监控JVM运行状态 29 people like this
  • Ceph学习笔记 27 people like this
  • 基于Calico的CNI 27 people like this
Tag Cloud
ActiveMQ AspectJ CDT Ceph Chrome CNI Command Cordova Coroutine CXF Cygwin DNS Docker eBPF Eclipse ExtJS F7 FAQ Groovy Hibernate HTTP IntelliJ IO编程 IPVS JacksonJSON JMS JSON JVM K8S kernel LB libvirt Linux知识 Linux编程 LOG Maven MinGW Mock Monitoring Multimedia MVC MySQL netfs Netty Nginx NIO Node.js NoSQL Oracle PDT PHP Redis RPC Scheduler ServiceMesh SNMP Spring SSL svn Tomcat TSDB Ubuntu WebGL WebRTC WebService WebSocket wxWidgets XDebug XML XPath XRM ZooKeeper 亚龙湾 单元测试 学习笔记 实时处理 并发编程 彩姐 性能剖析 性能调优 文本处理 新特性 架构模式 系统编程 网络编程 视频监控 设计模式 远程调试 配置文件 齐塔莉
Recent Comments
  • qg on Istio中的透明代理问题
  • heao on 基于本地gRPC的Go插件系统
  • 黄豆豆 on Ginkgo学习笔记
  • cloud on OpenStack学习笔记
  • 5dragoncon on Cilium学习笔记
  • Archeb on 重温iptables
  • C/C++编程:WebSocketpp(Linux + Clion + boostAsio) – 源码巴士 on 基于C/C++的WebSocket库
  • jerbin on eBPF学习笔记
  • point on Istio中的透明代理问题
  • G on Istio中的透明代理问题
  • 绿色记忆:Go语言单元测试和仿冒 on Ginkgo学习笔记
  • point on Istio中的透明代理问题
  • 【Maven】maven插件开发实战 – IT汇 on Maven插件开发
  • chenlx on eBPF学习笔记
  • Alex on eBPF学习笔记
  • CFC4N on eBPF学习笔记
  • 李运田 on 念爷爷
  • yongman on 记录一次KeyDB缓慢的定位过程
  • Alex on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • haolipeng on 基于本地gRPC的Go插件系统
  • 吴杰 on 基于C/C++的WebSocket库
©2005-2025 Gmem.cc | Powered by WordPress | 京ICP备18007345号-2