如何使用NPM作为前端自动化构建工具具

npm scripts 是指Npm 对于
package.json文件中
&scripts&属性的处理,通过该属性,npm 可以执行命令。
比如有下面配置:
{ "scripts": { "lint": "eslint ." }, "devDependencies": { "eslint": "^3.1.1" }}
则,使用终端,在项目目录中执行
npm run-script lint来执行
eslint .命令。不过,更常使用的是
npm run-script的简写形式
npm run来执行
&scripts&中的命令,即
npm run lint。
实际上,npm 执行的命令是
./node_modules/.bin/eslint .,原因是:
eslint包会在项目的
node_modules/.bin目录下生成一个
eslint可执行命令,
node_modules/.bin目录专门用来存放依赖包的可执行命令;
npm run时,Npm 会将
node_modules/.bin加到环境变量
内置的 scripts
npm 为几个最常使用的
scripts内置了简写命令:
test:通过
npm test执行;
start:通过
npm start执行;
stop:通过
npm stop执行;
restart:通过
npm restart执行;
pre 和 post hooks
依然以上面的
lintscript 为例,正如名字所示:
prelint:在执行
npm run lint之前执行;
postlint:在执行
npm run lint之后执行;
即执行顺序为:
npm run prelint-&
npm run lint-&
npm run postlint,如果前一个命令执行失败,即退出码(Exit Code)为非 0,则不会继续执行下一个命令。
比如要在执行代码测试之前先执行
lint,则可以通过下面配置实现:
{ "scripts": { "lint": "eslint .", "test": "mocha test/", "pretest": "npm run lint" }}
另外 npm 会在执行一些内置命令时,执行其
post命令:
prepublish:在包发布前执行,可执行测试、构建、修改版本号等任务;
preinstall:会在包被安装前执行;
postinstall:会在包安装完成后执行;
更多内置的
post可以参考
官网文档说明。
package.json 相关变量
package.json文件包含
{ &name&: &foo&, &version&: &1.2.3& },则 npm 在 npm scripts 中添加下面两个环境变量:
npm_package_name
npm_package_version
自定义环境变量
package.json中的
&config&对象自定义一些环境变量,比如:
{ "config": { "port": "8080" }, "scripts": { "start": "node server.js --port ${npm_package_config_port}" }}
npm_lifecycle_event
npm 正在执行哪个 npm script,
npm_lifecycle_event环境变量值就会设为其值,比如
npm start命令时,则其值为
npm run build命令时,其值为
从而可以根据该值判断正在执行的命令,然后就可以做不同的事。比如,
npm start用于生成开发环境版本代码,而
npm run build用于生成生产环境代码,这就可以在执行构建任务时,通过
npm_lifecycle_event来判断。
关于 npm scripts 更多及更详细的使用请参考官方文档:
npm scripts
Grunt vs Gulp vs npm scripts
关于这三者作为构建工具的对比,已经有人说明的很切中要点,也很细致了,流行的两篇文章:
Why we should stop using Grunt & Gulp和
Why I Left Gulp and Grunt for npm Scripts。对于文章中的观点,我也很赞同,在此只简单列下文章作者的观点。
Gulp 与 Grunt 的不足
总得来说就是 Gulp 与 Grunt 引入了一层复杂但是多余的抽象层,用来抽象直接的构建命令,比如
gulp-uglify和
grunt-contrib-uglify用来包装
uglifyjs命令。这层抽象所建立的插件生态带来了很多问题:
额外的抽象,带来了额外的学习成本;
插件依赖作者,无论是插件质量、设计合理性、文档、更新及时性等严重依赖作者自身的水平与投入;
为什么 npm scripts 先前使用的人不多?这可能是因为很多人存在对 npm scripts 的误解:
人们认为 npm scripts 需要熟悉命令行技能;
人们认为 npm scripts 不够强大;
人们认为 Gulp 的流(stream)对于快速构建是必须的;
人们认为 npm scripts 不能跨平台;
而真相是:
npm scripts 并不需要熟悉命令行技能,当然熟悉的话更好;
npm scripts 可以完成绝大多数 Grunt 与 Gulp 完成的任务,实在不行还可以写 NodeJS 代码来完成;
因为 npm scripts 在一个 Shell 环境中执行的,而 Shell 天生支持
几个常见的命令操作符
|是跨平台的,对于一些 Linux/Mac 中的 Shell 命令可以使用
shelljs来实现跨平台;
而 npm scripts 的不足是由于
package.json文件不可以写注释,对于复杂的构建任务,代码可读性很差。这个可以尽量通过贴切的命名,任务细分来减轻。另外就是需要熟悉各构建工具的命令行使用方式。
npm scripts 构建实例
关于如何使用 npm scripts 来完成创建的前端开发当中的构建任务,可以参考
How to Use npm as a Build Tool一文的教程,以及 github 上面的例子
npm-scripts-example。
总得来说,下面常见的构建任务都可以使用 npm scripts 来完成:
CSS 预处理
ES2015+/React 编译
JS 依赖打包
监听文件改动
LiveReload
到现在,我还会回想下,为什么 Grunt 与 Gulp 会大火?我觉得是因为前端中存在相当一部分很少接触命令行的开发者,对于 Linux/Mac 的命令行有点儿恐惧而不愿意学习它,另外看到构建工具命令行复杂的参数也会心生退却。个人认为,npm scripts 学习成本并不比 Grunt/Gulp 高,对于熟悉构建工具命令的人来说就更低了。所以,一个东西火,不代表它就是好的解决方案,只是代表很多人在关注和使用罢了。
最新教程周点击榜
微信扫一扫前端(240)
前端的技术发展真的快,好了,废话不多说,先说说使用browserify及gulp配合构建的例子以及个人认为的缺陷。
后面会将这个项目的构建工具以及demo源代码发出来的。。。但是但是但是,browserify+gulp还是没能解决开发和在客户端部分加载的问题,也没办法打包成为多个文件,然后像seajs那样模块加载—-这个可是很致命的。browserify的出现至少展示了前端工程化的新方向—-预编译,但是还差一点,而我就是要解决相差的那一点甚至为了解决这个问题而要推倒重来—甚至不用browserify。
不过说起来,这个demo和构建工具虽然是半成品,但也可以给大家一些启示,起码我自己在做这个预编译样式和代码的时候逐渐明白了方向。
构建的系统大约分成几部分–针对每一个项目的配置文件,build.js,构建工具以及构建的产物和资源列表。
大约如下:
还有,一个用来演示的构建网站,php+composer的,而mvc的只是个人根据网上的改改而成。
我们还是先来看看演示网站的实际成品吧,看看构建出来的结果产物:
静态资源的构建规则
1、对于成熟的外部类库,譬如,jquery,mement这些,可以指定为静态资源,然后,构建工具会自动计算出这些资源的md5码,然后就会在页面上面构建引用url。
来看看jquery的引用过程:
a、在配置文件build。js这样设定:
b、工具构建后得到的对应的资源表:
c、好了,在页面如何引用:
页面的引用是根据配置文件规定的资源id;来的,事实上,前端构建以后,所有资源都应该用文件列出来,而资源路径都应该要自动构建,所有资源都带有md5甚至样式和脚本和图片名字都包含md5的一个重要考量是,构建出来的文件可以作为本地缓存,以后改改路径就可以了,彻底利用缓存。
而脚本路径引用逻辑是这样的:
class UrlHelper{
private static $res_json;
private static $res_setting_json;
public function __construct()
if(!isset(self::$res_json)){
$_content=file_get_contents(BASE_PATH."/data/resource.json");
self::$res_json = json_decode($_content, true);
$_content=file_get_contents(BASE_PATH."/data/res.setting.json");
self::$res_setting_json = json_decode($_content, true);
public function CssUrl($resID){
$res_mode="dev";
if (self::$res_setting_json["mode"]=="dev"){
$res_mode="dev";
$res_mode="dist";
if(self::$res_json["styles"]&&self::$res_json["styles"][$resID]){
$res_rule=self::$res_json["styles"][$resID];
CONTEXTPATH.$res_rule[$res_mode];
return '&!--css resource named '.$resID.' is not found or mode '.$res_mode.' is not found--&';
public function JsUrl($resID){
$res_mode="dev";
if (self::$res_setting_json["mode"]=="dev"){
$res_mode="dev";
$res_mode="dist";
if(self::$res_json["scripts"]&&self::$res_json["scripts"][$resID]){
$res_rule=self::$res_json["scripts"][$resID];
CONTEXTPATH.$res_rule[$res_mode];
return '&!--js resource named '.$resID.' is not found or mode '.$res_mode.' is not found--&';
public function StaticCssUrl($resID){
$res_mode="dev";
if (self::$res_setting_json["mode"]=="dev"){
$res_mode="dev";
$res_mode="dist";
if(self::$res_json["static"]["styles"]&&self::$res_json["static"]["styles"][$resID]){
$res_rule=self::$res_json["static"]["styles"][$resID];
CONTEXTPATH.$res_rule[$res_mode]."?v=".$res_rule["md5"];
return '&!--css resource named '.$resID.' is not found or mode '.$res_mode.' is not found--&';
public function StaticJsUrl($resID){
$res_mode="dev";
if (self::$res_setting_json["mode"]=="dev"){
$res_mode="dev";
$res_mode="dist";
if(self::$res_json["static"]["scripts"]&&self::$res_json["static"]["scripts"][$resID]){
$res_rule=self::$res_json["static"]["scripts"][$resID];
CONTEXTPATH.$res_rule[$res_mode]."?v=".$res_rule["md5"];
return '&!--js resource named '.$resID.' is not found or mode '.$res_mode.' is not found--&';
public function CssForModule($module,$resID){
$res_mode="dev";
if (self::$res_setting_json["mode"]=="dev"){
$res_mode="dev";
$res_mode="dist";
if(self::$res_json["modules"][$module]&&self::$res_json["modules"][$module]["styles"]&&self::$res_json["modules"][$module]["styles"][$resID]){
$res_rule=self::$res_json["modules"][$module]["styles"][$resID];
CONTEXTPATH.$res_rule[$res_mode];
return '&!--css resource named '.$resID.' is not found or mode '.$res_mode.' is not found--&';
public function JsForModule($module,$resID){
$res_mode="dev";
if (self::$res_setting_json["mode"]=="dev"){
$res_mode="dev";
$res_mode="dist";
if(self::$res_json["modules"][$module]&&self::$res_json["modules"][$module]["scripts"]&&self::$res_json["modules"][$module]["scripts"][$resID]){
$res_rule=self::$res_json["modules"][$module]["scripts"][$resID];
CONTEXTPATH.$res_rule[$res_mode];
return '&!--js resource named '.$resID.' is not found or mode '.$res_mode.' is not found--&';
public function ActionUrlFor($model,$actionName){
$_php_name="/admin.php";
if($model=="admin"){}
$_php_name="/index.php";
return CONTEXTPATH.$_php_name."/".$actionName;
看不懂不要紧,因为这里只是着重说一下相关流程,等下会有demo放出去慢慢尝试的。
d、页面上面的渲染结果:
样式和图片的构建规则
样式和图片的构建,样式支持scss,支持import,同时可以设定多个样式合并在一起,还有就是,构建样式的时候会将图片自动放到产出目录,给图片加上md5特征码,顺便将样式里面对应图片的路径改成产出图片路径。
现在我们来看看一个例子:
a、我们现在有两个样式,叫global.scss,reset.scss需要合并在一起,还有一个样式叫login.scss的,需要构建一下,用于登录页面。
登录的样式:
我们需要这样设定:
构建以后变成了:
资源文件对应部分如下:
好吧。。我将全部内容都贴出来算了,等下再解释:
"styles": {
"dev": "/static/dist/css/all.2b7f3e80f486e8e74e1b7c06fa0f283f.css",
"dist": "/static/dist/css/all.2b7f3e80f486e8e74e1b7c06fa0f283f.min.css",
"md5": "2b7f3e80f486e8e74e1b7c06fa0f283f"
"scripts": {
"index": {
"dev": "/static/dist/js/index.4bec43ad342ba77e520e070fdab275b5.js",
"dist": "/static/dist/js/index.4bec43ad342ba77e520e070fdab275b5.min.js",
"md5": "4bec43ad342ba77e520e070fdab275b5"
"dev": "/static/dist/js/base.f4adca3a53aba2f69b437.js",
"dist": "/static/dist/js/base.f4adca3a53aba2f69b437.min.js",
"md5": "f4adca3a53aba2f69b437"
"static": {
"styles": {},
"scripts": {
"jquery": {
"dev": "/static/lib/jquery-1.8.0.js",
"dist": "/static/lib/jquery-1.8.0.min.js",
"md5": "029e82e640daf"
"seajs": {
"dev": "/static/lib/sea-debug.js",
"dist": "/static/lib/sea.js",
"md5": "1c05fcabbad21"
"ResourceHelper": {
"dev": "/static/helpers/ResourceHelper.js",
"dist": "/static/helpers/ResourceHelper.js",
"md5": "36ee7f820fdc2b043bedc6dbb2ce3f53"
"moment": {
"dev": "/static/lib/moment.js",
"dist": "/static/lib/moment.min.js",
"md5": "0dd576e48c33dff8190711"
"react": {
"dev": "/static/lib/react.js",
"dist": "/static/lib/react.min.js",
"md5": "bcecb0e4ecdc2c5"
"react-dom": {
"dev": "/static/lib/react-dom.js",
"dist": "/static/lib/react-dom.min.js",
"md5": "ee7a8275eedc45c8d34b6"
"dev": "/static/lib/ejs_production.js",
"dist": "/static/lib/ejs_production.js",
"md5": "bf9eac104b924e54632f7c"
"laytpl": {
"dev": "/static/lib/laytpl.js",
"dist": "/static/lib/laytpl.js",
"md5": "ae95df82da180a6cca9911eba78eb635"
"modules": {
"admin": {
"styles": {
"login": {
"dev": "/static/dist/css/login.abae2ec8e7b03bc6127388.css",
"dist": "/static/dist/css/login.abae2ec8e7b03bc6127388.min.css",
"md5": "abae2ec8e7b03bc6127388"
"scripts": {
"login": {
"dev": "/static/dist/js/login.cdbc1ea9b42d494cf1a9ebd5fad975b1.js",
"dist": "/static/dist/js/login.cdbc1ea9b42d494cf1a9ebd5fad975b1.min.js",
"md5": "cdbc1ea9b42d494cf1a9ebd5fad975b1"
可以看到所有拥有资源id的资源都包括在内。
然后引用的页面内容如下:
href="&?php echo CssUrl('all')?&" rel="stylesheet" type="text/css" /&
href="&?php echo CssForModule("admin","login")?&" rel="stylesheet" type="text/css" /&
type="text/javascript" src="&?php echo StaticJsUrl('jquery'); ?&"&&
type="text/javascript" src="&?php echo StaticJsUrl('moment'); ?&"&&
type="text/javascript" src="&?php echo StaticJsUrl('react'); ?&"&&
type="text/javascript" src="&?php echo StaticJsUrl('react-dom'); ?&"&&
type="text/javascript" src="&?php echo StaticJsUrl('ResourceHelper'); ?&"&&
type="text/javascript" src="&?php echo StaticJsUrl('laytpl'); ?&"&&
type="text/javascript" src="&?php echo StaticJsUrl('seajs'); ?&"&&
实际渲染效果如下:
href="/eFace/static/dist/css/all.2b7f3e80f486e8e74e1b7c06fa0f283f.css" rel="stylesheet" type="text/css" /&
href="/eFace/static/dist/css/login.abae2ec8e7b03bc6127388.css" rel="stylesheet" type="text/css" /&
type="text/javascript" src="/eFace/static/lib/jquery-1.8.0.js?v=029e82e640daf"&&
type="text/javascript" src="/eFace/static/lib/moment.js?v=0dd576e48c33dff8190711"&&
type="text/javascript" src="/eFace/static/lib/react.js?v=bcecb0e4ecdc2c5"&&
type="text/javascript" src="/eFace/static/lib/react-dom.js?v=ee7a8275eedc45c8d34b6"&&
type="text/javascript" src="/eFace/static/helpers/ResourceHelper.js?v=36ee7f820fdc2b043bedc6dbb2ce3f53"&&
type="text/javascript" src="/eFace/static/lib/laytpl.js?v=ae95df82da180a6cca9911eba78eb635"&&
type="text/javascript" src="/eFace/static/lib/sea-debug.js?v=1c05fcabbad21"&&
脚本的构建规则
好了,看了前面两个,实际上脚本的构建也差不多。
但缺点在于,browserify生成的脚本实际上只是放到同一个文件夹里面,然后自己定义了一个require,将模块都放在内部的数据里面,没有办法动态加载任何一个这样的脚本然后再加载里面的任意一个模块。
请看看源代码:
(function outer (modules, cache, entry) {
// Save the require from previous bundle to this closure if any
var previousRequire = typeof require == "function" && require
function newRequire(name, jumped){
if(!cache[name]) {
if(!modules[name]) {
// if we cannot find the module within our internal map or
// cache jump to the current global require ie. the last bundle
// that was added to the page.
var currentRequire = typeof require == "function" && require
if (!jumped && currentRequire)
return currentRequire(name, true)
// If there are other bundles on this page the require from the
// previous one is saved to 'previousRequire'. Repeat this as
// many times as there are bundles until the module is found or
// we exhaust the require chain.
if (previousRequire)
return previousRequire(name, true)
var err = new Error('Cannot find module \'' + name + '\'')
err.code = 'MODULE_NOT_FOUND'
var m = cache[name] = {exports:{}}
modules[name][0].call(
m.exports,
function(x) {
var id = modules[name][1][x]
return newRequire(id ? id : x)
m.exports,
return cache[name].exports
for(var i=0
newRequire(entry[i])
// Override the current require with this new one
return newRequire
})({1:[function(require,module,exports){
* Created by hasee on 2016/10/5.
var WebUI = {
showConfirm: function (opts) {
console.log("confirm pls.")
module.exports = WebUI
},{}],2:[function(require,module,exports){
var Child = React.createClass({ displayName: "Child",
render: function () {
return React.createElement("div", null, " The Child ")
module.exports = Child
},{}],3:[function(require,module,exports){
* Created by hasee on 2016/10/5.
//--前端日志记录,以便性能优化。
var Logger = {
log: function (message) {
console.log("run Logger.log")
module.exports = Logger
},{}],4:[function(require,module,exports){
var Child = require('./Child.jsx')
var Parent = React.createClass({ displayName: "Parent",
render: function () {
return React.createElement("div", null, React.createElement("div", null, " Hello World "), React.createElement(Child, null))
module.exports = Parent
},{"./Child.jsx":2}],5:[function(require,module,exports){
* Created by hasee on 2016/10/5.
var Logger = require('./assets/logger')
var WebUI = require('./assets/WebUI.js')
var Parent = require('./assets/Parent.jsx')
var NumberSelector = ""
var app = {
init: function () {
Logger.log("hello")
setTimeout(function () {
WebUI.showConfirm({})
ReactDOM.render(React.createElement(Parent, null), document.getElementById('app'))
//--模板渲染。
this.renderList()
var t2 = NumberSelector
renderList: function () {
var tplStr = ResourceHelper.getTemplateFromBaseDir("&h3&{{ d.title }}&/h3& &p class=\"intro\"&{{ d.intro }}&/p& &ul&
{{# for(var i = 0, len = d.list. i & i++){ }}
&span&{{ d.list[i].name }}&/span&
&span&所在城市:{{ d.list[i].city }}&/span&
{{# } }} &/ul&")
//第三步:渲染模版
var data = {
title: '前端攻城师',
list: [{ name: '贤心', city: '杭州' }, { name: '谢亮', city: '北京' }, { name: '浅浅', city: '杭州' }, { name: 'Dem', city: '北京' }]
$("#log").append(laytpl(tplStr).render(data))
$(function () {
app.init()
},{"./assets/Parent.jsx":4,"./assets/WebUI.js":1,"./assets/logger":3}]},{},[5])
./assets/Parent.jsx
这种形式的require真的丑到爆,当然,browserify可以用将npm install了的模块也打包进去文件里面。。
但是我觉得这个真的是扯谈。。。服务端的代码跟客户端浏览器本来就不一样的,硬要两者合并到时候死都不知道怎么死。
还有一点就是,不支持模块分割。。。有些模块是基本不变的,譬如,我们自己写的ui插件,有些是经常变化的,譬如,业务逻辑。我们需要一个机制可以有模块分割,浏览器加载。seajs当时也做得挺好的。
难道就没有一种像java那样,在文件里面写个package xxx,然后在其他文件上面导入命名空间,譬如,import(‘xxxx’)这样就可以用的机制吗?当然有,下一篇文章就是完成这个的。但是不知道什么时候会写。
资源下载及相关
需要注意的是,构建工具需要npm install一下,然后设定文件里面:
configFile需要换成你自己的项目目录。
下载地址:
b、php项目用的是composer,请自行搭建环境然后安装类库。
用来这么多类库的,还要搭建apache服务器,你懂得。
下载地址:
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1363311次
积分:14531
积分:14531
排名:第722名
原创:260篇
转载:425篇
评论:208条
(1)(8)(8)(8)(3)(2)(11)(2)(5)(6)(1)(4)(25)(21)(12)(12)(16)(6)(22)(33)(20)(31)(10)(4)(5)(19)(10)(4)(14)(16)(10)(24)(8)(63)(19)(25)(22)(44)(13)(7)(15)(15)(22)(14)(41)(11)posts - 21,&
comments - 0,&
trackbacks - 0
工作环境:window下
在一切的最开始,安装node.js (中文站,更新比较慢)(外文站,最新的资料,但是打开可能比较慢)
  这里是一篇知乎的关于node.js是什么的文
  简单的来说,它是JavaScript运行环境。更加深入,无法理解事件:1、如何通过nodejs利用JavaScript写后端语言;2、node的module是什么;3、关于V8引擎;
  任何语言只要有引擎就可以跑起来,这里相当于搭建了一个静态服务器,然后在server.js中写数据的获取,npm install express。这就是一个简单的静态服务器,可以用于数据处理。。
自行理解:
  1、nodejs是一个类似于底层的开发环境,帮助JavaScript语言让计算机理解;
  2、npm是用于管理nodejs的集成安装包;
  3、nodejs有很多模块,例如压缩文件,搭建静态服务器等,这些功能需要npm进行安装。
此文主要内容
  1、安装nodejs。
  2、安装npm,现在nodejs已经将npm集成了起来。
  3、安装cnpm,这是一个淘宝镜像文件,它的功能和npm一样,是在国内搭建的一个服务站,更新会比npm慢,但是可以基本满足开发使用,安装速度会比npm快。
  4、搭建gulp自动构建,用于检测安装包的自动架构而不是自己再一个个去写。
  5、搭建express静态服务器。
一、nodejs和npm的安装
  1.进入nodejs的官网,进行下载。注意:如果已经有安装好的版本,不可以直接安装高版本的,它会报错。可以卸载后再安装,也可以利用vnpm来进行升级。
    安装完成以后进入cmd中进行确认,它会显示安装的版本号。
node --version
npm --version
  2.npm和nodejs现在已经集成在了一起安装好了,,在这里可以看官方文档进行更加详细的学习。
  3.安装cnpm
  ,-g表示进行全局安装
npm install -g cnpm --registry=https://registry.npm.taobao.org
  我们同样可以使用如下来确定是否安装成功和版本号。
cnpm --version
二、安装gulp,对于主要插件进行测试
先进行安装
创建一个文件夹,例如gulptest,使用命令行,我们先要进入这个文件夹中,例如cd gulptest
首先进行全局安装
cnpm install gulp -g
接下来在项目文件下面进行项目开发依赖的安装
cnpm install gulp --save-dev
项目文件下面会自动生成一个package.json文件用于记录项目下面的插件安装,这里我们需要查看一下有没有这行代码,一般情况下,我们对于一个项目先要进行初始化,
npm init 这是为了自动生成package.json文件
"devDependencies": {
"glup": "^1.0.14"
现在来安装用于压缩html,css,js和img的插件
基本规则:cnpm install [gulp-xxxx] --save-dev,就是将插件安装起来,gulp下的插件命名都以gulp开头,插件名与插件名之间以空格隔开,如果你想要进行一次性安装的话
npm install gulp-htmlmin gulp-imagemin imagemin-pngcrush gulp-minify-css gulp-jshint gulp-uglify gulp-concat gulp-rename gulp-notify --save-dev
安装完成以后我们依旧可以进入项目根目录上的package.json文件中查看是否安装完成
安装完成以后要开始编写运行文件了
在根目录下面创建一个js文件,gulpfile.js文件,基础代码是
var gulp = require('gulp');
gulp.task('default', function() {
// 将你的默认的任务代码放在这
在根目录文件下命令行直接输入gulp就会默认运行这个文件中defalut代码
var gulp = require('gulp')
&&&&htmlmin = require('gulp-htmlmin')
&&&&imagemin = require('gulp-imagemin')
&&&&minifycss = require('gulp-minify-css')
&&&&uglify = require('gulp-uglify');
gulp.task('htmlmin',function(){
&&&&gulp.src('./views/**/*.html')
&&&&&&&&.pipe(htmlmin({
&&&&&&&&&&&&removeComments:true
&&&&&&&&}))
&&&&&&&&.pipe(gulp.dest('./dist/views'));
gulp.task('uglify',function(){
&&&&gulp.src('./static/js/**/*.js')
&&&&&&&&.pipe(uglify())
&&&&&&&&.pipe(gulp.dest('./dist/static/js'));
gulp.task('minifycss',function(){
&&&&gulp.src('./static/css/**/*.css')
&&&&&&&&.pipe(minifycss())
&&&&&&&&.pipe(gulp.dest('./dist/static/css'));
gulp.task('imagemin',function(){
&&&&gulp.src('./static/images/**/*.{png,jpg,gif,ico}')
&&&&&&&&.pipe(imagemin())
&&&&&&&&.pipe(gulp.dest('./dist/static/images'));
gulp.task('watch',function(){
&&&&gulp.src('./views/**/*.html',['htmlmin']);
&&&&gulp.src('./static/js/**/*.js',['uglify']);
&&&&gulp.src('./static/css/**/*.html',['minifycss']);
&&&&gulp.src('./static/images/**/*.{png,jpg,gif,ico}',['imagemin']);
gulp.task('default',['htmlmin','uglify','minifycss','imagemin','watch']);
  gulp.task('taskname',fuc);第一个参数时对任务进行命名,这个是可以随便命名的,在合并任务里面进行任务运行的时候添加的是对应的taskname,第二个参数时运行函数。
阅读(...) 评论()

我要回帖

更多关于 知识图谱构建工具 的文章

 

随机推荐