什么是模块
在dagger.js中,我们把html模板,脚本,层叠样式表等可复用的代码片段统称为模块。
模块类型列表
模块的加载时机
dagger.js实现了一个运行时模块管理器,所有的模块都是在浏览器运行时动态加载、解析和执行的。
如何注册模块
在安装章节中我们曾经提到,项目的入口页面要添加一个类型为“dagger/modules”的script标签作为应用程序配置项。在使用模块前,您需要先在配置项中对其进行注册。一个典型的模块注册项(内容为json格式)包括如下信息:
1. 模块名。由注册项的键指定。合法的模块名称(除去模板模块之外)由“$”,“-”,“_”,大小写字母和数字组成,首字符不能是数字。
2. 模块的资源加载位置。由注册项值的“uri”字段指定。其内容可以是url地址(远程资源),DOM选择器(本地资源),也可以是另一个模块的路径(引用资源)。
3. 模块的类型。由注册项值的“type”字段指定。
我们来看示例:
在上面的例子中,我们通过配置项注册了三个模块:
1. 脚本模块“remote_script”,其内容加载自远程urlhttps://codepen.io/dagger8224/pen/zYRpYpa.js。
2. json模块“embedded_json”,其内容加载自DOM选择器“#json”对应的本地元素。
3. json模块“json_alias”,其内容与模块“embedded_json”相同。
如何使用模块
您可以在指令表达式中通过回调参数对象“$module”访问模块内容(模板和样式模块除外)。与作用域类似,您也可以通过匿名方式访问$module下的字段:
+click="$module.func($scope.value)" // 具名方式访问模块和作用域对象
+click="func(value)" // 匿名方式访问模块和作用域对象
请注意,如果当前指令表达式中的“$module”和“$scope”回调参数对象下包含同名字段,请使用具名方式以避免访问冲突(匿名情况下,作用域对象下字段的访问优先级更高)。
+click="func(value)" // 匿名方式访问模块和作用域对象
模块类型的自动推断
大部分情况下,您并不需要显式指定模块类型,dagger.js能够智能地根据资源内容自动进行模块类型推断。省略了“type”字段的模块配置项值可以由对象退化为指向资源位置的字符串。模块类型的具体推断规则参见下表:
| uri类别 | 推断依据 | 推断结果 | 示例 |
|---|---|---|---|
| 远程资源 | url地址后缀为“.js” | 脚本模块 | ./script.js |
| MIME类型为“application/javascript” | |||
| MIME类型为“javascript/esm” | |||
| MIME类型为“text/javascript” | |||
| url地址后缀为“.css” | 样式模块 | ./style.css | |
| MIME类型为“text/css” | |||
| url地址后缀为“.html”且资源文件内容不包含<html>标签 | 模板模块 | ./template.html | |
| MIME类型为“text/html”且资源文件内容不包含<html>标签 | |||
| url地址后缀为“.html”且资源文件内容包含<html>标签 | 名空间模块 | ./namespace.html | |
| MIME类型为“text/html”且资源文件内容包含<html>标签 | |||
| url地址后缀为“.json” | json模块 | ./json.json | |
| MIME类型为“application/json” | |||
| 不满足上述条件的远程资源 | 字符串模块 | ./string.txt | |
| 本地资源 | 资源容器是类型为“dagger/script”的<script>标签 | 脚本模块 | script |
| 资源容器是类型为“dagger/style”的<style>标签 | 样式模块 | style | |
| 资源容器是<template>标签 | 模板模块 | template | |
| 资源容器是类型为“dagger/json”的<script>标签 | json模块 | json | |
| 资源容器是类型为“dagger/string”的<script>标签 | string模块 | string | |
| 引用资源 | 被引用模块为脚本模块 | 脚本模块 | script |
| 被引用模块为样式模块 | 样式模块 | style | |
| 被引用模块为模板模块 | 模板模块 | template | |
| 被引用模块为json模块 | json模块 | json | |
| 被引用模块为string模块 | string模块 | string |
条件加载模块资源
您可以将模块配置项值设置为一个数组,每个数组子项声明一个“match”字段作为过滤条件(支持媒体查询表达式),dagger.js将数组中第一个匹配过滤条件的结果作为模块的配置。您可以通过设置适当的条件配置项实现模块资源内容的响应式匹配(用来区分PC端和移动端等)。我们来看例子:
上面的例子中,由于模块“script_module1”的配置项数组中第一个元素的“match”字段执行结果为false,dagger.js将跳过对资源内容“./invalid.js”的加载。第二个配置项元素的“match”字段执行结果为true,因此dagger.js将加载url“https://codepen.io/dagger8224/pen/bGLLjYN.js”作为当前模块的内容。
为模块指定多个资源地址
您可以将“uri”字段内容设置为一个数组,dagger.js会依次尝试加载列表中指定的资源,直到成功加载模块为止。您可以在生产环境中为模块资源指定多个可选地址以提升应用程序的容灾能力。我们来看例子:
上面的例子中,模块“script_module1”匹配配置项(第二个)的“uri”字段内容是一个数组,dagger.js将首先尝试加载无效地址“./invalid2.js”的内容,在请求失败后,将继续尝试加载地址“https://codepen.io/dagger8224/pen/bGLLjYN.js”的内容,此时资源加载成功,因此不会再继续加载备用资源地址“./invalid3.js”。打开浏览器控制台,您可以看到一个“./invalid2.js”加载404的错误信息。
在配置项中直接声明模块资源内容
您也可以在配置项中指定“content”字段直接声明模块资源的内容(此时将忽略“uri”字段)。请注意,使用“content”来指定模块内容时自动推断规则将失效,您必须通过“type”字段显示指定模块类型。我们来看例子:
将模块资源定义在单独的文件或者DOM容器中更利于实现复用。通常来说,您应该避免使用“content”字段指定资源内容。
模块配置项中的其他可选通用字段
1. “base”,字符串类型,用于指定当前模块中远程资源相对路径的baseURI值,如果未指定,子模块的“base”将默认继承自其父级名空间模块。如果当前模块位于根名空间下,则其“base”默认指向当前页面的document.baseURI。我们来看例子:
2. “candidates” ,对象数组类型。用于指定备选配置内容,框架将从数组中筛选出首个满足“match”字段表达式条件的子项,融合到当前配置项下再进行解析。我们来看例子:
3. “integrity”,字符串类型。用于对远程资源内容进行sha256子资源完整性校验。您应该在产品环境使用“integrity”校验第三方模块以提升产品安全性。我们来看例子:
4. “prefetch”,字符串类型。主要用于在不阻塞当前路由场景视图渲染的前提下提前加载耗时较长的模块资源内容。框架在解析时将“prefetch”内容转换为正则表达式与当前的hash path匹配,预加载模块将只阻塞满足匹配条件的路由场景视图渲染。我们将在路由章节演示相关示例。