动态导入

121 阅读2分钟

为什么要使用动态导入?

什么情况下使用动态导入

首先我们先了解一下文件颗粒度之后会产生什么 例如:util 下面的 index 文件,文件存放我们常用的工具函数,当函数到达一定的量就会导致文件过大,大到某种程度之后,并且某些文件之间有调用之后就会变得难以维护。此时就需要分离出一部分函数到另一个文件中 index2。然而我们使用事希望挂载到某个对象身上 例如:

// util 文件夹
import util from "util/index"
vue.prototype.util = util
// mian.js
import util from "util/index"
vue.prototype.util = util

提出一部分函数之后

util/index
import xxx1 from "util/xxx1"
import xxx2 from "util/xxx2"
export default {
    ...index1,
    ...index2
}
// mian.js
import util from "util/index"
vue.prototype.util = util

但是如果我们要再次提取一部分函数成为一个文件

util/index
import xxx1 from "util/xxx1"
import xxx2 from "util/xxx2"
import xxx3 from "util/xxx3"
export default {
    ...index1,
    ...index2,
    ...index2,
}
// mian.js
import util from "util/index"
vue.prototype.util = util

需要修改两个地方我们不仅需要新建文件,还需要修改 index 文件,我们希望只需要生成文件,让 index 文件更具当前文件下的模块(文件)自动导入导出于是就可以使用以下

require.context

require.context是 webpack 中,用来创建自己的(模块)上下文 webpack会在构建的时候解析代码中的require.context() 作用:常常用来在组件内引入多个组件 directory:表示检索的目录 useSubdirectories:表示是否检索子文件夹 regExp:匹配文件的正则表达式,一般是文件名 例如 require.context("@/views/components",false,/.vue$/) require.context(directory, useSubdirectories = false, regExp = /^.//) 获取默认导出

// 获取interface 文件夹下面的所有模块的默认导出
const files = require.context("./interface", true, /\/*.ts/);
let module = {};

files.keys().forEach(filepath=>{
    const name = filepath.replace(/.\/|.ts$/g, "");
    const value = files(filepath);
    module[name] = value
})

获取具名导出

// 获取具名导出
const files = require.context("./interface", true, /\/*.ts/);
let api = {};

files.keys().forEach(filepath => {
    const module = files(filepath);
    for (const key in module) {
        if (Object.prototype.hasOwnProperty.call(module, key)) {
            const value = module[key];
            api[key] = value
        }
    }
})

export default api

import.meta.glob

import.meta.glob 是 对应 上面 require.context 方法
import.meta.glob 为动态导入,构建时,会分离为独立的 chunk;而import.meta.globEager为直接引入
import.meta.glob("./interface/*.ts");
获取默认导出
import { DAMNU_ENABLE } from "../../type";

const files = import.meta.glob("./interface/*.ts");
let module: DAMNU_ENABLE = {}

async function getApi() {
    let keys = Object.keys(files);
    for (let i = 0; i < keys.length; i++) {
        const name = keys[i].replace(/\.\/interface\/|\.ts/g, "") as string;
        const item = await files[keys[i]]()
        module[name] = (item as { default: DAMNU_ENABLE }).default

    }
}

await getApi();

export default module

获取具名导出

import { DAMNU_ENABLE } from "../../type";

const files = import.meta.glob("./interface/*.ts");
let module: DAMNU_ENABLE = {}

async function getApi() {
    let keys = Object.keys(files);
    for (let i = 0; i < keys.length; i++) {
        const name = keys[i].replace(/\.\/interface\/|\.ts/g, "") as string;
        const item = await files[keys[i]]()

        let names = Object.keys((item as DAMNU_ENABLE));
        for (let i = 0; i < names.length; i++) {
            module[names[i]] = (item as DAMNU_ENABLE)[names[i]]
        }

    }
}

await getApi();

export default module