佛山市品牌网站建设多少钱品牌网站制作流程图

当前位置: 首页 > news >正文

佛山市品牌网站建设多少钱,品牌网站制作流程图,建筑网课学习观后感,如何写一个wordpress主题模块循环依赖问题 在项目比较小的时候可能不怎么会遇到这个问题#xff0c;但项目一旦有一定的体量后就可能会遇到了。 我之前做项目时就遇到这个问题#xff0c;也是总结一篇文章。 比如这种类型的报错
commonjs存在的问题 先讲一下commonjs存在的问题。 CommonJS模块采…模块循环依赖问题 在项目比较小的时候可能不怎么会遇到这个问题但项目一旦有一定的体量后就可能会遇到了。 我之前做项目时就遇到这个问题也是总结一篇文章。 比如这种类型的报错
commonjs存在的问题 先讲一下commonjs存在的问题。 CommonJS模块采用深度优先遍历并且是加载时执行即脚本代码在require时就全部执行。一旦出现某个模块被“循环加载”就只输出已经执行的部分没有执行的部分不会输出。 举例子 // a.js require(./b.js); exports.a function () {};// b.js const { a } require(./a); a();// index.js require(./a.js);执行index.js 结果报错a is not function 执行流程 1 导入a.js require(a.js) // 此时moduleCache moduleCache {moduleA : {} }2 执行a.js为moduleA添加属性,发现第一行导入b.js模块a还没执行完执行b.js require(./b.js); // 此时moduleCache moduleCache {moduleA : {},moduleB : {} }3 执行b.js发现导入a.js此时moduleCache有moduleA,不会重复执行模块a的代码会直接用moduleCache中模块a已经导出的内容。 const { a } require(./a); 等价于 const {a} moduleCache.moduleA因为此时模块a的内容还未完全执行完所以解构的变量a是undefined还不是function所以报错。 webpack打包结果分析 // a.js import ./b.js; export const A () {};// b.js import { A } from ./a.js; A();// index.js import ./a;webpack打包结果 (() {use strict;var webpack_modules {./src/a.js: (unused_webpack_module,webpack_exports,webpack_require) {webpack_require.r(webpack_exports);webpack_require.d(webpack_exports, {A: () A,});var _b_jsWEBPACK_IMPORTED_MODULE_0__ webpack_require(./src/b.js);var A function A() {};},./src/b.js: (unused_webpack_module,webpack_exports,webpack_require) {webpack_require.r(webpack_exports);var _a_jsWEBPACK_IMPORTED_MODULE_0__ webpack_require(./src/a.js);(0, _a_jsWEBPACK_IMPORTED_MODULE_0.A)();},};var webpack_module_cache {};function webpack_require(moduleId) {var cachedModule webpack_module_cache[moduleId];if (cachedModule ! undefined) {return cachedModule.exports;}var module (webpack_module_cache[moduleId] {exports: {},});webpack_modulesmoduleId;return module.exports;}(() {webpack_require.d (exports, definition) {for (var key in definition) {if (webpack_require.o(definition, key) !webpack_require.o(exports, key)) {Object.defineProperty(exports, key, {enumerable: true,get: definition[key],});}}};})();(() {webpack_require.o (obj, prop) Object.prototype.hasOwnProperty.call(obj, prop);})();(() {webpack_require.r (exports) {if (typeof Symbol ! undefined Symbol.toStringTag) {Object.defineProperty(exports, Symbol.toStringTag, {value: Module,});}Object.defineProperty(exports, __esModule, { value: true });};})();var webpack_exports {};webpack_require.r(webpack_exports);var _aWEBPACK_IMPORTED_MODULE_0 webpack_require(./src/a.js); })();每个模块的代码会被放到一个对象 var webpack_modules {[moduleId] : 模块代码 }var webpack_modules {./src/a.js: (unused_webpack_module,webpack_exports,webpack_require) {webpack_require.r(webpack_exports); // 标记模块为ES模块webpack_require.d(webpack_exports, {A: () A, // getter});var _b_jsWEBPACK_IMPORTED_MODULE_0__ webpack_require(./src/b.js);var A function A() {};},./src/b.js: (unused_webpack_module,webpack_exports,webpack_require) {webpack_require.r(webpack_exports);var _a_jsWEBPACK_IMPORTED_MODULE_0__ webpack_require(./src/a.js);(0, _a_jsWEBPACK_IMPORTED_MODULE_0.A)();},};webpack自定义require导入函数 function webpack_require(moduleId) {var cachedModule webpack_module_cache[moduleId];if (cachedModule ! undefined) {return cachedModule.exports;}var module (webpack_module_cache[moduleId] {exports: {},});webpack_modulesmoduleId;return module.exports; }跟commonjs规范类似 查看缓存是否有模块导出结果如果模块执行过了返回模块导出结果在执行模块代码之前先创建模块导出对象module.exports将模块导出对象传入执行模块代码 webpack_require.d // 定义模块导出属性 webpack_require.o // 检查模块导出对象是否具有某个属性 webpack_require.r // 标记模块为ES模块模块代码执行前会先进行 将模块导出对象标记ES模块如果模块有导出内容会将这些内容定义到模块导出对象 代码执行流程 模块A执行 webpack_require.r(webpack_exports); webpack_require.d(webpack_exports, {A: () A, // 定义getter }); var _b_jsWEBPACK_IMPORTED_MODULE_0 webpack_require(./src/b.js); // 执行到这里 会暂停a模块代码执行执行b模块var A function A() {};moduleA 定义了一个A属性A属性是一个存取器属性有gettergetter就是返回真正导出的A。 执行b模块时()A,这里返回的A还是undefined。 执行b模块 webpack_require.r(webpack_exports); var _a_jsWEBPACK_IMPORTED_MODULE_0 webpack_require(./src/a.js);(0, _a_jsWEBPACK_IMPORTED_MODULE_0.A)();跟Commonjs的问题一样模块A还没有执行完A还没有赋值所以A这里是undefined不能作为函数调用。 这里和commonjs还是有些区别 打包结果中模块代码执行前会去先定义导出属性为属性设置一个getter因此在代码模块执行前这些导出属性就已经在导出对象中有getter。 这里因为配置babel打包结果会把const转成var所以变量声明提升了如果是const就会变成变量在声明前使用。 结论 项目会形成循环依赖实际开发中很难避免有可能引入了某个模块就会导致形成依赖链路。 形成循环依赖链路并不一定会报错但是在执行到对应模块时之前模块因为导入其他包模块代码还没完全执行完内容还没完全导出就有可能导致报错。 其实导致报错还好因为可以提前在本地就感知到处理但是如果你只是定义了一个变量那么这个变量可能是在你还没有赋值的时候就引用了所以其实模块导出的变量并不是一定可信的。 其实在遇到函数调用报错时可以通过把一些函数表达式改成函数声明就好因为打包结果模块的执行其实是执行一个函数在执行前会有函数声明提升但尽量不要用这种规范来处理因为很可能会遇到更多坑。 其实有模块循环依赖后还报错本身就是这条依赖链路有问题应该找到不合理的地方解决而不是去规避。用函数声明解决一些问题反倒会留下一些坑可能某些环境的值原本因为循环依赖导致引用时是undefined,但是碰巧你用函数声明避免了一些报错导致埋了一个坑。 有一些工具可以分析项目中的循环链路eslint也有相应的配置。 至于如何找到循环依赖的不合理地方就凭经验吧这里就不展开了毕竟是个人观点。