Web 前端工程化

    今天说一说前端的工程化,工程化大概包括模块化,组件化,自动化,规范化。在项目的启动之前,我们做好这一系列的工程化,那么项目的最终的质量会很高的。


    首先说一下模块化,模块化就是将一个大小拆分程相互依赖的小文件,在进行统一的拼装和加载,这样的话,方便了多人合作开发,提高了项目代码的可读性、可扩展性。一下我针对 JS 的模块化做了还算是比较详细的介绍吧,其他的大家可以自己去 get 一下

一、JS 模块化


    JavaScript 模块化大概分为以下几个:


    1、无模块化


        对于一些小型的,简单的不太复杂的项目,还算可以。但是如果项目是比较复杂,中大型的项目,那么’无模块化’的缺点就暴露出来了。

        ‘ 污染全局作用域 ’:我们在 index.html 文件的头部或者尾部引用 js 文件的时候,每一个 js (模块)都是暴露在全局的,所以简单的使用,不规范的命名会导致全局变量名有冲突。(ps:今后在开发的时候一定要注意自己的命名,命名要规范化。)

        ‘ 依赖关系混杂,不方便后期维护 ’,我们在引用的 js 文件的时候,有时候会依赖一些其他的 js ,比如需要依赖 jQuery.min.js 文件。那么文件引用顺序就需要注意啦。

    2、CommonJS 规范(CJS规范,适用于服务端)


        一般我们使用该规范的时候,是在服务器端 NodeJS 使用的。该规范把每一个文件都当成了一个模块,在文件内部定义的变量都是属于该模块。不会暴露出去,就不会污染全局变量了。那么 CommonJS 怎么使用的呢:


        通过  require() 加载需要的模块, 这个方法是一个全局的方法,通过 exports / module.exports 导出要暴露的接口。

  举个栗子:


// index.js :     

var a = require(‘./a.js’)

console.log(a.b) // 5

var b = function () {

    return 5

}

// a.js 

// 导出 b

module.export.b = b 



    a.js 就是一个 CommonJS 规范的模块。

    服务端,所有的模块都是放在本地硬盘的,可以同步加载(需要考虑电脑的性能、网速的快慢。)对于浏览器端来说,需要对服务器端发送请求,将文件请求过来。同步加载就不太适用了,只能采用异步加载, 所以浏览器端的 AMD规范 诞生。

3、 AMD规范

    AMD规范是异步加载的,模块的加载都不影响后边的语句执行,所有一来这个模块的语句,都定义在一个回调函数中。

    AMD规范中,定义了两个 API: require([module], callback)   、 define(id, [depends], callback),通过 define 定义一个模块,通过 require 加载一个模块。

    使用 require.js 的时候必须提前加载完所有的模块,然后才可以使用,这样的话,他的一个缺点就暴露出来了。那就是 ‘ 不能按需加载,如果模块过多,加载等待时间会很长 ’。

4、CMD规范


    实现此规范的是 sea.js ,和 require.js 相似,每个 js 文件都是一个模块,它比 AMD 的优点在于,它能够按需加载,不过对于浏览器端来说,有可能会造成小小的延迟。因为你是在需要的时候在进行加载的,所以在等待加载的这个过程,会有一定的延迟的。这一点是不同于 AMD 的。

    说白了就是, AMD 会提前加载模块,CMD 会延迟加载模块。

5、UMD规范

    JavaScript 已经通行前后端了,所以有可能会有 js 模块既在浏览器端运行,也在服务端运行。 UMD就是对 AMD 和 CommonsJS 的整合

6、ES6模块化

    ES6 的模块化是真正的规范,ES6 中我们可以通过 export 导出模块,通过 import 引入模块。由于现在浏览器对模块的支持度问题,所以大部分使用 babelJS 或者 Traceur 将 ES6 代码转化为兼容 ES5 版本的 js代码。


    我还是比较推崇使用 ES6 的语法进行代码的编写,加载模块的时候,每个模块只加载一次,第二次使用的时候,会从内存中直接读取,这样就优化了很多。每一个模块内声明的变量都是局部变量,不会污染全局作用域。一个模块也可以导入多个模块。

    基本使用:

// 以下提供几个常用 导出、导入 方法。

// a.js 文件

    let one = ‘one’;

    let two = ’two’;

    let onefun = function (one) {

        console.log(one, ‘123’);

    }


    let twofun = function (two) {

        console.log(two);

    }

    export{ one, two, onefun, twofun }

// index.js 文件

    import { one, two, onefun, twofun } from ‘./a.js’;


    console.log(one, two, onefun, twofer); // one two one123 two


// 你还可以这么用!!!

// 导出的时候,可以将要导出的接口名字更改

    export{ one as o, two as t }

    import{ o, t } from ‘a.js'

// 你也可以直接在 export 的地方定义导出的函数,或者变量

    export let a = () => console.log(‘123’);  // 这样是将 a() 导出了

// 对于匿名函数或者是不知道名字的变量,且该 js 模块中只有这一个要导出的接口,那么我们可以使用 export default 

    export default ’123123’;

    import default 123123 from ‘./a.js’;

// export 也能默认导出函数

    let fn = () => console.log(‘123’);

    export { fn as default };

// import 导入的时候也可以有好多种导入的语法


    import * as obj from ‘./a.js'

JS 模块化就介绍到这里吧。下边说一下 CSS模块化

二、CSS 模块化

    应该会有很多人想,为什么 CSS 还要有模块化的诞生,一般我们在开发的时候直接命名 类名,id名,然后用 ‘.’ 或者 ‘#’ 命名就行了。也有的人会去使用 SASS、LESS … 等预处理器。虽然 SASS、LESS实现了 CSS 文件的拆分,但是没有解决 CSS 模块化选择器的全局污染问题。


    为了方便多人写作开发,为了避免全局选择器的冲突,我们可以使用一些现有的 CSS命名风格。比如说: BEM风格(我就使用这种风格)、Bootstrap风格、Semantic UI 风格、NEC风格等等

    引用张鑫旭的一句话:精简高效的CSS命名的关键字有“分离”,“统一前缀”,方法为“面向属性的命名”,准则为“无层级、无标签”。

三、资源模块化

我认为最好的体现就是 Webpack 了。不过也有 gulp 、grunt 等等。不过还是 Webpack 比较强大啊,依赖关系单一化、资源处理集成化、项目结构清晰化。关于 Webpack 更多的知识,直接看官网吧。(https://doc.webpack-china.org/中文官网)

四、组件化

    组件化的框架目前还是比较流行的,像 React 、Vue 、Angular2 。这些框架都是目前大部分公司都在使用的框架。那么什么是组件化呢,组件化就是包含模板(HTML)+ 样式(CSS)+ 逻辑(JS)功能完备的结构单元。

    我认为,组件化的思想还是比较不错的,这样会让你的项目结构更清晰,同样也易于多人协作开发。在开发的时候,将一些经常用的组件进行封装,这样再次使用到该组件的时候就能够直接引用了。我们除了分装组件以外,还要合理的处理组件之间的关系,比如逻辑上的继承,样式上的扩展,模板上的嵌套和包含等。

五、规范化

    规范化是工程化中的一个重要部分,项目开发初期,规范化制定的好坏,会影响到项目的开发质量。大概包括以下内容:

目录结构的制定

编码规范(ESLint ...)

前后端接口规范

文档规范

组件管理

Git分支管理

Commit描述规范

定期CodeReview

视觉图标规范

...

六、自动化

    自动化构建(gulp、grunt、webpack ...)、自动化部署(shipit-deploy ...)、自动化测试(Karma、Mocha、jasmine ...)

你可能感兴趣的:(Web 前端工程化)