1.什么是工程化开发

  软件工程的工程化开发概念由来已久,但对于前端开发来说,我们没有像VS或者eclipse这样量身打造的IDE,因为在大多数人眼中,前端代码无需编译,因此只要一个浏览器来运行调试就行了。但是时至今日,互联网特别是移动互联网为前端开发带来了更大的机会,同时前端代码也变得越来越复杂,越来越难以管理,因此前端工程化开发的工作可以说是刻不容缓。

  那么前端工程化开发到底需要解决哪些前端工程师们火烧眉毛的问题呢?个人认为至少包含以下几点:

  1. 专业的IDE支持,完成包括项目初始化,语法提示,项目编译,打包等工作。

  2. 良好的模块化代码管理结构,模块化可以使我们编写的组件或者代码达到高度复用,降低代码间的耦合性;同时可以良好的与第三方组件兼容。

  3. 简单易配置的前端测试环境,完成组件的单元测试,页面的集成测试;同时提供良好的DEBUG环境,可以很好的定位错误的所在以及错误的详细信息。

  4. 静态资源(图片/字体/CSS/JS等)的良好管理方案,一是静态的文件版本问题,二是对于小图标自动转BASE64,减少HTTP请求

  5. 完整的代码版本管理,打包,发布,多环境部署,测试反馈等运维支持

  

  当然,以上只是个人意见。每个公司、每个项目的情况不一样,所需要的条件都会有所不同。

  以上这些需求,在以前基本上都是不敢想象的,这些工具都需要访问文件系统或者网络,很少有比较完整的解决方案。(好了,早期也有类似于Ant这样的Java解决方法,对前端开发人员要求过高而且不是很好用)好在,伟大的NodeJs诞生了,于是乎,基于NodeJs出现了很多优秀框架,像Grunt和 Gulp等。

  好了,今天的主题是webpack!让我们来看下webpack作为后起之秀,是如何对前端工程化进行支持的!

  

   2. 动态生成HTML

  大家注意,这里所说的动态生成HTML,是指我们使用webpack来动态产生我们最终所期望的HTML文件,而不是指在浏览器运行时使用JS生成HTML片段。

  那为什么要动态生成HTML,我自己写不行吗?答案当然是可以的。

  之所以要动态生成,主要是希望webpack在完成前端资源打包以后,自动将打包后的资源路径和版本号写入HTML中,达到自动化的效果。

  大家可以回想一下我们之前的三篇文章中介绍的案例,在那个练手的项目中,我们页面上的script标签是我们自己写的,那么如果我们需要给JS添加上版本号的话,岂不是每次都的去修改?还有CSS,都是内嵌在JS中的,待JS加载后再创建style标签,然后写入css内容。这么做的话,浏览器需要先等待JS加载完成后,才能生成CSS样式,页面上会有一个等待过程,这个过程页面是完全没有样式的。这当然不是我们所想要的。

  我们的目标是:webpack根据指定的模板,插入打包编译后CSS文件路径;插入打包生成的JS的文件路径。并且还需要为二者添加版本号。另外,我们还可以同时将HTML进行压缩,进一步减少文件大小。

  

  3.初始化项目、安装依赖

  我们这里默认大家的开发环境已经安装了npm以及webpack,尚未安装的同学可以自行安装。

  A.新建一个空项目,然后通过   npm  init     对项目进行初始化,按照提示输入项目的基本信息,然后生成package.json文件。这个文件里面会保存我们即将安装的一些npm插件信息,便于二次移植开发。

  B.安装项目所需依赖:

    npm install css-loader jquery@1 style-loader html-webpack-plugin --save-dev  
  npm install extract-text-webpack-plugin --save-dev   
  

  依次为css加载器,jquery,style加载器,HTML生成插件以及文件提取插件。

  最终package.json的依赖声明得到更新:

"devDependencies": {
"css-loader": "^0.23.0",
"extract-text-webpack-plugin": "^0.9.1",
"html-webpack-plugin": "^1.7.0",
"jquery": "^1.11.3",
"style-loader": "^0.13.0",
"webpack": "^1.12.9",
"webpack-dev-server": "^1.14.0"
}

  

  4. 创建目录,添加测试文件

  准备就绪,我们开始创建项目目录:

- webapp
- src #代码开发目录
- css #css目录,按照页面(模块)、通用、第三方三个级别进行组织
+ page
+ common
+ lib
+ img #图片资源
- js #JS脚本,按照page、components进行组织
+ page
+ view #HTML模板
- dist #webpack编译打包输出目录,同样按照css/js/img进行组织
+ css
+ js
+ view
+ node_modules #所使用的nodejs模块
package.json #项目配置
webpack.config.js #webpack配置
README.md #项目说明

  dist目录也可以不创建任何子目录,这里为了方便查看,将js/css/html分开存放。

  然后我们在src目录创建几个测试文件,详细的代码大家可以前往https://github.com/xiaoyunchen/webpack/tree/master/src 查看源码。

  我们先来看下index.js的内容:

1 //引入CSS
2 require("../../css/lib/reset.css");
3 require("../../css/common/global.css");
4 require("../../css/page/index.css");
5
6 document.write('Hello Index Js');

  代码很简单,主要是引入了几个css文件。再看下我们的 /view/index.html 这个模板的内容

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Index主页</title>
<meta name="author" content="https://github.com/xiaoyunchen/webpack"/>
<meta name="date" content="2015-12-3"/>
<meta name="description" content="基于webpack的前端工程化开发解决方案探索"/>
<!--
作者:https://github.com/xiaoyunchen/webpack
时间:2015-12-03
描述:head中无需再引入css以及facicon,webpack将根据入口JS文件的要求自动实现按需加载或者生成style标签
-->
</head>
<body>
<p>Hello,Webpack!!</p>
<!--
作者:chyun532@qq.com
时间:https://github.com/xiaoyunchen/webpack
描述:body中同样无需单独引入JS文件,webpack会根据入口JS文件自动实现按需加载或者生成script标签,还可以生成对应的hash值
-->
</body>
</html>

  这是一个简单的HTML模板,值得一提的是我们在这里并没有引入任何的CSS和JS,我们希望通过webpack打包来自动生成。(这里的模板还支持 Blueimp

  

  5. webpack配置

  最后是我们的重头戏,webpack.config.js,我们将在这里配置一些webpack任务,来完成我们的需求:

 1 var path=require('path');
2 var webpack = require('webpack');
3 var ExtractTextPlugin = require("extract-text-webpack-plugin");
4 var HtmlWebpackPlugin = require('html-webpack-plugin');
5 module.exports={
6 entry:{
7 index:"./src/js/page/index.js",
8 },
9 output:{
10 path: path.join(__dirname,'dist'),
11 publicPath: "/webpack/dist/",
12 filename: "js/[name].js",
13 chunkFilename: "js/[id].chunk.js"
14 },
15 module: {
16 loaders: [ //加载器
17 {test: /\.css$/, loader:ExtractTextPlugin.extract("style", "css") }
18 ]
19 },
20 plugins:[
21 new ExtractTextPlugin("css/[name].css"), //单独使用style标签加载css并设置其路径
22 new HtmlWebpackPlugin({ //根据模板插入css/js等生成最终HTML
23 favicon:'./src/img/favicon.ico', //favicon路径
24 filename:'/view/index.html', //生成的html存放路径,相对于 path
25 template:'./src/view/index.html', //html模板路径
26 inject:true, //允许插件修改哪些内容,包括head与body
27 hash:true, //为静态资源生成hash值
28 minify:{ //压缩HTML文件
29 removeComments:true, //移除HTML中的注释
30 collapseWhitespace:false //删除空白符与换行符
31 }
32 })
33 ]
34 };

  这个配置文件再之前的文章中我们已经讲过很多次了,这里就不在赘述,只对其中几点比较关键的点进行分析:

  17行:css加载器,只是这里改用了文件提取插件,将css提取出来单独作为一个文件进行存储。

  21行:配置提取出来的css文件名以及存放路径

  22行:html-webpack-plugin 这是webpack中生成HTML的插件,里面有详细的配置说明,大家可以前往查看。

    23行:配置favicon,通过webpack引入同时可以生成hash值

    24行:配置最终生成HTML文件存放路径

    25行:我们所使用的模板

    26行:允许webpack修改哪些内容,可选值为head和body,true的话是都可以修改

    27行:为静态资源生成hash值

    28行:压缩最终生成的HTML文件,相关配置参数请前往 html-minifer查看。(这里为了方便后面查看,没有移除HTML中的空白符与换行符。)

  OK,下面我们在项目的根目录下运行 webpack 打包命令完成项目打包:

  

  打包成功后,我们前往/dist/view目录下查看生成的index.html是什么样

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Index主页</title>
<meta name="author" content="https://github.com/xiaoyunchen/webpack">
<meta name="date" content="2015-12-3">
<meta name="description" content="基于webpack的前端工程化开发解决方案探索"> <link rel="shortcut icon" href="/webpack/dist/favicon.ico?69fed78822d5f8d3895c"><link href="/webpack/dist/css/index.css?69fed78822d5f8d3895c" rel="stylesheet"></head>
<body>
<p>Hello,Webpack!!</p> <script src="/webpack/dist/js/index.js?69fed78822d5f8d3895c"></script></body>
</html>

  可以看到生成的文件除了保留原模板中的内容以外,还根据入口文件index.js的定义,自动添加需要引入CSS与JS文件,以及favicon,同时还添加了相应的hash值。

  运行这个文件,可以看到代码正常,引入的文件路径也都OK!

  是的,我们最初想要通过动态生成HTML的目的达到了。

  webpack根据指定的模板,插入打包编译后CSS文件路径;

  插入打包生成的JS的文件路径。并且还需要为二者添加版本号。

  另外,我们还可以同时将HTML进行压缩,进一步减少文件大小。

  今天的分享就到这里。可能大家还有些疑问:按需加载的JS/CSS也会被提取出来吗?下一章我们将继续探索这个问题。

基于webpack的前端工程化开发解决方案探索(一):动态生成HTML(转)的更多相关文章

  1. 基于webpack的前端工程化开发解决方案探索(二):代码分割与图片加载

    今天我们继续来进行webpack工程化开发的探索! 首先来验证上一篇文章   基于webpack的前端工程化开发解决方案探索(一):动态生成HTML  中的遗留问题:webpack将如何处理按需加载的 ...

  2. 基于webpack的前端工程化开发解决方案探索(三):webpack-dev-server

    前两篇中我们使用webpack完成了静态资源(css/js/img)等自动写入HTML模板中,同时还可以为静态资源添加hash版本号,既满足了我们对于静态资源的打包要求,同时又无需开发人员介入打包过程 ...

  3. 阿里云无线&前端团队是如何基于webpack实现前端工程化的

    背景 前端经历了初期的野蛮生长(切图,写简单的特效)——为了兼容浏览器兼容性而出现的各种类库(JQUERY,YUI等——mv*(饱暖思淫欲,代码多了,也就想到怎样组织代码结构,backbone,ang ...

  4. [转]基于gulp和webpack的前端工程化

    本文样例代码 :https://github.com/demohi/learning-gulp 本文主要简单介绍一下基于gulp和webpack的前端工程化. 技术栈 React.js reFlux ...

  5. 【技术博客】基于vue的前端快速开发(工具篇)

    一.Vue教程 vue.js是一套构建用户界面的渐进式框架.vue采用自底向上增量开发的设计.vue的核心库只关心视图层,非常容易学习,非常容易与其它库和已有项目整合.vue完全有能力驱动采用单文件组 ...

  6. 基于 Webpack 4 搭建 Vue 开发环境

    自从工作之后,就已经很久没有写过博客了.时间被分割得比较碎,积累了一段时间的学习成果,才写下了这篇博客. 之前有写过 Webpack4 的文章,但是都比较偏入门,唯一的一篇实战篇 -- 基于Webpa ...

  7. 基于webpack的Vue.js开发环境快速搭建

    1. 安装node node下载地址 2. 安装淘宝 NPM npm 是node.js 的包管理工具. 镜像命令地址 #命令行: npm install -g cnpm 3. 安装vue # 全局安装 ...

  8. 前端下拉框选择和动态生成调用div

    进入到一个项目期中,一边做项目,一边学习其中用到的知识.这些知识都是零碎的,有数据库,有html,有js,还有django.趁周末时间,整理前面遇到过的前端相关的知识点. 下拉框选择 <html ...

  9. 基于 webpack 的 chrome 扩展开发探索

    起 最近利用闲暇时间在进行一款 chrome 扩展 V2EX-HELPER 的开发(如果巧遇 V 友欢迎试用),今天把它彻底改成了用 webpack 打包依赖的模式,不由得感概 webpack 的强大 ...

随机推荐

  1. 三、jQuery--jQuery基础--jQuery基础课程--第2章 jQuery 基础选择器

    1.#id选择器 jquery能使用CSS选择器来操作网页中的标签元素.如果你想要通过一个id号去查找一个元素,就可以使用如下格式的选择器:$("#my_id") 其中#my_id ...

  2. javascript - 浏览器对象

    Navigator对象 弹出窗口 Cookies Browser Objects 参考手册 参考手册描述了每个对象的属性和方法,并提供了在线实例. Window 对象 Navigator 对象 Scr ...

  3. 与你相遇好幸运,Sail.js定义其他主键

    uuid : { type: 'string', unique: true, required: true, primaryKey: true },

  4. javascript 面向对象编程小记

    虽然平常用jquery用的很熟,但是基本都是面向过程的写法.一个事件一个function,很少有面向对象的写法.今天得写一个日期控件,不得不用上面向对象编程. 刚开始我的想法是: var datepi ...

  5. 在Eclipse中自定义类似syso的快捷代码模板

    sysout/syso syserr/ syse 点击菜单栏的“Window”->“Preferences”,打开“Preferences”对话框.在Preferences”对话框中点击“Jav ...

  6. DES加密算法实现

    好久没写博客了,正好趁着实现网络工程与安全的DES算法的功夫,把代码发上来. DES的介绍可见:DES加密 原理不赘述了..实在太多,其实就是一个形式化算法,按部就班的实现就可以,只不过有些繁琐,我写 ...

  7. maven pom.xml示例

    示例说明: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3. ...

  8. 攻城狮在路上(叁)Linux(十二)--- Linux的目录与路径

    一.相对路径与绝对路径: A.绝对路径:由根目录/开始写起的路径,例如 /usr/share/doc B.相对路径:不是由根目录/开始写起的路径. 二.目录的相关操作: 1.cd: 目录切换 cd ~ ...

  9. CI登录验证

    预先加载数据库操作类和Session类 即在autoload.php中,$autoload['libraries'] = array('database', 'session'); a. 注: 使用s ...

  10. JavaScript前端框架的思考

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:现在JavaScript前端框架层出不穷,尤其Angular进入到2.x时候之后,我们 ...