精华内容
下载资源
问答
  • 前端模块化

    千次阅读 2020-10-29 15:15:04
    所谓模块化,就是指根据功能的不同进行划分,每个功能就是一个模块。最终,一个完整的产品是由各个模块组合而成的。 模块化的特点: 独立性。可以针对一个模块单独进行设计、研发,相对工作量和难度变小。 复用性。...

    前端模块化

    前端模块化是什么

    所谓模块化,就是指根据功能的不同进行划分,每个功能就是一个模块。最终,一个完整的产品是由各个模块组合而成的。
    模块化的特点:

    • 独立性。可以针对一个模块单独进行设计、研发,相对工作量和难度变小。
    • 复用性。一些通用模块(例如登录或注册)可以被重复使用,而不用每次重新开发。
    • 解耦性。模块与模块Z间,付作一永P所l块的工作。
    • 灵活性。通过选择和组合不同的模块,可以快速构建一个新的产品。

    ECMAScript5的模块化

    函数的封装

    函数的定义可以将代码逻辑封装在指定的函数作用域中。可以将函数的封装作为自定义模块化的第一步:

    functien outer(){
    	var v= '卧龙学苑';
        function inner(){
    		return 'this is inner function.';
        }
    }
    

    上述代码示例中,定义了outer()函数,方便在后面的逻辑中进行调用。outer()函数就可以看作是一个模块。

    但是,这样的做法有着明显的缺点,就是污染了全局命名空间。换句话讲,无法在全局作用域再定义一个 outer()函数。

    对象的自定

    为了解决封装函数所带来的问题,可以引入JavaScript对象的概念。就是把所有相关的模块成员封装在一个对象中。

    var outer = {
    	v: '卧龙学苑',
        inner: function () {
    		return 'this is inner function.';
        }
    }
    

    如上述代码示例,使用对象实现的好处:

    • 解决了全局命名空间可能出现的冲突问题。因为所有的模块成员都是作为一个对象的属性或方法存在的。
    • 模块成员之间也存在着某种关系。因为被定义在同一个JavaScript对象中,作为属性或方法存在。而这个对象名成为了所有模块成员对外的一个统一的模块名称。

    自调函数

    看似引人对象概念后,这个模块的解决方案不错,但依旧存在着一些问题。对于这样一个模块(对象),是可以从外部对该模块(对象)的属性或方法进行修改的。这就导致了会产生一些意外的安全问题,而这个问题可以通过自调函数来进行解决。

    var outer = (function () {
    	var v = 'longestory';
        function inner() {
    		return 'this is inner function.';
        }
    })();
    

    最终模块化结构

    如果想要在真实开发中使用模块化概念,代码结构还需要进一步优化。

    var outer = (function () {
    	var v = 'longestory';
        var interface = {
    		getAttr: function () {
                return v;
    		},
    		inner: function () {
    			return 'this is inner function.';
    		}
        }
    	return interface;
    })();
    

    ECMAScript6的模块化

    ECMAScript 2015提供了基于原生的模块化概念。一个ECMAScript 2015的模块就是一个单独的JavaScript 文件,与普通的JavaScript 文件之间仅有两个区别:

    • ECMAScript 2015的模块自动开启严格模式,即使没有写use strict。
    • 可以在模块中使用import和export 命令。

    export命令

    export命令用于将指定的模块内容导出,该命令可以修饰在function、var、let或 const等之前。

    export var v = 100;
    export let = 'this is string.';
    export function fn(){
    	return 'this is function.';
    }
    

    export命令除了上述方式以外,还可以这样编写:

    var v= 100;
    let l = 'this is string.';
    function fn(){
    	return 'this is function.';
    }
    export { v, l, fn }
    

    上述两种写法是等价的。但一般建议使用第二种写法,因为这样更直接,更清晰。

    import命令

    import命令用于导人其他模块所提供的功能,基本语法如下:

    import {...} from modulepath;
    

    根据上述语法结构,可以通过import命令导入其他模块:

    import {v,l,fn} from './temp.js';
    

    值得注意的是,使用import命令导入的名称必须与模块使用export导出的名称一致。
    使用import命令导入其他模块的内容时,默认使用的是模块声明的名称。也可以在导入时,进行重命名。

    import { v as variable } from './temp.is';
    

    前端模块化规范

    模块化开发可以将复杂的Web应用程序拆分成若干个模块,模块之间的相互依赖很低。使得开发结构更为清晰,依赖更为明确。在实际开发中,经常引人第三方的模块,例如 jQuery库等。

    但是,ECMAScript 官方到目前为止并没有为模块化提供一个统一的标准规范,这可能导致每个模块的编写方式不同。

    目前,最为流行的JavaScript模块化规范具有以下几种:

    • CommonJS
    • RequireJS
    • SeaJS

    CommonJS

    2009年,美国程序员Ryan Dahl创造了Nodejs 项目,将JavaScript语言用于服务器端编程。这标志“JavaScript模块化编程”正式诞生。

    Nocejs,的模块系统,就是参照CommonJS规范实现的。在CommonJS 中,有一个全局性方法require(),用于加载模块。

    CommonJS的Modules规范实现了一套简单易用的模块系统,ComnmonJS对模块的定义也十分的简单。主要分为模块定义、模块引用及模块标识三个部分。

    RequireJS

    RequireJS是一个JavaScript模块加载器。它非常适合在浏览器中使用。

    RequireJS是一个基于AMD规范实现的函数,它区别于传统的CommonJS的require 规范。因为它能够异步地加载动态的依赖。

    AMD( Asynchronous Module Definition,译为异步模块定义)是一个在浏览器端模块化开发的规范。模块将被异步加载,模块加载不影响后面语句的运行。所有依赖某些模块的语句均放置在回调函数中。

    AMD是RequiceJS在推广过程中对模块定义的规范化的产出。

    加载RequireJS

    在HTML页面中通过 <script> 元素引人RequireJS,如下示例代码:

    <script src="scripts/reauire.is"></script>
    

    这样加载 JavaScript 文件可能导致HTML页面失去响应。解决办法有两种,一是将
    件的引入代码放置在HTML页面的底部,二是将代码改写成如下方式:

    <script src="scripts/ require.is" defer async="true" ></script>
    

    async属性表示异步加载 JavaScript 文件,避免HTML页面失去响应。但是E浏览器不支持该属性,可以利用defer 属性进行替换。

    主模块的编写

    通过如下方式定义 RequireJJS 的主模块:

    <script data-main="scripts/main.is" src="scripts/require.is" defer async="true" ></script>
    

    data-main属性表示设置当前HTML页面程序的主模块。由于require.js 默认的文件后缀名是 js,所以可以把 main.js简写成main。

    定义模块

    RequireJS使用define()函数来定义一个模块。定义模块的常见形式如下:

    • 键值对方式定义
    • 函数式定义
    • 存在依赖的函数式定义
    define(["./cart", "./inventory"], function (cart, inventory) {
      //return an object to define the "my/shirt" module.
        return {
        `  color: "blue",
    	   size: "large",
           addToCart: function (){
               inventory.decrement(this);
               cart.add(this);`
           }
        } 
    });
    

    加载模块

    RequireJS使用config()函数对模块的加载行为进行自定义。

    require.config({
    	paths: {
    		"jquery": "jquery.min",
    		"underscore": "underscore.min",
            "backbone": "backbone.min"
        }
    });
    

    RequireJS 使用require()函数来加载指定模块。

    require(['jquery', 'underscore', 'backbone'], function ($,_, Backbone) {
    	//some code here
    });
    

    SeaJS

    Sea.js追求简单、自然的代码书写和组织方式,具有以下核心特性:

    • 简单友好的模块定义规范: Seajs 遵循CMD规范,可以像Nodejs一般书写模块代码。

    • 自然直观的代码组织方式:依赖的自动加载、配置的简洁清晰,可以让我们更多地享受编码的乐趣。Seajs 还提供常用插件,非常有助于开发调试和性能优化,并具有丰富的可扩展接口。

    CMD (Common Module Definition,译为通用模块定义)规范明确了模块的基本书写格式和基本交互规则。该规范是在国内发展出来的。

    CMD是 SeaJS在推广过程中对模块定义的规范化的产出。

    加载SeaJS

    在HTML页面中通过 <script> 元素引人 SeaJS,如下示例代码:

    <script src="scripts/sea.is"></script>
    

    这样加载JavaScript 文件可能导致HTML页面失去响应。解决办法有两种,一是将JavaScript文件的引入代码放置在HTML页面的底部,二是将代码改写成如下方式:

    <script src="scripts/sea.is" defer async="true" ></script>
    

    async属性表示异步加载 JavaScript 文件,避免HTML页面失去响应。但是IE浏览器不支持该属性,可以利用defer 属性进行替换。

    加载模块

    SeaJS利用config()方法进行配置:ll seais的简单配置:

    seajs.config({
    	base: "./seajs/",
        paths: {
            module: "module"
        }
        alias: {
    		"hello": "module"
        }
    })
    

    SeaJS利用use()方法加载模块:/加载入口模块

    seajs.use("hello",function(value){
        var h1 = document.createElement("h1");
        h1.textContent = value.hello;
        document.body.appendChild(h1);
    });
    

    定义模块

    SeaJS利用define()方法定义模块:

    // 所有模块都通过define来定义
    define(function (require, exports, module) {
        // 通过require引入依赖
        var $ = require('jquery');
        var Spinning = require('./spinning');
        
        // 通过exports对外提供接口
        exporto.doSomething= ...
        // 或者通过module.exports提供整个接口
        module.exports = ...
    });
    
    展开全文
  • 模块化导入和导出

    2020-03-03 21:38:51
    模块化就是将独立的一个功能封装到一个模块(文件)中,模块和模块之间是相互独立、相互隔离。 模块和模块之间虽然是相互独立的,但一个模块可以通过特定的接口公开自己的内部成员,以便让其它的模块可以使用或者...

    模块化概述

    模块化就是将独立的一个功能封装到一个模块(文件)中,模块和模块之间是相互独立、相互隔离。
    模块和模块之间虽然是相互独立的,但一个模块可以通过特定的接口公开自己的内部成员,以便让其它的模块可以使用或者访问自己的内部成员

    模块化规范

    浏览器端的模块化

    1…AMD(Asynchronous Module Definition,异步模块定义)
    代表产品为:Require.js
    2…CMD(Common Module Definition,通用模块定义)
    代表产品为:Sea.js

    服务器端的模块化

    服务器端的模块化规范是使用 CommonJS 规范:

    • 使用 require 引入其他模块或者包
    • 使用 exports 或者 module.exports 导出模块成员
    • 一个文件就是一个模块,都拥有独立的作用域

    ES6模块化

    ES6模块化规范中定义:

    • 每一个 js 文件都是独立的模块
    • 导入模块成员使用 import 关键字
    • 暴露模块成员使用 export 关键字

    默认导出和默认导入

    1.默认导出

    let num = 10;
    let name = '张三;
    
    function show() {
      console.log('1111111111111')
    }
    //属性名和属性值一样,可以只写一个
    export default {
      num,
      name,
      show
    }
    

    2.默认导入

    import m1 from './test.js'
    

    注意:在一个模块中,只允许使用export default向外默认暴露一次成员,千万不要写多个export default,否则会报错
    另外,如果在一个模块中没有向外暴露成员,其他模块引入该模块时将会得到一个空对象

    按需导入和导出

    1.按需导出

    export let num = 998;
    export let myName = "jack";
    export function fn = function() { 
    					 console.log("fn") 
    				 }
    

    2.按需导入

     import { num,fn as printFn ,myName } from "./test.js"
    

    3.同时导入默认导出的成员以及按需导入的成员

     import test,{ num,fn as printFn ,myName } from "./test.js"
    

    注意:一个模块中既可以按需导入也可以默认导入,一个模块中既可以按需导出也可以默认导出

    直接导入并执行代码

     import "./test2.js";
    

    test2.js

    for (let i = 0; i < 3; i++) {
      console.log(i)
    }
    
    

    上面的知识简单的总结,另外具体的可以参考这篇

    传送门

    展开全文
  • Android 开发:由模块化到组件化(一)

    万次阅读 多人点赞 2016-12-15 01:43:15
    当你看到这的时候,想必心理一阵恶寒:模块化?组件化?到底是什么鬼?有啥区别. 有这种感觉才是对的,模块化和组件化本质思想是一样的,都是"大化小",两者的目的都是为了重用和解耦,只是叫法不一样.如果非要说区别,那么...

    Android SDK一文中,我们谈到模块化和组件化,现在我们来聊聊组件化开发背后的哪些事.最早是在广告SDK中应用组件化,但是同样适用于普通应用开发

    以下高能,请做好心理准备,看不懂请发私信来交流.本文不推荐新手阅读,如果你刚接触Android开发不久,请立刻放弃阅读本文.


    模块化和组件化

    模块化

    组件化不是个新概念,其在各行各业都一直备受重视.至于组件化什么时候在软件工程领域提出已经无从考究了,不过呢可以确认的是组件化最早应用于服务端开发,后来在该思想的指导下,前端开发和移动端开发也产生各自的开发方式.

    在了解组件化之前,先来回顾下模块化的定义

    Modular programming is a software design technique that emphasizes separating the functionality of a program into independent, interchangeable modules, such that each contains everything necessary to execute only one aspect of the desired functionality.

    简单来说,模块化就是将一个程序按照其功能做拆分,分成相互独立的模块,以便于每个模块只包含与其功能相关的内容。模块我们相对熟悉,比如登录功能可以是一个模块,搜索功能可以是一个模块,汽车的发送机也可是一个模块.

    组件化

    现在来看看”组件化开发”,这里我们看一下其定义:

    Component-based software engineering (CBSE), also known as component-based development (CBD), is a branch of software engineering that emphasizes the separation of concerns in respect of the wide-ranging functionality available throughout a given software system. It is a reuse-based approach to defining, implementing and composing loosely coupled independent components into systems. This practice aims to bring about an equally wide-ranging degree of benefits in both the short-term and the long-term for the software itself and for organizations that sponsor such software.

    通俗点就是:组件化就是基于可重用的目的,将一个大的软件系统按照分离关注点的形式,拆分成多个独立的组件,已较少耦合。

    咋样一看还是非常抽象,说了这么多好像还是不明白.什么是组件呢?组件可以是模块、web资源,软件包,比如汽车的发动机是一个模块,也是一个组件,再或者前端中的一个日历控件是一个模块,也一个组件.

    模块化 vs 组件化

    当你看到这的时候,想必心理一阵恶寒:模块化?组件化?到底是什么鬼?有啥区别.
    有这种感觉才是对的,模块化和组件化本质思想是一样的,都是”大化小”,两者的目的都是为了重用和解耦,只是叫法不一样.如果非要说区别,那么可以认为模块化粒度更小,更侧重于重用,而组件化粒度稍大于模块,更侧重于业务解耦.

    组件化优缺点

    组件化开发的好处是显而易见:系统级的控制力度细化到组件级的控制力度,一个复杂系统的构建最后就是组件集成的结果.每个组件都有自己独立的版本,可以独立的编译,测试,打包和部署

    产品组件化后能够实现完整意义上的按需求进行产品配置和销售,用户可以选择使用那些组件,组件之间可以灵活的组建.

    配置管理,开发,测试,打包,发布完全控制到组建层面,并带来很多好处.比如一个组件小版本进行升级,如果对外提供的接口没有发生任何变化,其他组件完全不需要再进行测试.

    但是组件化的实施对开发人员和团队管理者提出了更高水平的要求.相对传统方式,在项目的管理和组织上难度加大,要求开发人员对业务有更深层次上的理解.


    进军Android 项目

    为什么要在Android中实行组件化开发

    为什么要在Android中实行组件化开发呢,其根本原因在于业务的增长提高了项目的复杂性,为了更好的适应团队开发,提高开发效率,实行组件化乃大势所趋.

    为了更好的帮助大家理解上面这句话,我将从最早的Android 项目开发方式说起.

    简单开发模型

    所谓的简单开发模型是最基础的开发方式,工程中没有所谓的模块,没有所谓的规划,常见于初学者学习阶段或者是个人学习过程所写的demo,其结构大概如下:
    这里写图片描述

    不难发现,往往是在一个界面中存在着大量的业务逻辑,而业务逻辑中充斥着各种各种网络请求,数据操作等行为,整个项目中没有所谓的模块的概念,项目组成的基本单位不是模块,而是方法级的.

    关于这种开发模型没什么需要介绍的,我们早期都经历过,现在除了很少非常古老的项目以及初学者练手之作,已经很少见到.

    单工程开发模型

    该种开发模型已经有了明确的模块划分,并且通过逻辑上的分层呈现出较好结构,该模型最为我们所熟悉,通常用于早期产品的快速开发,团队规模较小的情况下.该种开发模型结构如下:
    这里写图片描述

    随着产品的迭代,业务越来越复杂,随之带来的是项目结构复杂度的极度增加,此时我们面临着几个问题:

    1. 实际业务变化非常快,但是工程之前的业务模块耦合度太高,牵一发而动全身.
    2. 对工程所做的任何修改都必须要编译整个工程
    3. 功能测试和系统测试每次都要进行.
    4. 团队协同开发存在较多的冲突.不得不花费更多的时间去沟通和协调,并且在开发过程中,任何一位成员没办法专注于自己的功能点,影响开发效率.
    5. 不能灵活的对工程进行配置和组装.比如今天产品经理说加上这个功能,明天又说去掉,后天在加上.

    在面临这些问题的前提下,我们重新来思考组件化,看看它是否能解决我们在Android 项目开发中所遇到的难题.

    主工程多组件开发模型

    借助组件化这一思想,我们在”单工程”模型的基础上,将业务层中的各业务抽取出来,封装成相应的业务组件,将基础库中各部分抽取出来,封装成基础组件,而主工程是一个可运行的app,作为各组件的入口(主工程也被称之为壳程序).这些组件或以jar的形式呈现,或以aar的形式呈现.主工程通过依赖的方式使用组件所提供的功能.

    这里写图片描述

    (需要注意这是理想状态下的结构图,实际项目中,业务组件之间会产生通信,也会产生依赖,关于这一点,我们在下文会谈)

    不论是jar还是aar,本质上都是Library,他们不能脱离主工程而单独的运行.当团队中成员共同参与项目的开发时,每个成员的开发设备中必须至少同时具备主工程和各自负责组件,不难看出通过对项目实行组件化,每个成员可以专注自己所负责的业务,并不影响其他业务,同时借助稳定的基础组件,可以极大减少代码缺陷,因而整个团队可以以并行开发的方式高效的推进开发进度.

    不但如此,组件化可以灵活的让我们进行产品组装,要做的无非就是根据需求配置相应的组件,最后生产出我们想要的产品.这有点像玩积木,通过不同摆放,我们就能得到自己想要的形状.

    对测试同学而言,能有效的减少测试的时间:原有的业务不需要再次进行功能测试,可以专注于发生变化的业务的测试,以及最终的集成测试即可.

    到现在为止,我们已经有效解决了”单工程开发模型”中一些问题,对于大部分团队来说这种已经可以了,但是该模型仍然存在一些可以改进的点:每次修改依赖包,就需要重新编译生成lib或者aar.比如说小颜同学接手了一个项目有40多个组件,在最后集成所有组件的时候,小颜同学发现其中某组件存在问题,为了定位和修改该组件中的问题,小颜同学不断这调试该组件.由于在该模型下,组件不能脱离主工程,那么意味着,每次修改后,小颜同学都要在漫长的编译过程中等待.更糟糕的是,现在离上线只有5小时了,每次编译10分钟,为改这个bug,编译了20次,恩….什么也不用干了,可以提交离职报告了

    如何解决这种每次修改组件都要连同主工程一起编译的问题?下面我们来看主工程多子工程开发模型是如何解决该问题的.

    主工程多子工程开发模型

    该种开发模型在”主工程多组件”开发模型的基础上做了改进,其结构图如下:

    这里写图片描述

    不难发现,该种开发模型在结构上和”主工程多组件”并无不同,唯一的区别在于:所有业务组件不再是mouble而是作为一个子工程,基础组件可以使moudle,也可以是子工程,该子工程和主工程不同:Debug模式下下作为app,可以单独的开发,运行,调试;Release模式下作为Library,被主工程所依赖,向主工程提供服务.

    在该种模型下,当小颜同学发现某个业务组件存在缺陷,会如何做呢?比如是基础组件2出现问题,由于在Debug模式下,基础组件2作为app可以独立运行的,因此可以很容易地对该模块进行单独修改,调试.最后修改完后只需要重新编译一次整个项目即可.

    不难发现该种开发模型有效的减少了全编译的次数,减少编译耗时的同时,方便开发者进行开发调试.

    对测试同学来说,功能测试可以提前,并且能够及时的参与到开发环节中,将风险降到最低.

    到现在,我们在理论层次上讲明了采用组件化开发给我们带来的便利,空口无凭是没有说服力的,在下面的一小节中,我们来谈谈如何组件化在Android中的实施过程.

    组件化过程中遇到的问题

    组件划分

    组件化首要做的事情就是划分组件.如何划分并没有一个确切的标准,我建议早期实施组件化的时候,可以以一种”较粗”的粒度来进行,这样左右的好处在于后期随着对业务的理解进行再次细分,而不会有太大的成本.当然,我建议划分组件这一工作有团队架构人员和业务人员协商定制.

    子工程工作方式切换

    在”主工程多子工程模型”中,我们提到子工程在Debug模式下做为单独的Application运行,在Release模式下作为Library运行,如何去动态修改子工程的运行模式呢?我们都知道采用Gradle构建的工程中,用apply plugin: 'com.android.application'来标识该为Application,而apply plugin: 'com.android.library'标志位Library.因此,我们可以在编译的是同通过判断构建环境中的参数来修改子工程的工作方式,在子工程的gradle脚本头部加入以下脚本片段:

    if (isDebug.toBoolean()) {
        apply plugin: 'com.android.application'
    } else {
        apply plugin: 'com.android.library'
    }
    

    除此之外,子工程中在不同的运行方式下,其AndroidMainifest.xml也是不相同的,需要为其分别提供自己AndroidManifest.xml文件:在子工程src目录下(其他位置创建)创建两个目录,用来存放不同的AndroidManifest.xml,比如这里我创建了debug和release目录
    这里写图片描述
    接下来同样需要在该子工程的gradle构建脚本中根据构建方式制定:

    android {
        sourceSets {
            main {
                if(isDebug.toBoolean()) {
                    manifest.srcFile 'src/debug/AndroidManifest.xml'
                } else {
                    manifest.srcFile 'src/release/AndroidManifest.xml'
                }
            }
        }
    }
    

    组件通信与组件依赖

    在”主工程多组件”这种理想模型下业务组件是不存在相互通信和依赖的,但现实却是相反的,如下图:
    这里写图片描述

    这里,业务组件1和业务组件3同时向业务组件2提供服务,即业务组件2需要同时依赖业务组件3和业务组件1.

    现在我们再来看一种更糟糕的情况:
    这里写图片描述

    由此看来,在业务复杂的情况下,组件与组件之间的相互依赖会带来两个问题:

    • 重复依赖:比如可能存在业务组件3依赖业务组件1,而业务组件2又依赖业务组件3和业务组件1,此时就导致了业务组件1被重复依赖.
    • 子系统通信方式不能依靠传统的显示意图.在该种模型下,使用显示意图将导致组件高度耦合.比如业务组件2依赖业务组件1,并通过显示意图的方式进行通信,一旦业务组件1不再使用,那么业务组件2中使用现实意图的地方会出现错误,这显然与我们组件化的目的背道而驰.

    解决组件通信

    先来解决业务组件通信问题.当年看到上面那张复杂的组件通信图时,我们不难想到操作系统引入总线机制来解决设备挂载问题,同样,借用总线的概念我们在工程添加”组件总线”,用于不同组件间的通信,此时结构如下:
    这里写图片描述

    所有挂载到组件总线上的业务组件,都可以实现双向通信.而通信协议和HTTP通信协议类似,即基于URL的方式进行.至于实现的方式一种可以基于系统提供的隐式意图的方式,另一种则是完全自行实现组件总线.这篇文章不打算在此不做详细说明了.

    解决重复依赖

    对于采用aar方式输出的Library而言,在构建项目时,gradle会为我们保留最新版本的aar,换言之,如果以aar的方式向主工程提供提供依赖不会存在重复依赖的问题.而如果是直接以project形式提供依赖,则在打包过程中会出现重复的代码.解决project重复依赖问题目前有两种做法:1.对于纯代码工程的库或jar包而言,只在最终项目中执行compile,其他情况采用provider方式;2.在编译时检测依赖的包,已经依赖的不再依赖

    资源id冲突

    在合并多个组件到主工程中时,可能会出现资源引用冲突,
    最简单的方式是通过实现约定资源前缀名(resourcePrefix)来避免,需要在组件的gradle脚本中配置:

    andorid{
        ...
    
        buildTypes{
            ...
        }
    
        resourcePrefix "moudle_prefix"
    
    }
    

    一旦配置resourcePrefix,所有的资源必须以该前缀名开头.比如上面配置了前缀名为moudle_prefix,那么所有的资源名都要加上该前缀,如:mouble_prefix_btn_save.

    组件上下文(Context)

    最后需要注意在Debug模式下和Release模式下,所需要的Context是否是你所希望的,以避免产生强转异常.


    结束语

    最早接触组件化这个概念是在从事广告SDK工作中,最近陆续续的做了一些总结,因此有了这篇关于”组件化开发”的文章.另外,组件化开发不是银弹,并不能完全解决当前业务复杂的情况,在进行项目实施和改进之前,一定要多加考量.

    敬请期待第二篇,我们将在第二篇内介绍如何对项目实施组件化.

    展开全文
  • 目录ES6 前端模块化前言1、前端开发领域发展到目前阶段零件化组件化模块化2、组件化与模块化的关系3、组件化与模块化的特点一、前端模块化是什么二、ES5的模块化1、函数的封装2、对象的封装3、自调函数的封装三、ES6...

    ES6 前端模块化

    前言

    1、前端开发领域发展到目前阶段

    零件化

    最终呈现给用户是一个完整的产品

    • 降低生成成本 - 多人协作
    • 降低使用成本 - 各个零件之间是低耦合的

    组件化

    将一个完整的产品划分成各个组件

    • 目前,前端开发更多是指HTML页面和CSS样式

    模块化

    将一个完整的产品划分成各个模块

    • 目前,前端开发中更多是指JavaScript逻辑

    2、组件化与模块化的关系

    1. 将一个完整产品,划分成若干组件
    2. 将每一个组件划分成若干模块

    3、组件化与模块化的特点

    1. 是低耦合的

      软件开发的统一原则

    2. 是热插拔的

      需要时使用,不需要时去掉

    一、前端模块化是什么

    所谓模块化,就是指根据功能的不同进行划分,每个功能就是一个模块。最终,一个完整的产品是由各个模块组合而成的。

    模块化的特点:

    • 独立性

      可以针对一个模块单独进行设计、研发,相对工作量和难度变小。

    • 复用性

      一些通用模块(例如登录或注册)可以被重复使用,而不用每次重新开发。

    • 解耦性

      模块与模块之间,将相互影响降到最低,使得更换、升级或添加某个模块,不影响其他模块的工作。

    • 灵活性

      通过选择和组合不同的模块,可以快速构建一个 新的产品。

    二、ES5的模块化

    ECMAScript 5 中存在全局作用域和函数作用域

    不存在模块化概念

    要想在ECMAScript中使用,是要自定义的

    1、函数的封装

    // 问题: 污染全局命名空间
    function fn1() {}
    //这两函数没联系是独立的 -- 低耦合
    function fn2() {}
    

    2、对象的封装

    /*
    在JavaScript对象中:
    问题:	在全局作用域中可以随意修改指定对象的属性值
    */
    var obj1{}
    var obj2{}
    

    3、自调函数的封装

    /*
    通过自调函数解决函数和对象的问题
    问题: 在全局作用域中无法访问和使用自调函数内部的函数或对象
    解决:
        在浏览器环境中运行,添加到window对象中
        将局部的return出去,从而开放给全局
    */
    var global = (function () {
        function fn1() { }
        function fn2() { }
        return {
            fn1: fn1,
            fn2:fn2
        }
    })()
    

    三、ES6的模块化

    ECMAScript 2015提供了基于原生的模块化概念。一个ECMAScript 2015的模块就是一个单独的JavaScript文件,与普通的JavaScript文件之间仅有两个区别:

    • ECMAScript 2015的模块自动开启严格模式,即使没有写use strict
    • 可以在模块中使用importexport命令。

    export命令

    导出

    import命令

    import {...} from modulepath

    导入

    import {v as v1} from modulepath

    四、前端模块化规范

    ​ 模块化开发可以将复杂的Web应用程序拆分成若干个模块,模块之间的相互依赖很低。使得开发结构更为清晰,依赖更为明确。在实际开发中,经常引入第三方的模块,例如jQuery库等。
    ​ 但是,ECMAScript官方到目前为止并没有为模块化提供一个统一的标准规范,这可能导致每个模块的编写方式不同。

    目前,最为流行的、JavaScript模块化规范具有以下几种:

    • CommonJS
    • RequireJS
    • SeaJS

    CommonJS

    2009年,美国程序员Ryan Dahl创造了Node.js 项目,将JavaScript语言用于服务器端编程。
    这标志“JavaScript模块化编程”正式诞生。
    Nodejs.的模块系统,就是参照CommonJS规范实现的。在CommonJS中,有个全局性方法require(),用于加载模块。
    Common. JS的Modules规范实现了一套简单易用的模块系统,CommonJS对模块的定义也十分的简单。主要分为模块定义、模块引用及模块标识三个部分。

    RequireJS

    RequireJS是一个JavaScript模块加载器。它非常适合在浏览器中使用。
    RequireJS是一个基于AMD规范实现的函数,它区别于传统的CommonJS的require规范。因为它能够异步地加载动态的依赖。
    AMD ( Asynchronous Module Definition,译为异步模块定义)是一个在浏览器端模块化开发的规范。模块将被异步加载,模块加载不影响后面语句的运行。所有依赖某些模块的语句均放置在回调函数中。
    AMD是Require. JS在推广过程中对模块定义的规范化的产出。

    SeaJS

    Seajs追求简单、自然的代码书写和组织方式,具有以下核心特性:

    • 简单友好的模块定义规范: Seajs 遵循CMD规范,可以像Node;js - -般书写模块代码。
    • 自然直观的代码组织方式:依赖的自动加载、配置的简洁清晰,可以让我们更多地享受编码的乐趣。

    Seajs还提供常用插件,非常有助于开发调试和性能优化,并具有丰富的可扩展接口。
    CMD ( Common Module Definition,译为通用模块定义)规范明确了模块的基本书写格式和基本交互规则。该规范是在国内发展出来的。
    CMD是SeaJS在推广过程中对模块定义的规范化的产出。

    五、RequireJS

    HTML

    <!-- 
    引入requirejs文件  -  影响HTML页面加载速度
    解决:为script元素设置async属性 - 表示异步加载JavaScript文件
    问题:IE浏览器不支持该属性
    为script元素设置defer属性 - 表示IE浏览器的异步加载
    为当前HTML页面引入主模块文件
    为script元素设置data-main属性 - 表示指定加载主模块
    -->
    <script data-main="../script/index.js" async="true" defer src="../script/require.js"></script>
    

    index.js

    /*
        作为RequireJS的主模块
        - 使用require.config()函数对模块加载进行自定义
            require.config({
                paths: {
                    模块名称:模块路径
                }
            })
        - 使用require()函数加载指定的模块
            require(names,)
    */
    require.config({
        paths: {
            'hello':'./module'
        }
    })
    
    require(['hello'], function (value) {
        var h1 = document.createElement('h1')
        h1.textContent = value
        document.body.appendChild(h1)
    })
    

    module.js

    /*
        作为RequireJS的模块文件
        define()函数进行定义
    */
    define(function () {
        return 'Hello RequireJS'
    })
    

    需要引入第三方requirejs文件

    六、SeaJS

    seajs.config() 方法 - 用于配置价值模块
    seajs.config({
    	base:设置加载模块的基础路径
    	paths:设置加载模块的路径
    	alias:设置加载模块的别名
    })
    
    作为SeaJS的模块文件
    	define(function(require,exports,module){}函数定义)
    	require:用于导入其他模块
    	exports:用于导出当前模块
    		导出的是对象类型 - 所有内容都是对象形式
    	module:module.exports - 用于导出当前模块
    
    seajs.use()方法用于加载指定模块
    seajs.use(names,callback)
    	names:加载模块的名称
    	callback:回调
    		function(value){}
    			value:表示导出的对象
    

    需要引入第三方seajs文件

    展开全文
  • CSS模块化基本思想

    千次阅读 2016-03-14 17:48:30
    模块化的基本概念1.什么是模块模块化是指解决一个复杂问题时自顶向下逐层把系统划分成若干模块的过程。 模块化用来分割,组织和打包软件。每个模块完成一个特定的子功能,所有的模块按某种方式组装起来,成为一个...
  • 闲话不多说,下面开始扯正题,最近有个同事问我“模块化、组件化,插件化还有热更新他们之间有什么关系和区别?“ 概述 随着产品的业务不断的增加,我们的APP中代码就会越来越多,这时侯为了方便我们多个成员之间...
  • 模块化加载的实现

    千次阅读 2016-08-15 18:08:53
    浅谈模块化加载的实现原理 A-A+ 前端博客•2015-03-04•前端开发•AMD | CMD | JavaScript | RequireJS | SeaJS•1913View0 文章目录 一、模块化加载的技术原理 1. 数据模
  • 组件化开发和模块化开发概念辨析

    万次阅读 多人点赞 2018-01-29 00:57:06
    组件化开发和模块化开发概念辨析 网上有许多讲组件化开发、模块化开发的文章,但大家一般都是将这两个概念混为一谈的,并没有加以区分。而且实际上许多人对于组件、模块的区别也不甚明了,甚至于许多博客文章专门...
  • iOS应用组件化/模块化探究

    千次阅读 2019-01-09 14:48:35
    组件是近几年流行起的概念,它是当代码扩张到一定程度时,所采取的一种代码组织架构策略。淘宝、蘑菇街等大厂也在近几年陆续完成了其代码组件的过程。 提到组件,给人的感觉似乎很高大上,很神秘的感觉。但是...
  • css模块化

    千次阅读 2019-06-14 11:09:46
    设计原则 a、可复用能继承要完整 b、周期性迭代 ...但是翻其他地方,这种看上去长得很相似,功能点小,其他地方又找不出有用这种样式的,就不能叫做可复用,所以不要拆除出来。 而单看字体,左黑右红,这...
  • 模块化开发

    千次阅读 2011-04-09 17:02:00
    版本:2011年8月 原文地址: http://blog.csdn.net/gltop/article/details/6312109   作者:GLTOP ... ...本文我们将讨论一下模块化开发。这里提到了两个关键词:模块化和开发。模块化是本文将要讨
  • 模块化与解耦

    千次阅读 2016-02-26 15:18:46
    本文主要讲述了在iOS开发过程中,模块化工程架构的一种组织方式,本文主要讲述基于cocoapods来做模块化的方案,详细讲述了iOS开发怎么进行模块划分的内容,主要会在以下方面做阐述: 为什么要做模块化模块设计...
  • 模块化开发概述 一提到模块化,也许我们首先想到的是做项目的时候进行模块设计,按照功能划分不同的模块,最后通过模块的选择和组合组成最终的产品;那把模块化的思想放到前端页面,js上来是不是也适用?当然,而且...
  • 模块化开发的好处

    千次阅读 2019-07-18 09:03:27
    我们要进行模块化开发呢? 模块化开发的好处主要有这么几点: 1.使用模块化开发能解决文件之间的依赖关系。 当你引入很多个JS文件的时候,很有可能会不清楚这些JS文件之间的依赖关系,从而导致加载顺序出错。使用...
  • 模块化开发详细介绍及详细用法

    千次阅读 2018-05-25 23:53:19
    vue的三个特点:Ø MvvmØ 组件化Ø 模块化 模块化是指文件的组织,管理,使用的方式 。 代码的开发阶段:把一个大的文件,拆分成几个小文件,它们之间相互引用,依赖。代码发布之后:把这些小文件打包成一个大...
  • 同时我们也接入了Route,解决了activity间的跳转耦合,其实Route能够真正发挥它强大作用的是组件化、模块化项目中。以上这些工作我们都为后面业务的剥离打下了良好的基础。 2、 抢单、订单等各种业务柔和在主工程...
  • java9模块化初探

    千次阅读 2017-10-29 04:29:03
    众所周知,java 9的最大特性是引入了模块化系统jigsaw。那么为什么java要引入模块化系统?会对我们今后的开发产生什么影响,该如何正确的使用模块化系统。本文将对这些问题进行一些简单探讨。 开发一个大型应用,...
  • 前端中的模块化

    千次阅读 2019-02-09 10:51:57
    当我们要完成一个应用的时候,会根据对应的功能划分为许多不同的模块,就像一个论坛,有发帖的模块,评论的模块,js 中的模块也正是如此,一...通过直白的描述,我们可以知道,模块化的好处就是,抽离代码,重复使用...
  • css模块化及CSS Modules使用详解

    万次阅读 2016-11-17 09:46:48
    什么是css模块化?为了理解css模块化思想,我们首先了解下,什么是模块化,在百度百科上的解释是,在系统的结构中,模块是可组合、分解和更换的单元。模块化是一种处理复杂系统分解成为更好的可管理模块的方式。它...
  • 模块化的javaScript开发

    千次阅读 2012-12-01 20:31:43
    如今模块化的 JavaScript 的开发越来越火热,无论是模块加载器还是优秀的 JavaScript 模块,都是层出不穷。既然这么火,肯定是有存在的理由,肯定是解决了某些实际问题。很多没接触过模块化 JavaScript 开发者...
  • 程序为什么要模块化

    千次阅读 2008-12-18 09:35:00
    程序为什么要模块化,这是我这次进公司时,帮同事调程序时发自内心的一个感触,看到同事代码时,给我感觉第一:函数内代码太长,居然达400行。第二:代码太长导致变量命名不规范第三功能复杂第四可读性不好,看了好久...
  • 前端模块化开发的价值

    千次阅读 2016-08-09 11:41:38
    本文将从实际项目中遇到的问题出发,讲述模块化能解决哪些问题,以及如何使用 Sea.js 进行前端的模块化开发。 恼人的命名冲突 我们从一个简单的习惯出发。我做项目时,常常会将一些通用的、底层的功能抽象出来...
  • Android--开发:由模块化到组件化

    千次阅读 2017-04-17 18:16:34
    在Android SDK一文中,我们谈到模块化和组件化,现在我们来聊聊组件化开发背后的哪些事.最早是在广告SDK中应用组件化,但是同样适用于普通应用开发 以下高能,请做好心理准备,看不懂请发私信来交流.本文不推荐新手...
  • Android模块化组件化方案分享(2)

    千次阅读 2019-02-24 23:49:51
    组件的整合 统一不同业务组件的buildTypes 上一篇Android模块化组件化方案分享(1) 在前面 上篇文章笔者分享的组件化主要是项目内组件化,毕竟在一个项目中,组件间也是有一定的耦合性。例如跳转不用Arouter依然...
  • 软件工程 3:模块化设计

    千次阅读 2020-03-21 17:05:41
    文章目录软件工程 3面向过程:模块化设计模块设计原则:高内聚、低耦合函数设计:不知道如何下手怎么办错误处理:每个函数都有错误处理模块的编译和链接面向对象:万事万物皆对象类:一组相似事物的统称对象:一个...
  • 总是感觉自己的程序不够完美,移植性不够好,功能也不好扩展,每次完程序最怕的就是客户要改功能。 如果程序架构的不好,一改会影响到很多功能,哪怕原来是灯每秒闪1次,改成每秒闪3次这种看起来很简单的功能...
  • 1. 什么是前端工程 自有前端工程师这个称谓以来,前端的发展可谓是日新月异。相比较已经非常成熟的其他领域,前端虽是后起之秀,但其野蛮生长是其他领域不能比的。虽然前端技术飞快发展,但是前端整体的工程生态...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 161,957
精华内容 64,782
关键字:

产品功能模块化怎么写