• webpack前言:前端模块系统的演进



    前端开发和其他开发工作的主要区别,首先是前端是基于多语言、多层次的编码和组织工作,其次前端产品的交付是基于浏览器,这些资源是通过增量加载的方式运行到浏览器端,
    如何在开发环境组织好这些碎片化的代码和资源,
    并且保证他们在浏览器端快速、优雅的加载和更新,就需要一个模块化系统,这个理想中的模块化系统是前端工程师多年来一直探索的难题。

    模块系统的演进

    script 标签

    <script src="module1.js"></script>
    <script src="module2.js"></script>
    <script src="module3.js"></script> 

    这是最原始的 JavaScript 文件加载方式,这种原始的加载方式暴露了一些显而易见的弊端:

    • 文件只能按照<script> 的书写顺序进行加载
    • 在大型项目中各种资源难以管理,长期积累的问题导致代码库混乱不堪
    • 全局作用域下容易造成变量冲突

    CommonJS

    该规范的核心思想是允许模块通过 require 方法来同步加载所要依赖的其他模块,然后通过 exports 或 module.exports 来导出需要暴露的接口

    require("module");
    require("../file.js");
    exports.doStuff = function() {};
    module.exports = someValue;

    优点:

    • 服务器端模块便于重用
    • NPM 中已经有将近20万个可以使用模块包
    • 简单并容易使用

    缺点:

    • 同步的模块加载方式不适合在浏览器环境中,同步意味着阻塞加载,浏览器资源是异步加载的
    • 不能非阻塞的并行加载多个模块

    实现:

    AMD

    CommonJS是主要为了JS在后端的表现制定的,他是不适合前端的,于是乎,AMD(异步模块定义)出现了,它就主要为前端JS的表现制定规范。

    AMD(Asynchronous Module Definition)就只有一个接口:define(id?,dependencies?,factory);

    它要在声明模块的时候制定所有的依赖(dep),并且还要当做形参传到factory中,对于依赖的模块提前执行,依赖前置,像这样:

    define(['dep1','dep2'],function(dep1,dep2){...});

    要是没什么依赖,就定义简单的模块,下面这样就可以啦:

     define(function(){
         var exports = {};
         exports.method = function(){...};
         return exports;
     });

    优点:

    • 适合在浏览器环境中异步加载模块
    • 可以并行加载多个模块

    缺点:

    • 提高了开发成本,代码的阅读和书写比较困难,模块定义方式的语义不顺畅

    实现:

    前端模块加载

    前端期望的模块系统
    
    可以兼容多种模块风格,尽量可以利用已有的代码,不仅仅只是 JavaScript 模块化,还有 CSS、图片、字体等资源也需要模块化。

    前端模块要在客户端中执行,所以他们需要增量加载到浏览器中。

    模块的加载和传输,我们首先能想到两种极端的方式,

    一种是每个模块文件都单独请求,另一种是把所有模块打包成一个文件然后只请求一次。

    显而易见,每个模块都发起单独的请求造成了请求次数过多,导致应用启动速度慢;一次请求加载所有模块导致流量浪费、初始化过程慢。这两种方式都不是好的解决方案,它们过于简单粗暴。

    分块传输按需进行懒加载,在实际用到某些模块的时候再增量更新,才是较为合理的模块加载方案。

         要实现模块的按需加载,就需要一个对整个代码库中的模块进行静态分析、编译打包的过程。

    所有资源都是模块

    在上面的分析过程中,我们提到的模块仅仅是指JavaScript模块文件。然而,在前端开发过程中还涉及到样式、图片、字体、HTML 模板等等众多的资源。这些资源还会以各种方言的形式存在,比如 coffeescript、 less、 sass、众多的模板库、多语言系统(i18n)等等。

    如果他们都可以视作模块,并且都可以通过require的方式来加载,将带来优雅的开发体验,比如:

    require("./style.css");
    require("./style.less");
    require("./template.jade");
    require("./image.png");

    静态分析

    在编译的时候,要对整个代码进行静态分析,分析出各个模块的类型和它们依赖关系,然后将不同类型的模块提交给适配的加载器来处理。

    比如一个用 LESS 写的样式模块,可以先用 LESS 加载器将它转成一个CSS 模块,在通过 CSS 模块把他插入到页面的 <style>标签中执行。Webpack 就是在这样的需求中应运而生。

    同时,为了能利用已经存在的各种框架、库和已经写好的文件,我们还需要一个模块加载的兼容策略,来避免重写所有的模块。

    那么接下来,让我们开始 Webpack 的神奇之旅吧。

  • 相关阅读:
    mysql排序.按字段值排序
    spring.jackson.defaultpropertyinclusion无效问题 null 设置json不输出
    shedLock现在一次只执行一个实例的方法+redis实现分布式定时任务
    微信模板消息跳转小程序
    Nacos心跳时间配置及服务快速上下线
    NAVICAT 15自动运行自动导出EXCEL 并自动发送邮件
    You have an error in your SQL syntax; check the man第二次出现这个问题了,语句放mysql里执行没问题.在springboot里执行报错..乜有语法问题.也报语法问题.
    启动nacos报错:No DataSource set
    Mysql将查询结果某个字段以逗号分隔,使用group_concat函数可以实现(配合group by使用)
    Charles 安装及配置,详细步骤
  • 原文地址:https://www.cnblogs.com/chaixiaozhi/p/8535639.html
Copyright © 2020-2023  润新知