/
grunt_config_as_modules.html
253 lines (222 loc) · 8.06 KB
/
grunt_config_as_modules.html
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<title>刘旸 Zation</title>
<meta name="author" content="刘旸">
<meta name="description"
content="经历过各种技术和职位,最终发现前端开发才是我的归宿,现为Kber前端程序员,专注于实践优秀的前端代码架构。同时也关注用户体验以及新兴设计元素。">
<link href="/stylesheets/main.css?1423851139" media="screen" rel="stylesheet" type="text/css" />
<link href="/images/favicon.png?1401972413" rel="icon" type="image/png" />
<!--[if lt IE 9]>
<script src="/javascripts/html5shiv-printshiv.js?1401972413" type="text/javascript"></script>
<![endif]-->
</head>
<body class="detail">
<div class="main-container">
<header class="nav-container">
<div class="search-container">
<div class="search-cancel-icon">✖</div>
<button class="search-cancel">Cancel</button>
<input placeholder="Search for article title or tags" class="search" type="text">
<div class="search-qualifier"></div>
<ul class="search-result">
</ul>
</div>
<ul class="social-links">
<li class="google-plus">
<a target="_blank" href="https://plus.google.com/100624981016590778324?rel=author">
Google
</a>
</li>
<li class="weibo">
<a target="_blank" href="http://weibo.com/zation1">
Weibo
</a>
</li>
<li class="rss">
<a target="_blank" href="/feed.xml">
RSS
</a>
</li>
<li class="facebook">
<a target="_blank" href="http://www.facebook.com/yang.liu.37669">
Facebook
</a>
</li>
<li class="github">
<a target="_blank" href="https://github.com/zation">
Github
</a>
</li>
</ul>
<a href="/" class="logo">刘旸 Zation</a>
<ul class="nav">
<li><a class="blog-link" href="/">Blog</a></li>
<li><a class="about-link" href="/about.html">About</a></li>
<li><a class="resume-link" href="/resume.html">Resume</a></li>
</ul>
</header>
<section class="content">
<article class="article">
<header class="article-title">
<h1>
国内项目天坑记(二)
</h1>
<h2>——Gruntfile的模块化</h2>
</header>
<ul class="extro-info">
<li class="date">
2014. 06. 09
</li>
<li class="tag">
<a href="/tags/grunt.html">Grunt</a>
</li>
<li class="comment">
<a class="ds-thread-count"
data-thread-key="grunt_config_as_modules"
href="#comment"></a>
</li>
</ul>
<div class="article-content">
<p>在大型项目中用过Grunt的都知道,当自动化的配置和task多了一个,一个Gruntfile.js文件可能有好几百行,这样维护非常困难,于是对Gruntfile的模块化势在必行。感谢<a href="http://zhuanlan.zhihu.com/tla42">墨磊</a>同学帮助我们做了模块化!以下内容都是他的实践。</p>
<p>本质上Gruntfile.js就是一个node.js代码文件,所以我们可以很方便的用<a href="http://www.commonjs.org">CommonJS</a>的规范将Gruntfile.js模块化。下面我们首先来看看模块化以后的grunt目录结构:</p>
<pre><code>Gruntfile.js
grunt/
compile/
compass.js
concat.js
uglify.js
...
dev/
jshint.js
connect.js
...
config.js
tasks.js
</code></pre>
<p>这里要提一下grunt模块划分,一般是根据task的不同来划分的。而<a href="http://gulpjs.com/">gulp</a>是根据处理的文件类型的不同来划分的。</p>
<p>Gruntfile.js所做的事情就很简单了,只是加载tasks.js:</p>
<pre><code>'use strict';
module.exports = function (grunt) {
// load tasks
require('./grunt/tasks.js')(grunt);
};
</code></pre>
<p>tasks.js负责加载和注册所有的tasks和config.js:</p>
<pre><code>module.exports = function (grunt) {
require('./config.js')(grunt);
grunt.loadTasks('./grunt/compile');
grunt.loadTasks('./grunt/dev');
grunt.registerTask('some tasks', function () {
//...
});
return grunt;
};
</code></pre>
<p><strong>注意:</strong>这里<code>grunt.loadTasks()</code>方法的路径是相对于Gruntfile.js的。</p>
<p>config.js负责配置项目相关的属性:</p>
<pre><code>module.exports = function (grunt) {
grunt.initConfig({
// configurable paths
server: {
hostname: '0.0.0.0',
hostport: '9000'
},
testServer: {
hostname: 'localhost',
hostport: '9001'
},
yeoman: {
app: 'app',
dist: 'dist',
test: 'test',
tmp: '.tmp'
}
});
return grunt;
};
</code></pre>
<p>compile文件夹下的tasks是在build production package的时候用到的,dev文件夹下的tasks是在开发环境中用到的,这里也可以根据项目的实际情况进行分类。</p>
<p>这里我认为还可以做优化的地方在于:</p>
<ul>
<li>使用.json配置文件代替.js配置文件,并且预先设订好对于不同环境的配置文件,例如:config.json.development, config.json.production, config.json.staging, config.json.test… 不同的环境中就使用不同的配置文件,这样让所有的配置文件都可以做版本管理,而且也更加统一。</li>
<li>使用npm将这些配置代码都打包,放到另一个独立的github repo中,这样可以简化项目结构和代码,同时也利于这些代码在其他项目中的共用。</li>
</ul>
<p>这些优化我已经在新的项目中进行过尝试了,效果挺不错的,后面会写一篇更加详细的文章来进行介绍。</p>
</div>
</article>
<div id="comment">
<div class="ds-thread" data-thread-key="grunt_config_as_modules"></div>
</div>
</section>
</div>
<footer class="page-footer">
<div class="nav-container">
<div class="search-container">
<div class="search-cancel-icon">✖</div>
<button class="search-cancel">Cancel</button>
<input placeholder="Search for article title or tags" class="search" type="text">
<div class="search-qualifier"></div>
<ul class="search-result">
</ul>
</div>
<ul class="social-links">
<li class="google-plus">
<a target="_blank" href="https://plus.google.com/100624981016590778324?rel=author">
Google
</a>
</li>
<li class="weibo">
<a target="_blank" href="http://weibo.com/zation1">
Weibo
</a>
</li>
<li class="rss">
<a target="_blank" href="/feed.xml">
RSS
</a>
</li>
<li class="facebook">
<a target="_blank" href="http://www.facebook.com/yang.liu.37669">
Facebook
</a>
</li>
<li class="github">
<a target="_blank" href="https://github.com/zation">
Github
</a>
</li>
</ul>
<a href="/" class="logo">刘旸 Zation</a>
<ul class="nav">
<li><a class="blog-link" href="/">Blog</a></li>
<li><a class="about-link" href="/about.html">About</a></li>
<li><a class="resume-link" href="/resume.html">Resume</a></li>
</ul>
</div>
</footer>
<script src="/javascripts/main.js?1447233592" type="text/javascript"></script>
<script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-8993667-6', 'zation.me');
ga('require', 'displayfeatures');
ga('send', 'pageview');
</script>
<script type="text/javascript">
var duoshuoQuery = {short_name:"zation"};
(function() {
var ds = document.createElement('script');
ds.type = 'text/javascript';ds.async = true;
ds.src = 'http://static.duoshuo.com/embed.js';
ds.charset = 'UTF-8';
(document.getElementsByTagName('head')[0]
|| document.getElementsByTagName('body')[0]).appendChild(ds);
})();
</script>
</body>
</html>