☰
Imba 模块系统详解:import 与 export 语法、Web 组件与样式导入实战
2026/10/7 2:06:28 网站建设 项目流程
  • 编程语言
  • 编译器
  • 语言运行时

【免费下载链接】imba

🐤 The friendly full-stack language

项目地址:https://gitcode.com/gh_mirrors/im/imba
点击查看免费下载

本指南围绕 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 123

Imba 对命名导出的解析同样完整支持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"

这段示例演示了两个关键点:

  1. import './controls'是纯副作用导入——不导入任何成员,仅仅为了让编译器/打包器把controls.imba纳入构建。从语法上看它对应IMPORT String规则,生成的代码不含绑定,只触发模块加载。
  2. 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

项目地址:https://gitcode.com/gh_mirrors/im/imba
点击查看免费下载
上一篇:前端架构师面试通关指南:掌握awesome-front-end-system-design的系统设计核心
下一篇:Joplin 推荐插件机制解析:皇冠标签背后的信任体系与实现原理

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询