- 编程语言
- 编译器
- 语言运行时
【免费下载链接】imba
🐤 The friendly full-stack language
本指南围绕 Imba 的模块(Modules)机制展开,系统讲解import/export的完整语法家族、默认导出与命名导出的使用方式,以及 Web 组件、自定义元素和全局样式如何通过模块导入在项目中生效。读完本文,你将能够熟练地在 Imba 项目中组织模块化的代码:拆分工具函数、按需导入导出成员、以命名空间批量引用,并理解为什么 Imba 的组件与样式"导入即全局可用"。
模块语法总览
Imba 的模块系统在语法层面与 ES Modules 高度一致,但针对 Imba 的语言特性做了贴合设计:函数(def)、类(class)、标签(tag)、样式(css)等一切可导出实体都可以统一用export导出,再用import按需引入。以下语法清单覆盖了全部导入形式:
import defaultExport from "module-name" import * as name from "module-name" import { export1 } from "module-name" import { export1 as alias1 } from "module-name" import { export1 , export2 } from "module-name" import { foo , bar } from "module-name" import { export1 , export2 as alias2 , [...] } from "module-name" import defaultExport, { export1 [ , [...] ] } from "module-name" import defaultExport, * as name from "module-name" import "module-name"从编译器的语法定义(grammar.mjs)可以看出,Imba 的ImportDeclaration规则逐一对应了上述形式:默认导入、命名空间导入(* as name)、花括号成员列表、默认导入与命名空间/成员的组合导入,以及不带任何导入项的纯副作用导入(IMPORT String)。值得留意的是,Imba 还支持在import前附加环境标志(ENV_FLAG),使同一份源码可以按目标运行环境(如浏览器、Node、Worker)条件性地执行导入语句。
导入默认导出
默认导出在模块系统中用于导出"最主要的那个东西",通常是模块的入口函数或类。导入方无需知道内部命名,直接用任意合法标识符接收即可:
import DefaultExport from './source'对应的导出侧,Imba 支持export default加任意可导出实体的组合。仓库测试目录 modules 中就给出了三种典型形态:
# export-default.imba export default def main return 1# export-default-class.imba export default class Util def random Math.random()# lib.imba export default def hello 'lib'从语法规则(grammar.mjs)看,EXPORT DEFAULT DefaultExportable中的DefaultExportable可以是任意表达式(Expression),因此默认导出不仅限于函数或类,任何在模块顶层可求值的实体都能作为默认导出。实际项目中,最常见的做法是让一个模块默认导出其核心函数或组件,同时附带若干命名导出作为辅助能力。
导入命名成员
命名导入用于精确获取模块中的某一个或某几个导出成员,这是日常拆分工具函数时最高频的写法:
import {capitalize,camelize} from './util'导出侧只需在每个成员声明前加上export关键字,函数、常量、类等一律适用:
export def capitalize return 123 export def camelize return 123Imba 对命名导出的解析同样完整支持EXPORT { ImportSpecifierList }(花括号列表)、EXPORT { ... } FROM String(转发导出)以及EXPORT EXPORT_ALL FROM String(export * from式整体转发,见 grammar.mjs)。这意味着你可以编写"桶模块"(barrel module),把多个模块的导出集中转发给使用者。
导入成员并重命名(别名)
当导入的成员名称与当前作用域内已有标识符冲突,或希望使用更贴合上下文的名称时,用as为成员起别名:
import {capitalize as upcase,camelize} from './util'export def capitalize return 123 export def camelize return 123上述代码中,capitalize以upcase之名进入当前作用域,而camelize保持原名。在编译器的 nodes.mjs 中可以看到别名的解析逻辑:_key优先取别名(this._alias),否则取原成员名,随后以_key在根作用域注册导入变量;而生成的 JavaScript 则输出为标准的capitalize as upcase形式(见 nodes.mjs)。这说明 Imba 的别名导入最终会原样映射到 ES Modules,保持与生态的互操作性。
以命名空间导入整个模块
当模块导出成员较多、且希望避免污染当前作用域时,可以用* as把整个模块收进一个命名空间对象,通过.访问其所有成员:
# [preview=console] import * as utils from './util' console.log utils.ping!, utils.pong!export def ping return 123 export def pong return 123此例中,utils.ping与utils.pong分别调用util模块中导出的两个函数。import * as name在语法上对应IMPORT ImportNamespaceSpecifier FROM String(grammar.mjs),命名空间说明符由IMPORT_ALL AS Identifier构成。命名空间导入非常适合封装工具集(utils)、常量表和 API 客户端等聚合型模块,让调用处代码保持清晰的"命名空间.成员"可读性。
导入单个导出
命名导入同样适用于只取一个成员的情况,只是花括号内只列出一项:
# [preview=console] import {myExport} from './util' console.log myExport!export def myExport return 123这里myExport直接以自身名字绑定到当前作用域。需要注意的是,Imba 调用无参函数时使用尾缀感叹号(myExport!)的隐式调用语法,这与命名导入相互独立、互不影响——导入只负责建立名称绑定,调用语法由使用处自行决定。
导入 Web 组件:导入即全局可用
Imba 模块体系最独特的特性之一,是 Web 组件并不需要通过名称显式导入。只要承载组件定义的文件在项目中被任何地方导入过一次,这些组件就在整个应用中全局可用:
import './controls' imba.mount do <div[pos:absolute inset:0 d:flex ja:center]> <my-component> <app-avatar>controls.imba # no need to export this - it is globally available # as long as the file is imported somewhere in your project tag my-component <self[d:inline-block p:2]> "Custom component" tag app-avatar <self[d:inline-block]> "Avatar"这段示例演示了两个关键点:
import './controls'是纯副作用导入——不导入任何成员,仅仅为了让编译器/打包器把controls.imba纳入构建。从语法上看它对应IMPORT String规则,生成的代码不含绑定,只触发模块加载。controls.imba中的tag my-component、tag app-avatar无需export。Imba 的标签声明默认向全局标签注册表登记,只要文件被加载,组件名就能在任意模板中直接使用。这与普通函数/变量的"必须导出才能被外部引用"规则形成鲜明对比,理解这一差异是掌握 Imba 组件组织方式的关键。
导入自定义元素(Custom Element)
与全局标签不同,当你希望以"值"的形式引用组件(例如类型化使用、避免命名冲突)时,可以像普通成员一样导出并导入组件本身。此时组件通过export tag导出,导入方拿到的是该组件类,可在模板中以<MyElement>形式实例化:
import {MyElement} from './element' imba.mount do <div> <MyElement>export tag MyElement <self[d:inline-block p:2]> "Custom element here"从语法规则(grammar.mjs)看,Exportable明确包含TagDeclaration,即tag声明是可以被命名导出的合法实体。由此 Imba 提供了两种组件复用策略:不加export的全局标签(适合项目内共享的通用组件)与显式export tag的具名组件(适合需要作为依赖显式传递、或发布为库的一部分时)。发布组件库时,第二种方式能让使用者以import {MyElement} from 'my-lib'的方式明确引入,构建工具也能据此做更精确的依赖分析。
导入全局样式
全局样式(global css)与 Web 组件遵循同样的规则:必须被某个文件导入一次,才会进入构建产物并作用于整个项目。它同样采用纯副作用导入,不产生任何名称绑定:
import './styles' imba.mount do <div> <p> "Globally styled"global css p color:blue5当app.imba执行import './styles'后,styles.imba中定义的global css块会被纳入构建,从而让应用中所有<p>元素都获得color:blue5(Imba 内置调色板中的蓝色色阶)样式。需要说明的是,这一行为同时受构建配置影响——打包器在 bundle.imba 中配置的解析扩展名列表为['.imba','.imba1','.ts','.mjs','.cjs','.js','.svg'],说明模块解析天然覆盖 Imba 与 JavaScript/TypeScript 文件,样式导入走的是同一套模块解析管线;而 compilation.mjs 中也存在styles == "import"的编译分支,对应"样式以导入方式合入"的构建选项。因此,若你的项目通过imbaconfig.json或 CLI 把样式策略配置为 import 模式,这种导入式全局样式的行为会更加显式。
实战小结:一套清晰的模块组织模式
综合以上特性,可以在 Imba 项目中沉淀出如下模块组织习惯:
- 工具函数:放在
util类模块中,逐个export def,使用方按需import { fnA, fnB }或import * as utils; - 单一职责入口:每个功能模块用
export default暴露主函数/主类,辅助能力用命名导出补充; - 通用组件:直接
tag声明、不导出,由入口文件import './components/controls'一次性挂载,全项目模板可用; - 可复用组件库:用
export tag导出,使用方import { MyElement } from '...'精确引用; - 全局样式:放在独立
.imba文件中用global css定义,在入口处import './styles'确保进入构建。
通过把"值"(函数、类、常量)与"副作用"(组件注册、全局样式)的导入方式区分清楚,Imba 模块系统既保留了 ES Modules 的精确性与互操作性,又为 Web 组件和样式提供了贴合声明式开发体验的全局注册机制,这正是 Imba 作为全栈语言在组织大型前端应用时的核心优势所在。
- 编程语言
- 编译器
- 语言运行时
【免费下载链接】imba
🐤 The friendly full-stack language
相关推荐
Flow 模块类型系统全指南:`import type`、`export type` 与 `import typeof` 实战详解
Flow 模块类型系统全指南: import type 、 export type 与 import typeof 实战详解 在 Flow 中,类型别名( ty
开发工具静态分析代码质量uni-app UTS 模块系统实战指南:import/export、别名导入与跨模块数据共享
uni app UTS 模块系统实战指南:import/export、别名导入与跨模块数据共享 UTS(uni type script)是 uni app 与
示例工程前端移动开发跨平台JavaScript 模块化:深入理解 export 和 import 语法
JavaScript 模块化:深入理解 export 和 import 语法 在现代 JavaScript 开发中,模块化是组织代码的基础。本文将深入探讨 Ja
文档/教程前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考