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

【前端工程化】

目录

  • 前端工程户核心技术之模块化
    • 前端模块化的进化过程
    • commonjs规范介绍
      • commonjs规范示例
      • commonjs模块打包
    • amd规范、cmd规范
    • 前端工程化关键技术之npm+webpack原理

前端工程户核心技术之模块化

前端模块化是一种标准,不是实现。commonjs是前端模块化的标准,而nodejs实现了一套commonjs的规范。
什么是前端模块化:将复杂程序根据规范拆分成若干个模块,每个模块间组织是有逻辑的,一个模块包括输入和输出,每个模块内部实现时私有的,对外暴露接口与其他模块通信,而不是直接调用的关系。这其实就是一种典型的面向对象编程思想。一个html页面可以引用的script标签包括:脚本和模块
脚本和模块的区别:请添加图片描述
原来我们所有的业务逻辑代码只能写在index.js里,但用了模块化标准以后,就可以对他进行拆分了,可以把他拆分为一个入口文件entry.js,这个入口文件去引用若干个模块,然后把他们组织起来进行调用,浏览器去调用时,主要访问入口文件,再由入口文件调用其他模块化文件,组装成一个业务逻辑。脚本和模块化最典型的区别就是,通过模块化拆分后,我们可以更清楚的看到整个业务的逻辑,如果只有一个index.js你并不知道源码里面在干什么。

前端模块化的进化过程

请添加图片描述
定义的函数是挂载在window上的,如果有一个文件夹里也定义api函数,会引发全局命名空间冲突
请添加图片描述
请添加图片描述
请添加图片描述

commonjs规范介绍

commonjs是nodejs默认模块化规范,每个文件就是一个模块,有自己的作用域,可以维护自己的私有变量,node中cjs模块加载采用同步加载方式,必须等这个模块加载完了再去执行后面的代码,通过require加载模块,通过exports或者module.exports输出模块。
commonjs规范特点:

  1. 所有代码都运行在模块作用域,没有js脚本概念,写一个js文件就是一个模块,所以不会污染全局作用域。
  2. 模块可以多次加载,第一次加载时会运行模块,模块输出结果会被缓存,再次加载时,会从缓存结果中直接读取模块输出结果。
  3. 模块加载的顺序,按照其在代码中出现的顺序
  4. 模块输出的值是值的拷贝,类似iife方案中的内部变量

commonjs规范示例

每个功能创建一个文件,如api文件:

const handle = require('./handle')
function api(){return {code: 0,data:{a: 1,b: 2,}}
}
module.exports = {api,handle
}

handle.js文件:

function handle(data, key){return data.data[key]
}module.exports = handle;

sum.js文件:

function sum(a, b){return a+b;
}module.exports = sum;

然后在entry.js中引入各文件,执行相关业务逻辑:
请添加图片描述
请添加图片描述
首先,我们需要有一个主模块(即入口文件entry.js),在主模块中,我们会使用require加载模块,require加载模块时会把模块变成module对象,module对象中有一个load方法,通过load方法进行模块加载,在加载过程中,他会在模块的外层包一层,把原来的模块变成自适应函数,我们写的代码(比如写在api.js中的代码)变成函数里面的内容了,他会向自适应函数传入一些变量(require、module、exports、_filename、_dirname),这就是为什么在node里可以直接使用require的原因。使用module.exports输出模块时,最终输出结果会被缓存到module cache map中,这是一个键值对,键是module path+module name,值是module.exports。commonjs输出模块时,module.exports只能输出一个结果

commonjs模块打包

安装browserify:npm install browserify -g
打包命令:browserify module_test/cjs/entry.js -o dist/bundle.js
⚠️当存在多个entry.js模块时,每个entry.js模块都需要单独打包
browserify打包原理:

  1. 本质还是通过自执行函数实现模块化
  2. 将每个模块编号,存入一个对象,每个模块标记依赖模块
  3. 实现了require方法,核心是通过call方法调用模块,并传入require、module、exports方法,通过module存储模块信息,通过exports存储模块输出信息

amd规范、cmd规范

amd规范采用非同步(异步)加载模块,允许指定回调函数。node模块通常位于本地,加载速度快,所以适用于同步加载,但是在浏览器中,如果用同步加载会阻塞模块渲染(整个页面的渲染),所以在浏览器环境下,模块需要请求获取,适用于异步加载,所以诞生了amd规范,用来做异步加载,require.js是amd的一个具体实现库,amd、cmd目前很少使用,因为目前我们主要使用node和浏览器开发,分别使用commonjs和esmoudle。
cmd规范整合了commonjs和amd的优点,模块加载是异步的,cmd专门用于浏览器端,sea.js是cmd规范的一个实现,amd和cmd最大的问题是没有通过语法升级解决模块化,他们定义模块还是通过调用js方法来生成模块,这种方式利于我们快速应用,但是他没有办法对模块化进行规模化的应用,因为他们没有实现标准的语法规范
ESMoudle规范设计理念是希望在编译时就确定模块以来关系及输入输出,commonjs和amd必须在运行时才能确定依赖和输入、输出,ESMoudle通过import加载模块,通过exports输出模块
commonjs和ESMoudle规范的对比:

  1. commonjs模块输出的是值的拷贝,也就是说commonjs模块内部的值你想改是改不了的,但是es6模块输出的是值的引用
    使用es6定义test.js文件:
export let a = 1;
export function plus() {a++;
}

定义entry.js文件:

import {a, plus} from './test.js'
console.log(a);//1
plus();
console.log(a);//2

使用commonjs定义test.js:

let a = 1;
exports.a = a;
exports.plus = function(){a++;
}
// 上述代码等同于:
// module.exports={
//     a:1,// 这个a的值是直接拷贝过来的
//     plus// plus里加的是模块里的a
// }

定义entry.js文件:

const { a, plus} = require(./test.js);
console.log(a);// 1
plus();
console.log(a);// 1

如果想要获取模块里的a,需要使用get方法,在commonjs定义的test.js中定义get方法:

let a = 1;
exports.a = a;
exports.plus = function(){a++;
}
exports.get = function(){return a;
}

在entry.js文件中调用get:

const { a, plus, get} = require(./test.js);
console.log(a);// 1
plus();
console.log(a);// 1
console.log(get());// 2
  1. commonjs模块是运行时加载,es6模块是编译时输出接口,在编译时就能确定导入哪些模块,输出哪些模块
  2. commonjs是单个值导出,es6可以导出多个
  3. commonjs模块为同步加载,es6支持异步加载,导出的是一个promise
    请添加图片描述
  4. commonjs的this是当前模块的输出值,es6的this是undefined
  5. commonjs和es6的语法不同
    请添加图片描述
    script脚本和模块对比:模块具备更高的开发效率,可以将复杂的代码拆分成若干简单的代码,代码可读性强,复用高效,但是模块在加载过程中会损耗性能,因为模块文件很多,会使得加载速度变得更慢,而脚本具有更高的页面性能。模块在浏览器中运行会存在兼容性问题,要特别注意。所以在浏览器中运用模块化存在一些局限性,比如浏览器缺乏模块管理能力,模块分散在各个项目中,模块性能加载慢,无法在大型项目中直接使用,这两个问题是npm(解决模块管理能力问题)和webpack(解决模块加载慢问题)核心解决的问题

前端工程化关键技术之npm+webpack原理

npm实现的初步思路:

  1. 集中管理所有模块,所有模块都上传到仓库(registry)
  2. 模块内创建package.json标注模块的基本信息
  3. 通过nom publish发布模块,上传到仓库(registry)
  4. 通过nom install安装模块,模块安装到node_modules目录

npm解决的核心问题是模块管理问题,比如模块开发好了之后上传到哪里?如何进行快速复用?npm包含cli、模块仓库、官网三大部分。
请添加图片描述
首先,你产生了一个模块module1,需要通过npm init初始化或者说创建一个模块,常见的模块他只会包含package.json,在package.json里面我们通过修改name、version、dependencies确定模块的基本信息,如果这个模块想加载另外一个模块,那你需要通过npm install加载,加载完成后,另外一个模块会被下载到node_modules目录下,另外一个模块也是包含package.json和node_modules目录,这就是npm的规范。当module1开发完了之后,执行npm publish将其上传到npm仓库,仓库包含两部分,一个是公开部分,可以任意使用,但其中又分为普通仓库和组织的仓库;一个是private部分,也就是私有仓库。
npm原理总结:npm init创建模块,npm install安装模块,npm publish发布模块,npm link模块进行本地开发,npm config查看/调整本地配置,npm run调用package.json中的scripts。
npm规范:package.json管理模块信息,node_modules保存依赖
npm的局限:npm只能解决模块的高效管理和获取问题,无法解决页面性能加载问题,模块化发明后,制约其广泛应哟哦那个的因素就是性能问题
webpack实现原理
请添加图片描述
webpack主要是将所有的资源进行打包,打包到一个文件中。在原来的html模式中,如果你要去加载一些js,你需要通过script标签,如果你要去加载css,你需要编写css并做一个资源加载,这样在html中,就需要加载很多资源,如果通过webpack构建,首先会把js分为entry.js,然后在其中调用不同模块文件,这么多的资源如果按照原来的模式我们需要加载很多资源,但是webpack从entry.js开始,分析所有依赖并进行打包,然后将他们合成到一个bundle.js文件中,这样html在加载时就只用加载一个资源了,提高了页面性能
webpack的原理:最初的webpack核心解决的问题就是代码合并和拆分,webpack的核心里面是将资源都视为模块,统一进行打包和处理。webpack提供了loader和plugins完成功能扩展。


http://www.mrgr.cn/news/95695.html

相关文章:

  • (UI自动化测试web端)第二篇:元素定位的方法_name定位
  • 快速部署Samba共享服务器作为k8s后端存储
  • 3. 轴指令(omron 机器自动化控制器)——>MC_SetPosition
  • Python中json和jsonify的使用
  • 2025前端面试题记录
  • RabbitMQ八股文
  • 【解决方法】VMwareWorkstation无法连接到虚拟机。请确保您有权运行该程序、访问该程序使用的所有目录以及访问所有临时文件目录。
  • Ubuntu部署Docker搭建靶场
  • 练习用Jupyter使用selenium【疑问未解决版】
  • 【MySQL】基本查询(表的增删查改+聚合函数)
  • PostgreSQL_数据使用与日数据分享
  • 网络层之IP协议
  • Pytorch中的torch.utils.data.Dataset 类
  • 开发中常用的设计模式 用法及注意事项【面试题】
  • Flink启动任务
  • 常考计算机操作系统面试习题(四)
  • 深圳问顶安全科技有限公司asktopsec是做什么的?
  • 3. 轴指令(omron 机器自动化控制器)——>MC_SetOverride
  • Android Token的原理和本地安全存储
  • Unity Animation的其中一种运用方式