js模块间引用的一处疑惑

本人小白,最近在学习 vue-router,看源码的时候加了些输出语句如下所示。
index.js 和 install.js 在同一个目录下,index.js 中引用 install.js。

//index.js
console.log('index line 2');
import { install } from './install'
console.log('index line 4');
//install.js
console.log('install line 3');
//略
console.log('install line 56');

按照我的理解,应该是最先打印index line 2,然后打印install line 3,install line 56,最后打印index line 4。但是在浏览器里执行,结果如下所示。搞不懂
图片描述

阅读 2.4k
4 个回答

import命令具有提升效果,会提升到整个模块的头部

为了支持ES6的模块导入, webpck 自己有一套 import/export 机制, 你遇到的这种问题,应该是 webpack 的模块加载机制引发的

楼上两位回答加起来就是了, 规范这么要求,webpack就这么做了

javascript模块化发展
这个问题说来话长,完整了解需要从javascript这门语言天生缺少模块(module)化机制说起。下面长话短说.

最早,在ES6之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。
然后ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范。

ES6 模块的设计思想
ES6设计尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。而CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性,基本上是整体加载一个模块。
而ES6模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入,请认真记住并好好理解这句话。
ES6 可以在编译时就完成模块加载,也称为静态加载。

import命令提升效果
针对你的疑惑,其实了解一下import的命令机制就好了。
import命令具有提升效果,会提升到整个模块的头部,首先执行。
比如,下面的写法并不会报错,就是因为提升效果

foo();
import { foo } from 'my_module';

而除此之外,还有很多静态加载模块带来的一些特性,比如不能使用表达式等,可以单靠文档学习

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题