最近一两个月在思考未来自己的职业规划,团队内小伙伴陆陆续续走的走,来的来。大家都处于职业的焦虑之中,我一直都很想进一家大厂,目前仍然没有机会,也没有能力能够进去。毕业已经3年整了,不能继续说打好基础,把所有的业余精力都放在js基础学习上。应该着眼于自己的优势和有竞争力的方面努力,这样才不容易被取代。所以前端工程化是必不可少的深挖领域,以后博客都会产出工程化相关的文章。
前端工程化是一个很大的议题,基本上工程化体系是离不开webpack和js模块。首先先从模块说起,面试的时候免不了会被问到几个模块相关的问题。例如
模块化就是将一个大文件拆分成相互依赖的小文件,再通过打包工具进行统一的拼装和加载。有人会问了模块化的好处是什么,或者说为什么要做模块化?其实这样做的好处可以从两个角度分析
js的模块标准有两种 commonjs module和es6之后开始支持的es module。node应用采用的commonjs module规范,web应用一般采用es module规范。
commonjs module简称cjs,es module简称mjs,下同。
示例源码
cjs
//add.js
function add(a,b){
return a+b;
}
module.exports={add};
//index.js
const {add} =require(‘./add‘);
add(1,2);
模块的导入导出需要注意的问题
//add.js
function add (a,b){
return a+b
};
exports={add};
exports.add=function(a,b){
return a+b;
}
module.exports={
name:‘jack‘
}
mjs
//add.js
function add(a,b){
return a+b;
}
export {
add
}
// index.js
import {add} from ‘./add‘;
add(1,2);
到这里可以思考一个问题,
我们可以直接export default一个字面量对象吗?在导入的时候能解构到想要到值吗?来看下下面的代码
//add.js
function add(a,b){
return a+b
}
export default {
add
}
// index.js
import {add} from "./add.mjs";
add(1,2);
上面的代码其实是会报错的,报错的文件是index.js,export default {...}这种写法是没有不会报错的,只是不规范。那为啥index.js中解构的形式导出会报错呢,我们先来看看报的什么错误
import { add } from ‘./add.mjs‘;
^^^
SyntaxError: The requested module ‘./add.mjs‘ does not provide an export named ‘add‘
看报错信息说没有请求的模块中export没有提供add。既然这样,我们就直接给请求到的add模块赋一个值,然后我们打印出来看看究竟是一个什么东西,add模块的代码不变,index.js修改后的代码如下
// index.js
import util from "./add.mjs";
cosnole.log(util);
运行之后我们可以看到控制台输出
> [lzm]% node index.mjs
> { add: [Function: add] }
我们可以看到是一个拥有add函数的对象,按理说应该可以结构赋值才对呀。其实从上面的报错能看出来,import的解构会自动匹配export,如果没有则会报错。
可以再思考一个问题,在node环境下可以使用es module吗?
答案是可以的,以上例子都是在node环境下运行的。现在node已经支持es module规范了,参考官网的解释
esm_enabling
最本质的区别是模块依赖解析的时机不同
运行时和编译时
所谓运行时即代码已经解析成机器可以识别的形态,代码可以直接运行的阶段。而编译时即我们的js代码解析成机器可以识别的形态的过程。
cjs是在运行时才确定引入, 然后执行这个模块, 相当于是调用一个函数, 返回一个对象.
mjs是语言层面的, 导入导出是声明式的代码集合. 声明式的意思就是说, 直接利用关键字声明说我要导入/导出一个模块啦, 而不是粗鄙(节目效果)地将一个对象赋值给一个变量
如何处理模块的循环加载?
CommonJS模块的重要特性是加载时执行,即脚本代码在require的时候,就会全部执行,CommonJS的做法是,一旦出现某个模块被"循环加载",就只输出已经执行的部分,还未执行的部分不会输出。require函数第一次导入时会自动缓存结果,第二次再导入模块时会直接给到结果。
import不会去执行模块,而是只生成一个引用。等到真的需要用到时,再到模块里面去取值
es 模块并没有帮我们解决循环依赖,所以循环依赖问题需要开发者自己解决
原文:https://www.cnblogs.com/xingguozhiming/p/14915305.html