4.前端工程化

本文目录 1.es6的模块管理 与 commonjs 的对比 2.简单介绍下前端模块化规范:amd,cmd,commonjs和es6的module 3.commonjs 和 es6 的 module 哪个支持异步 4.Base64 的原理?编码后比编码前是大了还是小了 5.webpack构建原理与运行的基本流程 6.loader的原理及手些loader的思路 7.loader和plugin的区别 8.babel是什么 9.babel的工作流程 1.es6的模块管理 与 commonjs 的对比 CommonJS 输出是值的拷贝,即原来模块中的值改变不会影响已经加载的该值,ES6静态分析,动态引用,输出的是值的引用,值改变,引用也改变,即原来模块中的值改变则该加载的值也改变。 CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。 CommonJS 加载的是整个模块,即将所有的接口全部加载进来,ES6 可以单独加载其中的某个接口(方法), CommonJS this 指向当前模块,ES6 this 指向undefined 2.简单介绍下前端模块化规范:amd,cmd,commonjs和es6的module AMD AMD是RequireJS在推广过程中对模块定义的规范化产出。 AMD规范则是非同步加载模块,允许指定回调函数。 AMD标准中,定义了下面两个API: require([module], callback) define(id, [depends], callback) 即通过define来定义一个模块,然后使用require来加载一个模块。 并且,require还支持CommonJS的模块导出方式。 CMD CMD是SeaJS在推广过程中对模块定义的规范化产出。 CMD是同步模块定义。 二者的区别是前者是对于依赖的模块提前执行,而后者是延迟执行。 前者推崇依赖前置,而后者推崇依赖就近,即只在需要用到某个模块的时候再require。 CommonJS Nodejs中使用的是这个规范。CommonJS的核心思想就是通过 require 方法来同步加载所要依赖的其他模块,然后通过 exports 或者 module.exports 来导出需要暴露的接口。 ESM 在ES6中,我们可以使用 import 关键字引入模块,通过 exprot 关键字导出模块,功能较之于前几个方案更为强大,也是我们所推崇的,但是由于ES6目前无法在浏览器中执行,所以,我们只能通过babel将不被支持的import编译为当前受到广泛支持的 require。 3.commonjs 和 es6 的 module 哪个支持异步 紧接着问了这个问题,emmm.. 当时差点没缓过来,冷静分析了一波,然后想到我们最近的项目中在做react组件的异步加载,想到了 es10 版本添加了异步 import() 方式去载入一个模块,所以答案毫无疑问是 esm 目前支持异步,其实返回来想想,如果用排除法这个也很简单,因为 commonjs 规范主要是给 node 层用的,node 层对于 module 的加载无非就是文件的读写,所以它根本没有必要去支持异步加载,读写 io 本身就很快~ 4.Base64 的原理?编码后比编码前是大了还是小了 Base64是一种基于用64个可打印字符来表示二进制数据的表示方法。编码后的数据比原始数据略长,为原来的4/3。 5.webpack构建原理与运行的基本流程 Webpack构建运行在node.js环境下,它的配置文件遵循CommonJS规范,webpack.config.js导出一个Object对象(或者导出一个Function,或者导出一个Promise函数,还可以导出一个数组包含多份配置)。Webpack从入口文件开始,识别出源码中的模块化导入语句,递归地找出所有依赖,然后把入口文件和所有依赖打包到一个单独的文件中(即一个chunk),这就是所谓的模块打包。最新版的Webpack,已经支持了E6/CommonJS/AMD等模块化语句。 webpack运行的基本流程分为初始化、编译、输出三个阶段. 初始化: 从配置文件和shell文件读取、合并参数; 加载plugin 实例化compiler 编译: 从entry发出,针对每个module串行调用对应loader翻译文件内容 找到module依赖的module,递归进行编译处理 输出: 把编译后module组合成chunk 把chunk转换成文件,输出到文件系统 构建流程的详细过程: 初始化:从配置文件或是shell读取与合并参数,得到最终参数,实例化插件new Plugin() 开始编译:通过上一步初始化得到的最终参数,初始化一个Compiler对象,加载插件(依次调用插件中的apply方法),通过执行Compiler.run开始编译 确定入口:根据配置中entry找出所有入口文件 编译模块:从entry出发,调用配置的loader,对模块进行转换,同时找出模块依赖的模块(如何找?见下文),依次递归,直到所有依赖模块完成本步骤处理 完成模块编译:这一步已经使用loader对所有模块进行了转换,得到了转换后的新内容以及依赖关系 输出资源: 根据入口与模块之间的依赖关系,组装成一个个chunk代码块,并且生成文件输出列表 输出成功:根据配置中的输出路径和文件名,将文件写入文件系统,完成构建 6.loader的原理及手些loader的思路 loader是 webpack 用于在编译过程中解析各类文件格式,并输出; loader本质上就是一个 node 模块,通过写一个函数来完成自动化的过程; 由此我们就可以在开发模式下,通过解析各类前端无法解析的文件格式,然后将其解析后返回为对象或字符串供前端开发时使用,在 webpack 的编译过程中自动会将我们前端项目中引用的文件格式对应到指定 loader 解析后输出。 比如下面这段webpack.config.js配置 module.exports = { //... module: { rules: [ {webpack.config.js test: /\.txt$/, use: { loader: path.resolve(__dirname, './txt-loader.js'), options: { name: 'YOLO' } } } ] } } 这是一个非常简单的 loader 来解析 txt 文件,它将满足以下功能 读取 txt 文件内容并输出为一个对象,对象内包括文件内容与文件名 读取 webpack loader 选项,将内容中的 [name] 替换为我们选项 name 的值 loader能把源文件翻译成新的结果,一个文件可以链式经过多个loader编译。以处理scss文件为例: sass-loader把scss转成css css-loader找出css中的依赖,压缩资源 style-loader把css转换成脚本加载的JavaScript代码 7.loader和plugin的区别 对于loader,它是一个转换器,将A文件进行编译形成B文件,这里操作的是文件,比如将A.scss转换为A.css,单纯的文件转换过程。 plugin是一个扩展器,它丰富了webpack本身,针对是loader结束后,webpack打包的整个过程,它并不直接操作文件,而是基于事件机制工作,会监听webpack打包过程中的某些节点,执行广泛的任务 8.babel是什么 Babel 是一个 JavaScript 编译器 Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。 9.babel的工作流程 Babel的编译过程和大多数其他语言的编译器相似,可以分为三个阶段: 解析(Parsing):将代码字符串解析成抽象语法树。 转换(Transformation):对抽象语法树进行转换操作。 生成(Code Generation): 根据变换后的抽象语法树再生成代码字符串。

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):