好用的import: Vite的Glob 导入

简介: 好用的import: Vite的Glob 导入

Vite 的 Glob 导入


【内容简介】 在 Vite 中有一个特殊的导入方式,即我们今天打算讨论的 Glob 导入 。这种导入弥补完善了JavaScript导入体系中不能同时导入到某个文件目录的多个文件的缺陷。


1. 回顾 JavaScript import

JavaScript 模块是声明性的,模块之间的关系是根据文件级别的导入和导出来指定的。模块中声明的变量、函数、类等在模块外是不可见的模块依赖于importexport

如果想要导入,那么以为着你必须先在一个文件中导出,如:

export const numberRegexp = /^[0-9]+$/;

静态导入可以用以下方式来表达:

import "module-name";
import { export1 , export2 } from "module-name";
import defaultExport from "module-name";
import { export1 , export2 as alias2 , [...] } from "module-name";
import defaultExport, { export [ , [...] ] } from "module-name";
import * as name from "module-name";
import defaultExport, * as name from "module-name";
import { export } from "module-name";
import { export as alias } from "module-name";

你也可以动态加载模块,这需要一个import()函数。它返回一个 promise,它用一个模块对象来实现。如:

import('/modules/myModule.js')
  .then(module => {
    ...
  })
  .catch(err => {
    ...
  });
// 也可以用 await 
let module = await import('/modules/myModule.js');

这些基于JavaScript的导入方法用起来有一个缺点,就是无法监视目录文件的变化。在开发中我们如果能将一个目录是为一个整体进行导入,那么该目录中的所有子目录与文件就可以有层级的获取,而不是一个一个写在道路路径里如'/modules/myModule.js'

比如Python的著名重量型Web框架Dajngo,其一个子应用就是以一个目录为整体的模块进行组织的,这当然要求一次能够导入一个目录并能够区分目录中的层级。

2. Glob 导入即基本使用与原理

Glob 导入即Vite中提供的 import.meta.glob()import.meta.globEager() 导入函数。 Glob 导入可以导入目录中的所有文件/目录,也可以对文件/目录进行匹配筛选。

会被当成导入标识符:必须是相对路径(以 ./ 开头)或绝对路径(以 / 开头,相对于项目根目录解析)。

2.1 glob()导入函数

glob()导入函数指的是 import.meta.glob() ,这种导入是动态导入,匹配到的文件默认是懒加载的。因此如果你使用该导入,自然如果被导入的某个模块中具体代码有错误页不会被抛出。

现在有一个目录如下:

我们在另外一个位置建立一个文件,相对目录表示该路径为'./test/,现在我们尝试以下几种方法看看导入完成了什么事情:

(1)所有当前目录层级下的文件

export const modules = import.meta.glob('./test/*')

这里我们使用了通配符来匹配所有的文件。但是这不会包含其中的目录。

展开后可以看到:

{./test/b.ts: ƒ, ./test/c.ts: ƒ, ./test/d.ts: ƒ}
./test/b.ts: () => import("/src/test/b.ts")
./test/c.ts: () => import("/src/test/c.ts")
./test/d.ts: () => import("/src/test/d.ts?t=1639678566331")

因为,import.meta.glob(‘./test/*’)相当于在上面被转译成了以下代码:

const modules = {
  './test/b.ts': () => import("/src/test/b.ts"),
  './test/c.ts': () => import("/src/test/c.ts"),
  './test/d.ts: ()' => import("/src/test/d.ts")
}

显然,这时以模块的相对路径作为“键”,导入的内容整体作为为响应 你可以遍历 modules 对象的 key 值来访问相应的模块:

for (const path in modules) {
  modules[path]().then((mod) => {
    console.log(path, mod)
  })
}

(2)所有当前目录层级下特定类型的文件

export const modules = import.meta.glob('./test/*.ts')

2.2 globEager()导入函数

globEager()导入函数是指 import.meta.globEager() 。从功能上来看,它与glob()函数几乎完全一样。但是这中导入是静态的,它将在你掉用该函数时直接引入所有的模块。

这意味这,如果你在一次性导入所有模块时,这些某块都将被加载,且要求所有模块在语法上时正确的,否则将抛出错误。

还是刚才的目录:

export const aaa = import.meta.globEager('./test/*.ts')

可以清楚的看到有一个最明显的区别时,各个模块被立即导入进来作为以各自相对路径为键的值。

这种方式将被转换成如下代码:

// vite 生成的代码
import * as __glob__0_0 from './test/b.ts''
import * as __glob__0_1 from './test/c.ts''
import * as __glob__0_2 from './test/d.ts''
const modules = {
  './test/b.ts'': __glob__0_0,
  './test/c.ts'': __glob__0_1,
  './test/db.ts'': __glob__0_2,
}

3. 示例:通过Glob 导入子目录特定文件

这时一个简单的例子。由于在之前的例子中我们看到,导入没有将文件系统中的目录带进来,而只有文件的键值对,似乎不能同时处理所有子目录中的文件,其实不然。

现在我们动态导入test所有子目录中的文件:

export const aaa = import.meta.glob('./test/*/*')

仅此小例启发诸君。

目录
相关文章
|
5月前
|
JavaScript 前端开发
JS require 与 import 的区别
JS require 与 import 的区别
120 1
|
5月前
|
JavaScript 前端开发
JS中 require 与 import 的区别
JS中 require 与 import 的区别
|
12月前
|
Python
python flask 后端报错 ImportError: cannot import name ‘cached_prope‘
问题python flask 后端报错 ImportError: cannot import name ‘cached_prope‘flask程序启动但抛出该错误,是因为werkzeug 版本过高,需要降低版本即可 解决:一般这种情况是需要注意第三方库版本的对应,werkzeug需要0.16.0 版本时 flask的版本应该时1.x.x 的版本,不能是2.x过高的版本。
146 0
Python模块——glob模块详解
Python模块——glob模块详解
Python模块——glob模块详解
|
4月前
|
XML 数据格式 Python
Python模块导入包括:`import math`导入标准库
【6月更文挑战第23天】Python模块导入包括:`import math`导入标准库,`from math import sqrt`导入单个函数,`import numpy as np`给模块取别名,`from random import *`导入所有(不推荐),`import xml.etree.ElementTree as ET`导入子模块,`import_module('pandas')`按需导入,和使用相对路径如`from .module import func`处理项目结构。记得调整`sys.path`以包含自定义模块路径。
73 4
|
5月前
|
前端开发 开发者
sass中的导入与部分导入
sass中的导入与部分导入
|
11月前
ES6 import导入重命名
ES6 import导入重命名
127 0
|
Python
Flask开发 导入flask_uploads包时提示“IMPORTERROR: CANNOT IMPORT NAME ‘SECURE_FILENAME‘ FROM ‘WERKZEUG‘“
在使用Flask开发过程中,使用Flask_uploads模块开发上传文件功能时,在项目中导入该包时,提示“ImportError: cannot import name ‘secure_filename’ from 'werkzeug”错误。
557 0
Flask开发 导入flask_uploads包时提示“IMPORTERROR: CANNOT IMPORT NAME ‘SECURE_FILENAME‘ FROM ‘WERKZEUG‘“
|
Python
flask开发导入flask_uploads包时提示"ImportError: cannot import name 'secure_filename' from 'werkzeug'"
在使用Flask开发过程中,使用Flask_uploads模块开发上传文件功能时,在项目中导入该包时,提示“ImportError: cannot import name ‘secure_filename’ from 'werkzeug”错误。
296 0
|
JavaScript 前端开发
js中的import和export
# 引言 我们在开发时,如果将 JavaScript 加载到页面中,通常是以小片段的形式提供效果和交互,一般会把所有的 JavaScript 代码全都写在一个文件中,并加载到一个 `script` 标签中。尽管可以把 JavaScript 拆分为多个文件,但是所有的变量和函数仍然会被添加到全局作用域中。 由此我们需要使用第三方代码来完成常见任务,并且需要把代码分解为模块化的文件,避免污染全局命名空间。 ECMAScript 2015 规范在 JavaScript 语言中引入了 *module*,也有了 import 和 export 语句。 `import`和`eport`声明共同作用