Code Monkey home page Code Monkey logo

blog's Introduction

Hi there, I'm GaoXiang

Now I'm working at HongSong Entrepreneurial team as a web frontend developer.

Blog:link / zhihu:link / bilibili:link /

Languages and Tools:

blog's People

Contributors

gaoxianglyx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

blog's Issues

模块化-AMD规范———— ESL

AMD规范
AMD 适合浏览器环境开发的主要特性有下面几点:

  • 开发时不需要页面上写一大堆 script 引用,一个 require 初始化模块就搞定。不需要每增加一个文件,就需要到 HTML 或者其他地方添加一个 script 标签或文件声明。
  • 开发时不需要依赖额外的环境,如果不是联调或数据模拟,直接 file:// 都能跑。。
  • 方便打包构建,打包构建应该便于进行模块的合并,并且在绝大多数场景不需要对页面进行修改。
  • 能够通过多种构建方案产生多种打包组合,方便从系统加载过程与缓存进行性能优化。特别是规模较大的应用,哪些东西首次加载、哪些东西缓加载、哪些东西需要被拼合、哪些东西经常变更等等,在构建的时候都会被考虑,对系统性能都可能有较大的影响。

AMD define的形式

define(id?, dependencies?, factory);
id - string
dependencies - Array
factory - Function | Object

AMD使用

  • 将模块 ID 交给应用页面决定,便于重构和模块迁移。模块开发者应该适应这点,从模块定义时就决定模块名称的思路中解放出来。这是使用 AMD 的开发者能获得的最大便利
  • 模块划分应尽可能细粒度,细粒度划分模块,有助于更精细地进行模块变更、依赖、按需加载和引用等方面的管理,有利于让系统结构更清晰,让设计上的问题提早暴露,也能从一定程度上避免一些看起来也合理的循环依赖。
  • 在 factory 中使用 require 引用依赖模块,不要写 dependencies 参数,没必要回到头部,也可以避免依赖循环
  • 即用即记载,require 与使用的距离越远,代码的阅读与维护成本越高。
  • 避免无意义的 装载时依赖。
  • 遵守 即用即 require 可以有效避免出现死循环依赖。
  • 模块的资源引用,在 factory 头部声明,如css资源什么的,会比较清晰

AMD初始化

  • AMD 对于下面两种情况,无法保证初始化顺序
    • factory 内部 require 的依赖模块
    • 在 dependencies 中声明但是在 factory 形参列表之外的依赖模块
  • CMD采用用时定义,确实可以保证模块初始化定顺序=声明顺序
  • 其实 requireJS也可以不提前写好依赖(像cmd一样),最主要的是require无法保证完全按顺序加载
  • 对于两种加载的方式,AMD规范并没有明确限制,requireJS提供了前置依赖和用时依赖两种书写方式,不过都是在factory执行前就把依赖给加载并执行;CMD是你requrie某个依赖的模块时候,才开始执行这个依赖模块的factory(Execution must be lazy);
  • esl对于两种情况采用不同的加载方式,融合了require和sea,明确了分别的处理方式,没有限制只有一种初始化方式,所以依然属于amd规范
  • PS:在正式的项目里面,确实考虑得很多,感觉自己现在仅仅是理解这些已经有点疲倦了。怎么让自己快速接受这种**呢?专注得进入这种状态吧

使用ESL

  • esl主要解决requireJS的痛点——体积太大
  • ESL完全解决了依赖循环的问题
  • 性能比requireJS强
  • 对于多次normalize进行缓存

ES6模块解析,对比CommonJS

ES6模块

ES6模块的特点

  1. 总是处于严格模式
  2. 具有顶层 (top-level) 作用域,但又不是全局 (global) 作用域(import命令具有提升效果,不管写在哪一行都会提到模块头部首先执行)
  3. 可以通过 import 关键字从其他模块导入程序绑定 (bindings, 通常就是变量或者函数)
  4. 可以通过 export 关键字导出指定的 bingdings

严格模式(以下会报错)

  • with 语句
  • 函数重复命名的参数
  • 八进制数字直接量 (比如 010)
  • 重复属性名 ( ES5 会报错,ES6 不会)
  • 使用 implements, interface, let, package, private, protected, public, static 和 yield 作为标识符

ES6的模块的静态加载

  • 静态加载:在编译阶段进行加载(预编译)

JS是脚本语言,是边执行边编译的,这里的编译阶段应该是指的执行前的这个编译解释阶段

  • 动态加载:在运行时加载依赖

ES6模块的设计**,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。commonjs和AMD模块,都只能在运行时确定这些东西。

  • 运行时加载: CommonJS/AMD 模块就是对象;即在输入时是先加载整个模块,生成一个对象,然后再从这个对象上面读取方法,这种加载称为“运行时加载”
  • 编译时加载: ES6 模块不是对象,而是通过 export 命令显式指定输出的代码,输入时采用静态命令的形式。即在输入时可以指定加载某个输出值,而不是加载整个模块,这种加载称为“编译时加载

Commonjs和ES6模块的运行机制就像是深复制和浅复制

ES6模块的运行机制与CommonJS不一样,它遇到模块加载命令import时,不会去执行模块,而是只生成一个动态的只读引用。等到真的需要用到时,再到模块里面去取值,ES6模块是动态引用。

  • 在 CommonJS 中,导入(imports)是模块导出值的复制值(同时 require()动作是同步的)。也就是说,在一个模块中一个值和这个值导出被复制后的值不是同一个,两者之间不存在连接
  • 在 ES6 中,导入是对导出值的只读。因此,模块中的值和导出后的值是同一个,存在连接,只是在导入的模块中对这个值是只读的。“只读”说明在导入的模块中不能直接修改被导入的值,如果要修改被导入的值,可以通过调用被导入模块的函数来达到目的。

静态模块结构的优势:

  1. 在打包时消除死代码(dead code)。在项目开发的过程中,我们可以借助 ES6 实现模块化开发;在部署的时候,可以把这些分散的模块集中打包集成(打包减少了网络请求的数量,这点并不时很关键,因为在 HTTP/2 中将会有所改变;打包压缩了代码,减少了代码的体积;在打包过程中,没有用到的代码将会被移除)。
  2. 简洁高效的打包,不存在定制的打包格式(compact bundling, no custom bundle format)。ES6 模块可以被高效地合并,是因为所有的模块都被当作一个单独的作用域(single scope)(通过重命名变量来消除名冲突)。这些得益于 ES6 模块的两个特性:
  • 静态模块结构不存在模块的条件加载(但是仍可以通过把模块放到函数中来实现);
  • 导入对到导出的值只读,这意味着我们无需复制导出的值,而直接访问导出的值。
  1. 更快的导入检索(faster lookup of imports):
  • 在 CommonJS 中,通过复制来导入,同时模块存在动态机制(导出、导入),因而在查找属性的时候更加慢;
  • ES6 模块时静态的,意味着在模块执行之前就已经知道导入的值是什么,可以优化访问。
  1. 变量检查。同样得益于 ES6 的静态模块结构,我们可以在执行前进行导入、导出的变量检查。
  2. 为宏指令做准备(ready for macros)。macros 会是 JavaScript 发展蓝图中的一个 milestone。目前可以通过一些第三方的库来实现宏定义。
  3. 静态类型(static types)定义.
  4. 静态结构为支持其他编译型语言提供了可能。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.