有个前端项目,需要用到配置文件。这个配置文件实在是太大了,就想拆成多个小的,然后一一引入,组合成一个完整的配置文件。
如果是vue代码,这种情况根本是手到擒来,不费吹灰之力,而该前端项目是个普通的js程序。但其实,在编写VUE代码过程中,我们所熟知的import,export,并不是VUE的语法,而是js es6(?)的语法。所以,虽然不是VUE项目,现在一般的浏览器都能支持js代码中使用import和export。
思路是这样的:
1)将配置文件拆成一个主配置文件,以及多个小的js文件
2)每个小js文件里将内容通过export输出
3)在主配置文件中import这些小js文件
4)在html页面中引入该主配置文件,引入时,标记里需要加上 type=“module” 属性。
结果出来的问题就是,引入主配置文件后,里面的内容外部好像获取不到,说是没有定义,not defined。
究其原因,主要集中在2点:
1)通过引入的js模块文件,里面的变量不是全局性的,而是模块内部的
2)上面的加载语句,加载出来的内容,只有等到页面全部加载完毕后才能访问,一般放在window.onload事件里处理
下面是详细介绍。
1、小配置文件
//hjzl.js
export default [{pid: "hjzl",id: "hjzl-water",name: "花果山环境质量",type: "group",open: true,},{pid: "hjzl-water",id: "hjzl-water-2022",name: "2022年东海海水质量",type: "group",open: false,},{pid: "hjzl-water",id: "hjzl-water-2022",name: "2021年东海海水质量",type: "group",open: false,},
];
2、主配置文件
//config.js
import baseMaps from "./_baseMaps.js";
import baseLayers from "./_baseLayers.js";
import hjzl from "./_hjzl.js";
import hjjc from "./_hjjc.js";
import hjjg from "./_hjjg.js";
import hjyj from "./_hjyj.js";
import widgets from "./_widgets.js";//注意是window.config
window.config = {title: "花果山水帘洞新时代幺百零八五规划",plans: [...baseLayers, ...hjzl, ...hjjc, ...hjjg, ...hjyj],
};
3、html
齐天大圣府办公室
2、主配置文件
//config.js
import baseMaps from "./_baseMaps.js";
import baseLayers from "./_baseLayers.js";
import hjzl from "./_hjzl.js";
import hjjc from "./_hjjc.js";
import hjjg from "./_hjjg.js";
import hjyj from "./_hjyj.js";
import widgets from "./_widgets.js";//export ...
export default {title: "花果山水帘洞新时代幺百零八五规划",plans: [...baseLayers, ...hjzl, ...hjjc, ...hjjg, ...hjyj],
};
3、html
齐天大圣府办公室
我猜这幅图的意思是,
1)通常js文件下载时,是下载完js并执行,html的解析会受到中断和阻塞;
2)如果加上属性defer,那么下载js和解析html会并行,并且直到所有html加载完毕才执行该js
3)如果加上属性async,下载js和解析html会并行,然后中断html,执行js
4)如果type=“module”,那么就跟加defer属性一样。当然,module文件里有可能会引用其他module,它们也是并行下载的
5)如果type="module"同时async,参考3
所以,type="module"的情况下,js会在html加载完毕才执行,因此,module里面的内容只有放在window.onload里才能处理。
参考文章:
https://v8.dev/features/modules#defer
https://javascript.info/modules-intro