本篇主要介绍webpack的基本原理以及基于webpack搭建纯静态页面型前端项目工程化解决方案的思路。
下篇(还没写完)探讨下对于Node.js作为后端的项目工程化、模块化、前后端共享代码、自动化部署的做法。
关于webpack的更多用法和前端工程的讨论,可以到github https://github.com/chemdemo/chemdemo.github.io/issues/10
关于前端工程
下面是百科关于“软件工程”的名词解释:
软件工程是一门研究用工程化方法构建和维护有效的、实用的和高质量的软件的学科。
其中,工程化是方法,是将软件研发的各个链路串接起来的工具。
对于软件“工程化”,个人以为至少应当有如下特点:
- 有IDE的支持,负责初始化工程、工程结构组织、debug、编译、打包等工作
- 有固定或者约定的工程结构,规定软件所依赖的不同类别的资源的存放路径甚至代码的写法等
- 软件依赖的资源可能来自软件开发者,也有可能是第三方,工程化需要集成对资源的获取、打包、发布、版本管理等能力
- 和其他系统的集成,如CI系统、运维系统、监控系统等
广泛意义上讲,前端也属于软件工程的范畴。
但前端没有Eclipse、Visual Studio等为特定语言量身打造的IDE。因为前端不需要编译,即改即生效,在开发和调试时足够方便,只需要打开个浏览器即可完成,所以前端一般不会扯到“工程”这个概念。
在很长一段时间里,前端很简单,比如下面简单的几行代码就能够成一个可运行前端应用:
1 2 3 4 5 6 7 8 9 10 11 |
<!DOCTYPE html> <html> <head> <title>webapp</title> <link rel="stylesheet" href="app.css"> </head> <body> <h1>app title</h1> <script src="app.js"></script> </body> </html> |
但随着webapp的复杂程度不断在增加,前端也在变得很庞大和复杂,按照传统的开发方式会让前端失控:代码庞大难以维护、性能优化难做、开发成本变高。
感谢Node.js,使得JavaScript这门前端的主力语言突破了浏览器环境的限制可以独立运行在OS之上,这让JavaScript拥有了文件IO、网络IO的能力,前端可以根据需要任意定制研发辅助工具。
一时间出现了以Grunt、Gulp为代表的一批前端构建工具,“前端工程”这个概念逐渐被强调和重视。但是由于前端的复杂性和特殊性,前端工程化一直很难做,构建工具有太多局限性。
诚如 张云龙@fouber 所言:
前端是一种特殊的GUI软件,它有两个特殊性:一是前端由三种编程语言组成,二是前端代码在用户端运行时增量安装。
html、css和js的配合才能保证webapp的运行,增量安装是按需加载的需要。开发完成后输出三种以上不同格式的静态资源,静态资源之间有可能存在互相依赖关系,最终构成一个复杂的资源依赖树(甚至网)。
所以,前端工程,最起码需要解决以下问题:
- 提供开发所需的一整套运行环境,这和IDE作用类似
- 资源管理,包括资源获取、依赖处理、实时更新、按需加载、公共模块管理等
- 打通研发链路的各个环节,debug、mock、proxy、test、build、deploy等
其中,资源管理是前端最需要也是最难做的一个环节。
注:个人以为,与前端工程化对应的另一个重要的领域是前端组件化,前者属于工具,解决研发效率问题,后者属于前端生态,解决代码复用的问题,本篇对于后者不做深入。
在此以开发一个多页面型webapp为例,给出上面所提出的问题的解决方案。
前端开发环境搭建
主要目录结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
- webapp/ # webapp根目录 - src/ # 开发目录 + css/ # css资源目录 + img/ # webapp图片资源目录 - js/ # webapp js&jsx资源目录 - components/ # 标准组件存放目录 - foo/ # 组件foo + css/ # 组件foo的样式 + js/ # 组件foo的逻辑 + tmpl/ # 组件foo的模板 index.js # 组件foo的入口 + bar/ # 组件bar + lib/ # 第三方纯js库 ... # 根据项目需要任意添加的代码目录 + tmpl/ # webapp前端模板资源目录 a.html # webapp入口文件a b.html # webapp入口文件b - assets/ # 编译输出目录,即发布目录 + js/ # 编译输出的js目录 + img/ # 编译输出的图片目录 + css/ # 编译输出的css目录 a.html # 编译输出的入口a b.html # 编译处理后的入口b + mock/ # 假数据目录 app.js # 本地server入口 routes.js # 本地路由配置 webpack.config.js # webpack配置文件 gulpfile.js # gulp任务配置 package.json # 项目配置 README.md # 项目说明 |
这是个经典的前端项目目录结构,项目目结构在一定程度上约定了开发规范。业务开发的同学只需关注src
目录即可,开发时尽可能最小化模块粒度,这是异步加载的需要。assets
是整个工程的产出,无需关注里边的内容是什么,至于怎么打包和解决资源依赖的,往下看。
本地开发环境
我们使用开源web框架搭建一个webserver,便于本地开发和调试,以及灵活地处理前端路由,以koa
为例,主要代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// app.js var http = require('http'); var koa = require('koa'); var serve = require('koa-static'); var app = koa(); var debug = process.env.NODE_ENV !== 'production'; // 开发环境和生产环境对应不同的目录 var viewDir = debug ? 'src' : 'assets'; // 处理静态资源和入口文件 app.use(serve(path.resolve(__dirname, viewDir),ass="crayon-sy">(serve(path.resolve(__dirname, viewDir),s://github.com/chemdemo/chemdemo.github.io/issues/10" target="_blank">https://github.com/chemdemo/chemdemo.github.io/issues/10
关于前端工程下面是百科关于“软件工程”的名词解释:
其中,工程化是方法,是将软件研发的各个链路串接起来的工具。 对于软件“工程化”,个人以为至少应当有如下特点:
广泛意义上讲,前端也属于软件工程的范畴。 但前端没有Eclipse、Visual Studio等为特定语言量身打造的IDE。因为前端不需要编译,即改即生效,在开发和调试时足够方便,只需要打开个浏览器即可完成,所以前端一般不会扯到“工程”这个概念。 在很长一段时间里,前端很简单,比如下面简单的几行代码就能够成一个可运行前端应用:
但随着webapp的复杂程度不断在增加,前端也在变得很庞大和复杂,按照传统的开发方式会让前端失控:代码庞大难以维护、性能优化难做、开发成本变高。 感谢Node.js,使得JavaScript这门前端的主力语言突破了浏览器环境的限制可以独立运行在OS之上,这让JavaScript拥有了文件IO、网络IO的能力,前端可以根据需要任意定制研发辅助工具。 一时间出现了以Grunt、Gulp为代表的一批前端构建工具,“前端工程”这个概念逐渐被强调和重视。但是由于前端的复杂性和特殊性,前端工程化一直很难做,构建工具有太多局限性。 诚如 张云龙@fouber 所言:
html、css和js的配合才能保证webapp的运行,增量安装是按需加载的需要。开发完成后输出三种以上不同格式的静态资源,静态资源之间有可能存在互相依赖关系,最终构成一个复杂的资源依赖树(甚至网)。 所以,前端工程,最起码需要解决以下问题:
其中,资源管理是前端最需要也是最难做的一个环节。 注:个人以为,与前端工程化对应的另一个重要的领域是前端组件化,前者属于工具,解决研发效率问题,后者属于前端生态,解决代码复用的问题,本篇对于后者不做深入。 在此以开发一个多页面型webapp为例,给出上面所提出的问题的解决方案。 前端开发环境搭建主要目录结构
这是个经典的前端项目目录结构,项目目结构在一定程度上约定了开发规范。业务开发的同学只需关注 本地开发环境我们使用开源web框架搭建一个webserver,便于本地开发和调试,以及灵活地处理前端路由,以
|