├── components
├── page
│ ├── index.jade
│ ├── index.js
│ ├── index.scss
│ └── index.html
├── sprite
│ ├── sprite.scss
│ ├── icon.png
│ ├── autosprite.scss
│ └── retina.scss
└── project.example.js
├── templates
├── src
│ ├── html
│ │ ├── include.html
│ │ └── master.html
│ ├── tpl
│ │ ├── common
│ │ │ ├── footer.jade
│ │ │ └── header.jade
│ │ └── index
│ │ │ └── list.jade
│ ├── libs
│ │ └── bootstrap
│ │ │ ├── bootstrap.css
│ │ │ └── bootstrap.js
│ ├── js
│ │ ├── common
│ │ │ ├── report.js
│ │ │ └── global.js
│ │ ├── common.js
│ │ └── index.js
│ ├── test-include.html
│ ├── favicon.ico
│ ├── css
│ │ ├── common
│ │ │ ├── _level.scss
│ │ │ ├── _ricons.scss
│ │ │ └── _reset.scss
│ │ └── index.scss
│ ├── img
│ │ ├── common
│ │ │ └── banner.png
│ │ ├── sprite
│ │ │ ├── icons
│ │ │ │ ├── search.png
│ │ │ │ └── webqq.png
│ │ │ ├── level
│ │ │ │ ├── search.png
│ │ │ │ └── webqq.png
│ │ │ └── icons@2x
│ │ │ │ ├── search.png
│ │ │ │ └── webqq.png
│ │ └── static
│ │ │ └── static-img-url.png
│ ├── test-extend.html
│ └── index.html
├── __gitignore
├── userdef.js
├── __editorconfig
├── README.md
├── __jshintrc
├── project.js
├── package.json
├── config.rb
├── livefile.js
└── gulpfile.js
├── .gitignore
├── .npmignore
├── package.json
├── slushfile.js
└── README.md
/components/page/index.jade:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/components/page/index.js:
--------------------------------------------------------------------------------
1 | // require();
2 |
--------------------------------------------------------------------------------
/templates/src/html/include.html:
--------------------------------------------------------------------------------
1 | include content
--------------------------------------------------------------------------------
/templates/src/tpl/common/footer.jade:
--------------------------------------------------------------------------------
1 | this is a footer
--------------------------------------------------------------------------------
/templates/src/libs/bootstrap/bootstrap.css:
--------------------------------------------------------------------------------
1 | body {}
2 |
--------------------------------------------------------------------------------
/templates/src/js/common/report.js:
--------------------------------------------------------------------------------
1 | // frontend report kit
2 |
--------------------------------------------------------------------------------
/components/page/index.scss:
--------------------------------------------------------------------------------
1 | @charset"UTF-8";
2 | @import"common/reset";
3 |
--------------------------------------------------------------------------------
/templates/src/libs/bootstrap/bootstrap.js:
--------------------------------------------------------------------------------
1 | console.log('bootstrap.js');
2 |
--------------------------------------------------------------------------------
/templates/src/tpl/common/header.jade:
--------------------------------------------------------------------------------
1 | p #{title}
2 | this is a pre header
3 |
4 |
--------------------------------------------------------------------------------
/templates/__gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | .sass-cache
3 | /dist
4 | .tmp
5 | /public
6 | .offline
--------------------------------------------------------------------------------
/templates/src/js/common.js:
--------------------------------------------------------------------------------
1 | require('./common/global.js');
2 | require('./common/report.js');
3 |
--------------------------------------------------------------------------------
/templates/src/test-include.html:
--------------------------------------------------------------------------------
1 | conctent here
2 |
3 |
4 |
--------------------------------------------------------------------------------
/components/sprite/sprite.scss:
--------------------------------------------------------------------------------
1 | $<%= spriteName %>-layout:smart;
2 | @import "sprite/<%= spriteName %>/*.png";
3 |
--------------------------------------------------------------------------------
/components/sprite/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rehorn/slush-alloyteam-simple/HEAD/components/sprite/icon.png
--------------------------------------------------------------------------------
/templates/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rehorn/slush-alloyteam-simple/HEAD/templates/src/favicon.ico
--------------------------------------------------------------------------------
/templates/src/css/common/_level.scss:
--------------------------------------------------------------------------------
1 | $level-layout:smart;
2 | @import"sprite/level/*.png";
3 | @include all-level-sprites;
4 |
--------------------------------------------------------------------------------
/templates/src/js/common/global.js:
--------------------------------------------------------------------------------
1 | // keep it if using url md5 rev replacement in javascript
2 | console.log('global is load');
3 |
--------------------------------------------------------------------------------
/templates/src/img/common/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rehorn/slush-alloyteam-simple/HEAD/templates/src/img/common/banner.png
--------------------------------------------------------------------------------
/templates/src/img/sprite/icons/search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rehorn/slush-alloyteam-simple/HEAD/templates/src/img/sprite/icons/search.png
--------------------------------------------------------------------------------
/templates/src/img/sprite/icons/webqq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rehorn/slush-alloyteam-simple/HEAD/templates/src/img/sprite/icons/webqq.png
--------------------------------------------------------------------------------
/templates/src/img/sprite/level/search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rehorn/slush-alloyteam-simple/HEAD/templates/src/img/sprite/level/search.png
--------------------------------------------------------------------------------
/templates/src/img/sprite/level/webqq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rehorn/slush-alloyteam-simple/HEAD/templates/src/img/sprite/level/webqq.png
--------------------------------------------------------------------------------
/templates/src/img/sprite/icons@2x/search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rehorn/slush-alloyteam-simple/HEAD/templates/src/img/sprite/icons@2x/search.png
--------------------------------------------------------------------------------
/templates/src/img/sprite/icons@2x/webqq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rehorn/slush-alloyteam-simple/HEAD/templates/src/img/sprite/icons@2x/webqq.png
--------------------------------------------------------------------------------
/templates/src/img/static/static-img-url.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rehorn/slush-alloyteam-simple/HEAD/templates/src/img/static/static-img-url.png
--------------------------------------------------------------------------------
/templates/userdef.js:
--------------------------------------------------------------------------------
1 | // user custom file
2 | // don't submit to svn/git
3 | module.exports = {
4 | distId: 'R000567',
5 | opUser: 'rehorn'
6 | };
7 |
--------------------------------------------------------------------------------
/components/sprite/autosprite.scss:
--------------------------------------------------------------------------------
1 | $<%= spriteName %>-layout:smart;
2 | @import "sprite/<%= spriteName %>/*.png";
3 | @include all-<%= spriteName %>-sprites;
4 |
--------------------------------------------------------------------------------
/templates/src/html/master.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/templates/src/tpl/index/list.jade:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | include ../common/header.jade
4 | body
5 | h1 #{body}
6 | p Welcome to my super lame site.
7 | include ../common/footer.jade
--------------------------------------------------------------------------------
/templates/__editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = tab
6 | indent_size = 4
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
--------------------------------------------------------------------------------
/templates/src/test-extend.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | my content
6 |
7 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.log
3 | node_modules
4 | build
5 | *.node
6 | coverage
7 | *.orig
8 | .idea
9 | sandbox
10 | test/out-fixtures/*
11 | test/watch-*.txt
12 | templates/node_modules
13 | templates/.sass-cache
14 | templates/dist/*
15 | templates/.tmp
16 | templates/public/*
17 | templates/.offline
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.log
3 | node_modules
4 | build
5 | *.node
6 | coverage
7 | *.orig
8 | .idea
9 | sandbox
10 | test/out-fixtures/*
11 | test/watch-*.txt
12 | templates/node_modules
13 | templates/.sass-cache
14 | templates/dist/*
15 | templates/.tmp
16 | templates/public/*
17 | templates/.offline
--------------------------------------------------------------------------------
/templates/README.md:
--------------------------------------------------------------------------------
1 | Alloyteam Simple Web Apps
2 | ==========================
3 |
4 | alloyteam web 前端项目工程化模板
5 |
6 | ### 安装
7 | 1. 安装 npm 依赖 (或直接下载 node_modules.zip解压)
8 | ```javascript
9 | npm install
10 | ```
11 | 2. 开发
12 | ```javascript
13 | gulp
14 | ```
15 | 3. 编译发布
16 | ```javascript
17 | gulp dist
18 | ```
--------------------------------------------------------------------------------
/templates/src/js/index.js:
--------------------------------------------------------------------------------
1 | require('./common/global.js');
2 |
3 | var list = require('../tpl/index/list.jade');
4 |
5 | var data = {
6 | body: 'this is body',
7 | title: 'hi title'
8 | };
9 | var dom = list(data);
10 | document.write(dom);
11 |
12 | console.log('test!!');
13 | console.log('index loaded');
14 |
--------------------------------------------------------------------------------
/components/page/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | <%= pageName %>
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/templates/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Index Demo Page
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/templates/__jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "camelcase": true,
3 | "curly": true,
4 | "eqeqeq": true,
5 | "forin": true,
6 | "indent": 4,
7 | "latedef": true,
8 | "newcap": true,
9 | "trailing": true,
10 |
11 | "undef": true,
12 | "predef": [ "$" ],
13 |
14 | "boss": true,
15 | "expr": true,
16 | "sub": true,
17 |
18 | "maxerr": 100,
19 | "jquery": true,
20 | "browser": true
21 | }
--------------------------------------------------------------------------------
/templates/src/css/index.scss:
--------------------------------------------------------------------------------
1 | @charset"UTF-8";
2 | @import"common/level";
3 | @import"common/ricons";
4 | @import"common/reset";
5 | body {
6 | border: 1;
7 | }
8 | .hello {
9 | &:before {
10 | @include level-sprite("search");
11 | }
12 | }
13 | .hello-2x {
14 | &:before {
15 | @include icons-sprite-retina("search");
16 | }
17 | }
18 | .banner {
19 | width: 45px;
20 | height: 100px;
21 | background-image: image-url("common/banner.png");
22 | }
23 | .test {
24 | color: red;
25 | }
26 |
--------------------------------------------------------------------------------
/templates/project.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | // 站点相关,项目名
3 | name: '<%= name %>',
4 | // 项目 cdn 根,对应 alloydist 发布系统的 public/cdn/
5 | cdn: '<%= cdn %>',
6 | // 项目 html 根,对应 alloydist 发布系统的 public/webserver/
7 | webServer: '<%= webServer %>',
8 | // 子模块名称
9 | subModule: '<%= subModule %>',
10 | // 是否开启 liveproxy
11 | liveproxy: 1,
12 | // 发布单号,用于命令行发布
13 | distId: '',
14 | // jb 发布映射设置建议,不需改动
15 | distHtmlDir: '<%= distHtmlDir %>', // html映射
16 | distCdnDir: '<%= distCdnDir %>' // cdn映射
17 | };
18 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "slush-alloyteam-simple",
3 | "version": "0.7.0",
4 | "description": "Alloyteam Simple Web Apps generator base on slush & glup",
5 | "keywords": [
6 | "slushgenerator", "gulp", "web", "app", "front-end", "node", "alloyteam", "simple"
7 | ],
8 | "homepage": "https://github.com/rehorn/slush-alloyteam-simple",
9 | "bugs": "https://github.com/rehorn/slush-alloyteam-simple/issues",
10 | "author": "rehornchen@tencent.com",
11 | "repository": {
12 | "type": "git",
13 | "url": "git://github.com/rehorn/slush-alloyteam-simple.git"
14 | },
15 | "main": "slushfile.js",
16 | "files": [
17 | "slushfile.js",
18 | "templates",
19 | "components"
20 | ],
21 | "engines": {
22 | "node": ">= 0.8.0",
23 | "npm": ">=1.0.0"
24 | },
25 | "dependencies": {
26 | "gulp": "^3.8.6",
27 | "gulp-install": "^0.1.8",
28 | "gulp-template": "^0.1.1",
29 | "gulp-util": "^2.2.20",
30 | "gulp-if": "^1.2.2",
31 | "gulp-rename": "^1.2.0",
32 | "inquirer": "^0.5.1"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/components/sprite/retina.scss:
--------------------------------------------------------------------------------
1 | $<%= spriteName %>:sprite-map("sprite/<%= spriteName %>/*.png", $layout:smart);
2 | $<%= spriteName %>-2x:sprite-map("sprite/<%= spriteName %>@2x/*.png", $layout:smart);
3 | //Sprite mixin, works perfectly with standard defines
4 | @mixin <%= spriteName %>-sprite-retina($sprite) {
5 | background-image: sprite-url($<%= spriteName %>);
6 | background-position: sprite-position($<%= spriteName %>, $sprite);
7 | background-repeat: no-repeat;
8 | overflow: hidden;
9 | display: block;
10 | height: image-height(sprite-file($<%= spriteName %>, $sprite));
11 | width: image-width(sprite-file($<%= spriteName %>, $sprite));
12 | @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
13 | background-image: sprite-url($<%= spriteName %>-2x);
14 | background-size: (image-width(sprite-path($<%= spriteName %>-2x)) / 2) (image-height(sprite-path($<%= spriteName %>-2x)) / 2);
15 | background-position: round(nth(sprite-position($<%= spriteName %>-2x, $sprite), 1) / 2) round(nth(sprite-position($<%= spriteName %>-2x, $sprite), 2) / 2);
16 | height: image-height(sprite-file($<%= spriteName %>-2x, $sprite)) / 2;
17 | width: image-width(sprite-file($<%= spriteName %>-2x, $sprite)) / 2;
18 | }
19 | }
--------------------------------------------------------------------------------
/templates/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "alloyteam-simple",
3 | "version": "0.1.1",
4 | "description": "Alloyteam Simple Web Apps - By Slush generator alloyteam-simple",
5 | "keywords": [
6 | "front-end",
7 | "alloyteam",
8 | "web",
9 | "app"
10 | ],
11 | "homepage": "https://github.com/alloyteam",
12 | "repository": {
13 | "type": "git",
14 | "url": "git://github.com/rehorn/slush-alloyteam-simple.git"
15 | },
16 | "author": "alloyteam",
17 | "dependencies": {},
18 | "devDependencies": {
19 | "async": "^2.0.1",
20 | "babel-core": "^6.13.2",
21 | "babel-loader": "^6.2.4",
22 | "babel-preset-es2015": "^6.13.2",
23 | "babel-preset-es2015-loose": "^7.0.0",
24 | "del": "^2.2.1",
25 | "ejs-compiled-loader": "^2.1.1",
26 | "file-loader": "^0.9.0",
27 | "file2-loader": "^0.1.0",
28 | "gulp": "^3.9.1",
29 | "gulp-clean-css": "^2.0.12",
30 | "gulp-compass": "^2.1.0",
31 | "gulp-html-extend": "^1.1.6",
32 | "gulp-htmlrefs": "^0.3.6",
33 | "gulp-if": "^2.0.1",
34 | "gulp-minify-html": "^1.0.6",
35 | "gulp-newer": "^1.2.0",
36 | "gulp-rev": "^7.1.0",
37 | "gulp-savefile": "^0.1.1",
38 | "gulp-uglify": "^2.0.0",
39 | "gulp-zip": "^3.2.0",
40 | "jade": "^1.11.0",
41 | "jade-loader": "^0.8.0",
42 | "liveproxy": "^0.1.4",
43 | "lodash": "^4.14.2",
44 | "request": "^2.74.0",
45 | "run-sequence": "^1.2.2",
46 | "style-loader": "^0.13.1",
47 | "vinyl-paths": "^2.1.0",
48 | "webpack-stream": "^3.2.0"
49 | },
50 | "engines": {
51 | "node": ">=0.10.0",
52 | "npm": ">=1.2.10"
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/templates/config.rb:
--------------------------------------------------------------------------------
1 | # Require any additional compass plugins here.
2 |
3 | # set the css file encoding
4 | Encoding.default_external = "utf-8"
5 |
6 | dist_root = "dist/"
7 | http_images_path = "../img/common"
8 | http_generated_images_path = "../../img"
9 | generated_images_dir = dist_root + "img"
10 |
11 | # To enable relative paths to assets via compass helper functions. Uncomment:
12 | # relative_assets = true
13 |
14 | # To disable debugging comments that display the original location of your selectors. Uncomment:
15 | # line_comments = false
16 |
17 | # cache buster via parameter
18 | # Increment the deploy_version before every release to force cache busting.
19 | # deploy_version = 1
20 | # asset_cache_buster do |http_path, real_path|
21 | # if File.exists?(real_path)
22 | # hash = Digest::MD5.file(real_path.path).hexdigest
23 | # hash.to_s[0, 8]
24 | # else
25 | # "v=#{deploy_version}"
26 | # end
27 | # end
28 |
29 | # cache buster via path md5
30 | asset_cache_buster do |path, real_path|
31 | if File.exists?(real_path)
32 | pathname = Pathname.new(path)
33 | hash = Digest::MD5.file(real_path.path).hexdigest
34 | hash = hash.to_s[0, 8]
35 | new_path = "%s/%s-%s%s" % [http_images_path, pathname.basename(pathname.extname), hash, pathname.extname]
36 |
37 | {:path => new_path, :query => nil}
38 | end
39 | end
40 |
41 | # If you prefer the indented syntax, you might want to regenerate this
42 | # project again passing --syntax sass, or you can uncomment this:
43 | # preferred_syntax = :sass
44 | # and then run:
45 | # sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass
46 |
--------------------------------------------------------------------------------
/templates/livefile.js:
--------------------------------------------------------------------------------
1 | var express = require('liveproxy').express;
2 |
3 | // mocker cgi 路由模拟
4 | // function log(req) {
5 | // console.log('[mocker]: ' + req.url);
6 | // };
7 |
8 | // var router1 = express.Router();
9 | // router1.get('/v1/post/:id', function(req, res, next) {
10 | // log(req);
11 | // res.end('v1 called');
12 | // });
13 |
14 | module.exports = {
15 | // action 上下文目录
16 | cwd: './dist',
17 |
18 | // 外网访问代理
19 | // proxyAgent: 'proxy.tencent.com:8080',
20 |
21 | // 本地文件夹替换配置
22 | handler: [{
23 | match: '<%= webServerResolve %>index.html',
24 | action: './'
25 | }, {
26 | match: '<%= webServerResolve %>',
27 | action: './'
28 | }, {
29 | match: '<%= cdnResolve %>',
30 | action: './'
31 | }],
32 |
33 | // cgi mocker 模拟配置
34 | // mocker: [{
35 | // match: 'cgi.find.qq.com',
36 | // action: router1
37 | // }],
38 |
39 | // host/路由配置
40 | // router: [{
41 | // match: 'find.qq.com/cgi-bin/',
42 | // action: '-'
43 | // }, {
44 | // match: 'find.qq.com/',
45 | // action: '10.12.23.156:8080'
46 | // }],
47 |
48 | // 扩展配置,目前支持 [网络延迟delay], [添加response返回头addResponseHeader]
49 | // extender: [{
50 | // match: 'find.qq.com/cgi-bin/',
51 | // action: {
52 | // func: 'delay',
53 | // args: 5
54 | // }
55 | // }, {
56 | // match: 'find.qq.com/',
57 | // action: {
58 | // func: 'addResponseHeader',
59 | // args: ['powered', 'alloyteam']
60 | // }
61 | // }]
62 | };
63 |
--------------------------------------------------------------------------------
/components/project.example.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | // 站点相关,项目名
3 | name: 'alloyteam-simple-app',
4 | // 项目 cdn 根,对应 alloydist 发布系统的 public/cdn/
5 | cdn: 'http://s.url.cn/qqfind/',
6 | // 项目 html 根,对应 alloydist 发布系统的 public/webserver/
7 | webServer: 'http://find.qq.com/',
8 | // 子模块名称
9 | subMoudle: '/',
10 | // webpack: js 模块化相关
11 | webpack: {
12 | entry: {
13 | index: './src/js/index/index.js'
14 | },
15 | output: {
16 | filename: '[name].js',
17 | },
18 | externals: {
19 | jQuery: "jQuery"
20 | },
21 | module: {
22 | loaders: [{
23 | test: /\.hbs$/,
24 | loader: "handlebars-loader"
25 | }]
26 | }
27 | },
28 | // jb 相关配置
29 | // offline: {
30 | // 'bid': 128, // alloykit bid, 需要修改
31 | // 'publish': true,
32 | // 'compatible': 0,
33 | // 'qversionfrom': 0,
34 | // 'qversionto': 0,
35 | // 'platform': [2, 3],
36 | // 'loadmode': 2,
37 | // 'verifyType': 0,
38 | // 'expire_time': 1577836800000,
39 | // 'cdn': 'defaultCDN',
40 | // 'note': '',
41 | // 'frequency': 1,
42 | // 'gray': true,
43 | // 'uins': []
44 | // },
45 | // 可选,jb 部署单号,用于命令行操作
46 | distId: '',
47 | // 操作用户
48 | opUser: 'alloy-gulp',
49 | // 接口校验 token
50 | token: 'ASdxseRTSXfiGUIxnuRisTU',
51 | // jb 发布映射设置建议,不需改动
52 | distHtmlDir: '/data/sites/find.qq.com/', // html映射
53 | distCdnDir: '/data/sites/cdn.qplus.com/qqfind/' // cdn映射
54 | };
55 |
--------------------------------------------------------------------------------
/templates/src/css/common/_ricons.scss:
--------------------------------------------------------------------------------
1 | /*
2 | * Retina Sprites for Compass
3 | * by: Gaya Kessler
4 | * last update: 03/11/14
5 | *
6 | * Usage:
7 | * 1. create two folders in your image directory (in this case 'icons' and 'icons-2x').
8 | * 2. adjust the foldernames defined below if you use different names.
9 | * 3. create sprite images for pixel ratio 1 screens and put them in the first folder.
10 | * 4. create sprite images for pixel ratio 2 screens and put them in the second folder, use the same filenames.
11 | * 5. use the sprite-image in your Sass/Scss using: '@include use-sprite()'
12 | */
13 |
14 | //first we'll define the folders where the sprites are and their layouts
15 | $icons:sprite-map("sprite/icons/*.png", $layout:smart);
16 | $icons-2x:sprite-map("sprite/icons@2x/*.png", $layout:smart);
17 | //Sprite mixin, works perfectly with standard defines
18 | @mixin icons-sprite-retina($sprite) {
19 | background-image: sprite-url($icons);
20 | background-position: sprite-position($icons, $sprite);
21 | background-repeat: no-repeat;
22 | overflow: hidden;
23 | display: block;
24 | height: image-height(sprite-file($icons, $sprite));
25 | width: image-width(sprite-file($icons, $sprite));
26 | @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
27 | background-image: sprite-url($icons-2x);
28 | background-size: (image-width(sprite-path($icons-2x)) / 2) (image-height(sprite-path($icons-2x)) / 2);
29 | background-position: round(nth(sprite-position($icons-2x, $sprite), 1) / 2) round(nth(sprite-position($icons-2x, $sprite), 2) / 2);
30 | height: image-height(sprite-file($icons-2x, $sprite)) / 2;
31 | width: image-width(sprite-file($icons-2x, $sprite)) / 2;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/templates/src/css/common/_reset.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | * {
4 | margin: 0;
5 | padding: 0;
6 | }
7 |
8 | li {
9 | list-style: none;
10 | }
11 |
12 | input[type=search] {
13 | -webkit-appearance: none;
14 | }
15 |
16 | a {
17 | text-decoration: none;
18 | color: #0079ff;
19 | }
20 |
21 | html {
22 | width: 100%;
23 | background: #f8f8f8;
24 | font-family: "Helvetica Neue", Helvetica, STHeiTi, sans-serif;
25 | min-height: 100%;
26 | display: -webkit-flex;
27 | display: flex;
28 | }
29 | html body {
30 | width: 100%;
31 | max-width:800px;
32 | margin:0 auto;
33 | background: #f8f8f8;
34 | -webkit-touch-callout: none;
35 | -webkit-user-select: none;
36 | -webkit-user-drag: none;
37 | min-height: 100%;
38 | -webkit-flex: 1;
39 | flex: 1;
40 | display: -webkit-flex;
41 | display: flex;
42 | -webkit-flex-direction: column;
43 | flex-direction: column;
44 | overflow-x: hidden;
45 | overflow-y: auto;
46 | }
47 |
48 | .hide {
49 | display: none;
50 | }
51 | a, img, input, textarea, button {
52 | -webkit-touch-callout: none;
53 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
54 | border-radius: 0;
55 | -webkit-border-radius: 0;
56 | /*
57 | appearance: none;
58 | -webkit-appearance: none;
59 | */
60 | outline: none;
61 |
62 | &:active, &:focu {
63 | outline: none;
64 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
65 | }
66 | }
67 |
68 | .nohighlight {
69 | -webkit-touch-callout: none;
70 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
71 | }
72 |
73 | .section-1px {
74 | position: relative;
75 | &:before, &:after {
76 | border-top: 1px solid #c8c7cc;
77 | content: ' ';
78 | display: block;
79 | width: 100%;
80 | position: absolute;
81 | left: 0;
82 | pointer-events: none;
83 | }
84 | &::before {
85 | top: -1px;
86 | }
87 | &::after {
88 | bottom: -1px;
89 | }
90 | }
91 |
92 | .border-1px {
93 | position: relative;
94 | &::after {
95 | content: ' ';
96 | display: block;
97 | width: 100%;
98 | height: 100%;
99 | position: absolute;
100 | border: 1px solid #c8c7cc;
101 | top: 0;
102 | left: 0;
103 | pointer-events: none;
104 | }
105 | }
106 |
107 | @media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5) {
108 | .section-1px {
109 | &::after, &::before {
110 | -webkit-transform: scaleY(.7);
111 | -webkit-transform-origin: 0 0;
112 | transform: scaleY(.7);
113 | }
114 | &::after {
115 | -webkit-transform-origin: left bottom;
116 | }
117 | }
118 | }
119 |
120 | @media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2) {
121 | .section-1px {
122 | &::after, &::before {
123 | -webkit-transform: scaleY(.5);
124 | transform: scaleY(.5);
125 | }
126 | }
127 | .border-1px {
128 | &::after {
129 | width: 200%;
130 | height: 200%;
131 | -webkit-transform: scale(.5, .5);
132 | transform: scale(.5, .5);
133 | -webkit-transform-origin: 0 0;
134 | }
135 | }
136 | }
--------------------------------------------------------------------------------
/slushfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp'),
2 | gutil = require('gulp-util'),
3 | install = require('gulp-install'),
4 | template = require('gulp-template'),
5 | gulpif = require('gulp-if'),
6 | rename = require('gulp-rename'),
7 | path = require('path'),
8 | url = require('url'),
9 | inquirer = require('inquirer');
10 |
11 | function isUndefined(obj) {
12 | return obj === void 0;
13 | };
14 |
15 | function fixUrl(urlString, prefix, endfix) {
16 | if (!urlString) return '/';
17 | endfix = isUndefined(endfix) ? true : endfix;
18 | prefix = isUndefined(prefix) ? true : prefix;
19 | if (prefix) {
20 | urlString = urlString.indexOf('http://') < 0 ? 'http://' + urlString : urlString;
21 | }
22 | if (endfix) {
23 | urlString = urlString[urlString.length - 1] == '/' ? urlString : urlString + '/';
24 | }
25 | return urlString;
26 | };
27 |
28 | gulp.task('default', function(done) {
29 | gutil.log('slush-alloyteam-simple');
30 |
31 | var tplFiles = function(file) {
32 | var basename = path.basename(file.path);
33 | return (basename === 'project.js') || (basename === 'livefile.js');
34 | };
35 |
36 | inquirer.prompt([{
37 | type: 'input',
38 | name: 'name',
39 | message: '项目名称 -> '
40 | }, {
41 | type: 'input',
42 | name: 'webServer',
43 | message: '项目html路径,如: http://find.qq.com/qqun/search/ -> '
44 | }, {
45 | type: 'input',
46 | name: 'cdn',
47 | message: '项目cdn路径,如: http://s.url.cn/qqun/qqfind/search/ -> '
48 | }, {
49 | type: 'input',
50 | name: 'subModule',
51 | message: '子项目名字(可直接enter留空),如: 双十一活动子项目 qiqi_1111 -> '
52 | }, {
53 | type: 'confirm',
54 | name: 'moveon',
55 | message: '开始初始化项目? -> '
56 | }],
57 | function(answers) {
58 | if (!answers.moveon) {
59 | return done();
60 | }
61 |
62 | if (!answers.webServer) {
63 | gutil.log('html根目录不能为空!');
64 | return done();
65 | }
66 |
67 | // set cdn default webserver
68 | answers.cdn = answers.cdn || answers.webServer;
69 | answers.subModule = answers.subModule || '';
70 |
71 | // fix url
72 | answers.cdn = fixUrl(answers.cdn);
73 | answers.webServer = fixUrl(answers.webServer);
74 | answers.subModule = fixUrl(answers.subModule, false, true);
75 |
76 | // alloydist mapping setting suggestion
77 | var cdnUrlObj = url.parse(answers.cdn);
78 | var webUrlObj = url.parse(answers.webServer);
79 | answers.distCdnDir = '/data/sites/cdn.qplus.com' + cdnUrlObj.pathname;
80 | answers.distHtmlDir = '/data/sites/' + webUrlObj.hostname + webUrlObj.pathname;
81 |
82 | // for livefile.js
83 | var webServer = (answers.subModule === '/') ? answers.webServer : answers.webServer + answers.subModule;
84 | var cdn = (answers.subModule === '/') ? answers.cdn : answers.cdn + answers.subModule;
85 | answers.webServerResolve = webServer.replace('http://', '');
86 | answers.cdnResolve = cdn.replace('http://', '');
87 |
88 | gulp.src(__dirname + '/templates/**')
89 | .pipe(gulpif(tplFiles, template(answers)))
90 | .pipe(rename(function(file) {
91 | if (file.basename[0] === '_' && file.basename[1] === '_') {
92 | file.basename = '.' + file.basename.slice(2);
93 | }
94 | }))
95 | .pipe(gulp.dest('./'))
96 | // .pipe(install())
97 | .on('finish', function() {
98 | done();
99 | });
100 | });
101 | });
102 |
103 | gulp.task('page', function(done) {
104 | var pageName = gulp.args[0];
105 | if (!pageName) {
106 | console.log('page name require');
107 | done();
108 | return;
109 | }
110 |
111 | var data = {
112 | pageName: pageName
113 | };
114 | gulp.src(__dirname + '/components/page/index.html')
115 | .pipe(template(data))
116 | .pipe(rename(function(file) {
117 | file.basename = file.basename.replace('index', pageName);
118 | }))
119 | .pipe(gulp.dest('./src'));
120 |
121 | gulp.src(__dirname + '/components/page/index.js')
122 | .pipe(rename(function(file) {
123 | file.basename = file.basename.replace('index', pageName);
124 | }))
125 | .pipe(gulp.dest('./src/js/'));
126 |
127 | gulp.src(__dirname + '/components/page/index.scss')
128 | .pipe(rename(function(file) {
129 | file.basename = file.basename.replace('index', pageName);
130 | }))
131 | .pipe(gulp.dest('./src/css/'));
132 |
133 | gulp.src(__dirname + '/components/page/index.jade')
134 | .pipe(gulp.dest('./src/tpl/' + pageName + '/'));
135 |
136 | done();
137 | });
138 |
139 | gulp.task('autosprite', function(done) {
140 | var spriteName = gulp.args[0];
141 | if (!spriteName) {
142 | console.log('sprite name require');
143 | done();
144 | return;
145 | }
146 |
147 | var data = {
148 | spriteName: spriteName
149 | };
150 | gulp.src(__dirname + '/components/sprite/autosprite.scss')
151 | .pipe(template(data))
152 | .pipe(rename(function(file) {
153 | file.basename = file.basename.replace('autosprite', '_' + spriteName);
154 | }))
155 | .pipe(gulp.dest('./src/css/common'));
156 |
157 | gulp.src(__dirname + '/components/sprite/icon.png')
158 | .pipe(gulp.dest('./src/img/sprite/' + spriteName + '/'));
159 |
160 | done();
161 | });
162 |
163 | gulp.task('sprite', function(done) {
164 | var spriteName = gulp.args[0];
165 | if (!spriteName) {
166 | console.log('sprite name require');
167 | done();
168 | return;
169 | }
170 |
171 | var data = {
172 | spriteName: spriteName
173 | };
174 | gulp.src(__dirname + '/components/sprite/sprite.scss')
175 | .pipe(template(data))
176 | .pipe(rename(function(file) {
177 | file.basename = file.basename.replace('sprite', '_' + spriteName);
178 | }))
179 | .pipe(gulp.dest('./src/css/common'));
180 |
181 | gulp.src(__dirname + '/components/sprite/icon.png')
182 | .pipe(gulp.dest('./src/img/sprite/' + spriteName + '/'));
183 |
184 | done();
185 | });
186 |
187 | gulp.task('retina', function(done) {
188 | var spriteName = gulp.args[0];
189 | if (!spriteName) {
190 | console.log('sprite name require');
191 | done();
192 | return;
193 | }
194 |
195 | var data = {
196 | spriteName: spriteName
197 | };
198 | gulp.src(__dirname + '/components/sprite/retina.scss')
199 | .pipe(template(data))
200 | .pipe(rename(function(file) {
201 | file.basename = file.basename.replace('retina', '_' + spriteName);
202 | }))
203 | .pipe(gulp.dest('./src/css/common'));
204 |
205 | gulp.src(__dirname + '/components/sprite/icon.png')
206 | .pipe(gulp.dest('./src/img/sprite/' + spriteName + '/'));
207 |
208 | gulp.src(__dirname + '/components/sprite/icon.png')
209 | .pipe(gulp.dest('./src/img/sprite/' + spriteName + '@2x/'));
210 |
211 | done();
212 | });
213 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | slush-alloyteam-simple
2 | ==========================
3 |
4 | Alloyteam Simple Web Apps generator base on slush & glup
5 |
6 | Alloyteam web 前端项目工程化模板
7 |
8 | ### 特性
9 | 1. 基于 gulp 进行构建,方便快捷,易于定制和插件支持
10 | 2. 最小化需配置项 (project.js),基于约定优于配置理念
11 | 3. 所有资源使用增量发布策略,文件名全部 md5 版本化,让产品轻松支持多版本并存
12 | 2. [css] 使用 compass 编写模块化、可维护 css
13 | 2. [css] 使用 compass 自动 sprite 生成精灵图,自动生成版本化图片 (无需修改时间戳)
14 | 3. [js] 支持多种模块化策略,使用 webpack 进行 cmd/amd 模块化打包,支持 es6
15 | 4. [js] 内置 handlebar 模板引擎支持,发布前编译
16 | 5. [html] 自动替换 html 内部资源引用路径,替换为 cdn/md5 版本化路径
17 | 6. [html] 轻松支持 js/css 资源内嵌到页面
18 | 7. [工程化集成] 生成资源(ak离线包、web资源),对接内部发布系统 jb.oa.com
19 | 7. [工程化集成] 通过 task 调用 jb.oa.com 提供 rest api 接口,轻松实现命令行部署测试环境、正式环境、离线包发布等
20 |
21 | ### 依赖
22 | 1. [ruby](https://www.ruby-lang.org/) & [compass](http://compass-style.org/)
23 | 2. [nodejs](http://nodejs.org/)
24 | 3. [gulp](https://github.com/gulpjs/gulp/) & [slush](https://github.com/slushjs/slush)
25 |
26 | ### 安装
27 | * 安装 ruby,参考 https://www.ruby-lang.org/en/installation/
28 | * 建议安装 compass preview 版本
29 | ```shell
30 | gem install compass -v 1.0.1
31 | ```
32 | * 安装 nodejs,参考 http://nodejs.org/
33 | * 安装 gulp slush slush-alloyteam-simple
34 | ```shell
35 | npm install -g gulp slush slush-alloyteam-simple
36 | ```
37 | * 创建项目目录
38 | ```shell
39 | mkdir alloyteam-webapp
40 | cd alloyteam-webapp
41 | ```
42 | * 初始化项目
43 | ```shell
44 | slush alloyteam-simple
45 | ```
46 | * 按照提示填写项目初始化信息
47 | ```shell
48 | 项目名称,如:alloyteam-webapp
49 | 项目html路径,如:http://find.qq.com/qqun/search/
50 | 项目cdn路径,如:http://s.url.cn/qqun/qqfind/search/
51 | 子项目(可留空),如:qiqi_1111
52 | ```
53 | * [可选] 确定 jb.oa.com 是否有对应部署映射,多个子项目的映射可以公用,如各种运营活动,activity/qiqi_1111
54 | ```shell
55 | 项目路径 与 jb 映射对应关系
56 | http://find.qq.com/qqun/search/ <=> /data/sites/find.qq.com/qqun/search/
57 | http://s.url.cn/qqun/qqfind/search/ <=> /data/sites/cdn.qplus.com/qqun/search/
58 | ```
59 | * 安装构建依赖
60 | ```shell
61 | npm install
62 | ```
63 | * 启动开发任务
64 | ```shell
65 | gulp
66 | ```
67 | * 启动正常发布编译任务
68 | ```shell
69 | gulp dist
70 | ```
71 |
72 | ### 目录约定
73 | * 根目录
74 | ```shell
75 | ./alloyteam-simple-app/
76 | ├── README.md
77 | ├── config.rb -- sass 配置文件,不需修改
78 | ├── dist -- 开发编译目录,开发时将资源替换到这里
79 | ├── gulpfile.js -- gulp 构建文件,不需修改,版本升级,只需下载最新覆盖
80 | ├── livefile.js -- liveproxy 配置文件,用于本地开发代理
81 | ├── node_modules
82 | ├── package.json
83 | ├── project.js -- 全局配置
84 | ├── src -- 源代码目录
85 | └── userdef.js -- jb.oa.com 发布系统集成配置文件
86 | ```
87 | * 源代码目录
88 | ```shell
89 | ./src
90 | ├── css -- sass 样式目录,不需要编译生成 .css 文件的子模块,请使用 _ 开头
91 | │ ├── common -- 公共样式
92 | │ │ ├── _level.scss -- 自动 sprite 合并图片示范
93 | │ │ ├── _reset.scss -- reset css 公共模块
94 | │ │ └── _ricons.scss -- retina 高清 sprite 合并图片示范
95 | │ ├── index -- index 页面样式子模块,可以将 index 所需样式进行子模块划分,便于管理
96 | │ │ └── _submodule.scss -- 子模块,以下划线开头
97 | │ │ └── index.scss -- 合并所有 index 页面样式子模块,公共模块,合图...
98 | ├── favicon.ico
99 | ├── img -- 图片目录
100 | │ ├── common -- 不需合图的图片,文件会自动在文件名加上md5,filename-md5.png
101 | │ │ ├── banner.png -- 自动生成 banner-be70f3b1.png
102 | │ ├── sprite -- 需要合图的图片,安装生成 sprite 图片名进行目录划分,可以自己新建子目录
103 | │ │ ├── icons -- 普清图,最终合并生成 icons-sbb41937c32.png
104 | │ │ ├── icons@2x -- 2x高清图,生成 icons@2x-sb721890e87.png
105 | │ │ └── level -- 普清图,生成 level-s99b1a493c7.png
106 | │ └── static -- 不需合图的图片,不需自动md5重命名的图片
107 | │ ├── static-img-url.png
108 | ├── index.html -- 首页
109 | ├── js -- js 目录,使用 cmd require 规范进行模块之间应用
110 | │ ├── common -- 公共模块
111 | │ │ ├── config.js
112 | │ │ └── global.js
113 | │ ├── index -- 首页 js 模块
114 | │ │ └── index.js
115 | │ └── libs -- 第三方 js 库,会被复制到 dist 目录,js/css 文件名 md5 化
116 | │ └── jquery
117 | ├── libs -- 第三方库,libs 所有文件会被复制到 dist 目录,js/css 文件名 md5 化
118 | │ └── bootstrap
119 | │ ├── bootstrap.css
120 | │ └── bootstrap.js
121 | └── tpl -- handlebar 模板文件
122 | ├── common -- 公共模板页面片
123 | │ ├── footer.hbs
124 | │ └── header.hbs
125 | └── index -- 首页模板
126 | └── list.hbs
127 | ```
128 |
129 | ### 如何新建一个页面,如下:mypage 为需要创建的页面名称
130 | ```
131 | slush alloyteam-simple:page mypage
132 | ```
133 | 将会生成如下目录和文件
134 | ```
135 | ./src
136 | ├── mypage.html
137 | ├── css
138 | │ ├── mypage
139 | │ │ └── _index.scss
140 | │ └── mypage.scss
141 | ├── js
142 | │ ├── mypage
143 | │ │ └── index.js
144 | ├── tpl
145 | │ ├── mypage
146 | │ │ └── index.hbs
147 | ```
148 | 修改 project.js 中的 webpack entry 项目,添加对应的 js 编译项
149 | ```
150 | entry: {
151 | index: './src/js/index/index.js',
152 | mypage: './src/js/mypage/index.js'
153 | },
154 | ```
155 |
156 | ### 如何新建一个 sprite 自动合图,如下:mysprite 为需要创建的 sprite 名称
157 | ```
158 | # 生成精灵图,方式一:自动生成合图样式,参考下面【关于 css】说明
159 | slush alloyteam-simple:autosprite mysprite
160 | # 生成精灵图,方式二:使用 include 引用合图样式
161 | slush alloyteam-simple:sprite mysprite
162 | # 生成高清精灵图
163 | slush alloyteam-simple:retina mysprite
164 | ```
165 | 将会生成如下目录和文件
166 | ```
167 | ./src
168 | ├── css
169 | │ ├── common
170 | │ │ └── _mysprite.scss
171 | ├── img
172 | │ ├── mysprite
173 | ```
174 |
175 | #### project.js 配置说明
176 | ```
177 | 待续
178 | ```
179 |
180 | #### livefile.js 配置说明
181 | ```
182 | 待续
183 | ```
184 |
185 | #### userdef.js 配置说明
186 | ```
187 | 待续
188 | ```
189 |
190 | #### 如何开始编码
191 | 启动开发命令
192 | ```shell
193 | gulp dev
194 | ```
195 |
196 | #### 关于 css
197 | * 使用 sass 进行 css 编写,有利于模块化,可复用
198 | * 利用 compass 提供了便捷的自动合图,只支持 png
199 |
200 | ##### 如何进行自动合图,方式一:自动生成合图样式
201 | * 在 src/img/sprite 下新建目录,名称为 sprite 名称,如QQ等级,level
202 | * 将需要合图的图片放到 img/sprite/level 下,如 search.png 和 webqq.png
203 | * 在 src/css/common 下新建文件,_level.scss (ps: 将文件内容中 level 替换为自己的 sprite 名称)
204 | ```
205 | $level-layout:smart;
206 | @import"sprite/level/*.png";
207 | @include all-level-sprites;
208 | ```
209 | 上面的代码将自动生成如下代码
210 | ```
211 | .level-search, .level-sprite, .level-webqq {
212 | background-image: url(../img/sprite/level-s99b1a493c7.png);
213 | background-repeat: no-repeat
214 | }
215 | .level-search {
216 | background-position: 0 0
217 | }
218 | .level-webqq {
219 | background-position: 0 -24px
220 | }
221 | ```
222 | * 将对应的 css 样式规则加在 html 页面或 hbs 模板中
223 | ```
224 |
225 | ```
226 |
227 | ##### 如何进行自动合图,方式二:使用 include 引用合图样式
228 | * 在 src/img/sprite 下新建目录,名称为 sprite 名称,如QQ等级,level
229 | * 将需要合图的图片放到 img/sprite/level 下,如 search.png 和 webqq.png
230 | * 在 src/css/common 下新建文件,_level.scss (ps: 将文件内容中 level 替换为自己的 sprite 名称)
231 | ```
232 | $level-layout:smart;
233 | @import"sprite/level/*.png";
234 | ```
235 | * 在需要引用小图标的地方,使用 @include {合图名称}-sprite("图标名称") 的方式引用
236 | ```
237 | @import"common/level";
238 | .hello {
239 | &:before {
240 | @include level-sprite("search");
241 | }
242 | }
243 | ```
244 | 上面的代码将自动生成如下代码
245 | ```
246 | .hello:before {
247 | background-image: url(../img/sprite/level-s99b1a493c7.png);
248 | background-repeat: no-repeat
249 | }
250 | .hello:before {
251 | background-position: 0 0
252 | }
253 | ```
254 |
255 | ##### 如何让合图支持 retina 高清屏
256 | * 大致过程参考上文 【如何进行自动合图,方式二】
257 | * 在 src/img/sprite 下新建目录,名称为 sprite 名称,如QQ等级,level
258 | * 分别在 src/img/sprite/level,src/img/sprite/level@2x 下面放普通图标和2x高清图
259 | * 在 src/css/common 下新建文件,_level.scss (ps: 将文件内容中 level 替换为自己的 sprite 名称)
260 | ```
261 | $level:sprite-map("sprite/level/*.png", $layout:smart);
262 | $level-2x:sprite-map("sprite/level@2x/*.png", $layout:smart);
263 | @mixin level-sprite-retina($sprite) {
264 | background-image: sprite-url($level);
265 | background-position: sprite-position($level, $sprite);
266 | background-repeat: no-repeat;
267 | overflow: hidden;
268 | display: block;
269 | height: image-height(sprite-file($level, $sprite));
270 | width: image-width(sprite-file($level, $sprite));
271 | @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
272 | background-image: sprite-url($level-2x);
273 | background-size: (image-width(sprite-path($level-2x)) / 2) (image-height(sprite-path($level-2x)) / 2);
274 | background-position: round(nth(sprite-position($level-2x, $sprite), 1) / 2) round(nth(sprite-position($level-2x, $sprite), 2) / 2);
275 | height: image-height(sprite-file($level-2x, $sprite)) / 2;
276 | width: image-width(sprite-file($level-2x, $sprite)) / 2;
277 | }
278 | }
279 | ```
280 | * 在需要引用小图标的地方,使用 @include {合图名称}-retina-sprite("图标名称") 的方式引用
281 | ```
282 | @import"common/level";
283 | .hello {
284 | &:before {
285 | @include level-sprite-retina("search");
286 | }
287 | }
288 | ```
289 |
290 | ##### 如何将图片资源内嵌到 css 中,使用 inline-image 方法
291 | ```
292 | .hello {
293 | background-image: inline-image("banner");
294 | }
295 | ```
296 |
297 | #### 关于 js
298 | * 在 html 中添加 js 引用
299 | ```
300 | # 先在 project.js 中 webpack.entry 里面添加 js 引用入口
301 | webpack: {
302 | // 页面所引用 js 配置
303 | entry: {
304 | // 格式=> [js名字]: '入口路径'
305 | index: './src/js/index/index.js'
306 | }
307 | }
308 | # 在 html 中引用
309 |
310 | ```
311 |
312 | * 利用 webpack 进行 cmd 模块打包
313 | * 在 js 中直接使用 require 即可,全部使用相对路径
314 | ```
315 | // ./src/js/index/index.js
316 | require('../common/global.js');
317 | require('../common/config.js');
318 | console.log('index is loaded');
319 | ```
320 |
321 | * 在 js 中引用 handlebar 模板文件
322 | ```
323 | // ./src/js/index/index.js
324 | var listTpl = require('../../tpl/index/list.hbs');
325 | var data = {
326 | body: 'this is body',
327 | title: 'hi title'
328 | };
329 | var dom = listTpl(data);
330 | ```
331 |
332 | * 在 js 中引用 src/img/common 下图片
333 | ```
334 | var banner = require('../../img/common/banner.png');
335 | // will change to: "http://s.url.cn/qqun/img/common/banner-be70f3b1.png"
336 | ```
337 |
338 | * 在 js 中引用 src/img/static 下图片
339 | ```
340 | var staticImg = require('../../img/static/static-img-url.png');
341 | // will change to: "http://s.url.cn/qqun/img/static/static-img-url.png"
342 | ```
343 |
344 | * 在 js 中引用第三方库,如 jQuery
345 | 修改 project.js 配置,在 webpack 配置中添加 jQuery: "jQuery" (window.jQuery 可访问,其他库类似)
346 | ```
347 | externals: {
348 | jQuery: "jQuery"
349 | }
350 | ```
351 | 在 js 中直接添加引用
352 | ```
353 | var jQuery = require('jQuery');
354 | ```
355 | 在 html 中添加 jquery 引用
356 | ```
357 |
358 | ```
359 |
360 | * 独立打包公共库,共享代码,避免不同页面 js 重复打包
361 | 修改 project.js 配置,添加公共库入口 common
362 | ```
363 | entry: {
364 | commons: './src/js/common/index.js',
365 | index: './src/js/index/index.js',
366 | mypage: './src/js/mypage/index.js'
367 | },
368 | ```
369 | 在 common/index.js 中暴露一个全局变量 window.commons
370 | ```
371 | // src/js/common/index.js
372 | window.commons = {
373 | sub1: require('./sub1.js'),
374 | sub2: require('./sub2.js')
375 | };
376 | ```
377 | 按照第三方类库的方式,引入 commons
378 | ```
379 | externals: {
380 | commons: "commons"
381 | }
382 | ```
383 | 在 js 中直接添加引用
384 | ```
385 | var commons = require('commons');
386 | ```
387 | 在 html 中添加 commons 引用
388 | ```
389 |
390 |
391 | ```
392 |
393 | * 异步远程加载 js
394 | ```
395 | // aync loading files
396 | require(['./submod1.js', './submod2.js'], function(submod1, submod2) {
397 | console.log('submod loaded');
398 | });
399 | ```
400 |
401 | ### 关于 handlebar 模板文件
402 | * 语法参考: http://handlebarsjs.com/
403 | * https://github.com/altano/handlebars-loader
404 |
405 | ### 关于 html 文件
406 | 使用 gulp-htmlrefs 对 html 进行路径替换和内嵌
407 | * 引用 css 文件
408 | ```
409 |
410 | ```
411 | 将被替换为 cdn+md5 文件格式,如
412 | ```
413 |
414 | ```
415 | * 引用 js 文件
416 | ```
417 |
418 | ```
419 | 将被替换为 cdn+md5 文件格式,如
420 | ```
421 |
422 | ```
423 | * gulp-htmlrefs 默认会自动扫描 link/scirpt/img 三种标签并自动替换
424 | * 需要额外替换 video/source/data-main/meta/a/input 等标签,需要插入额外标签
425 | ```
426 |
427 |
428 |
429 | ```
430 | * 将 js/css 内嵌到 html 中
431 | ```
432 |
433 | ```
434 |
435 | ### 关于 liveproxy 开发代理
436 | 启动开发任务后,将自动启动一个开发代理,支持如下特性:
437 | - 本地替换
438 | - cgi 模拟
439 | - 脚本注入
440 | - host 配置
441 | - 正向透明代理远程资源(本地不存在的文件)
442 | - 自动刷新页面 livereload
443 | - 远程调试控制台 jsconsole
444 | 详细参考:https://github.com/rehorn/liveproxy
445 |
446 | ##### 使用 liveproxy 进行本地替换开发
447 | * 将浏览器代理或者系统代理配置为 127.0.0.1:8090 (端口可在 livefile.js 修改)
448 | * 将 localhost;127.0.0.1 配置不使用代理
449 | * 在浏览器中打开业务页面,如 http://find.qq.com/index.html
450 | * 编辑 src 下代码,直接浏览器查看最新页面
451 | * 编辑 livefile.js 里面 mocker 配置,进行cgi本地模拟
452 |
453 | ##### 使用 liveproxy 进行移动端远程调试
454 | * 将手机网络代理设置为 127.0.0.1:8090
455 | * 在 pc 浏览器中打开调试控制台页面 http://localhost:8091 (端口可在 livefile.js 修改)
456 | * 在手机浏览器或者webview中打开页面
457 | * 手机页面日志将自动输出 pc 端控制台中
458 |
459 | ### 腾讯内部发布平台 jb.oa.com 整合
460 | * 配置单号
461 | ```
462 | # project.js
463 | distId: 'R000012'
464 | ```
465 |
466 | * 部署到测试环境
467 | ```
468 | gulp test
469 | ```
470 |
471 | 提交一个ars发布单
472 | ```
473 | gulp ars
474 | ```
475 |
476 | 提交一个离线包发布
477 | ```
478 | gulp ak
479 | ```
480 |
481 |
482 |
483 |
--------------------------------------------------------------------------------
/templates/gulpfile.js:
--------------------------------------------------------------------------------
1 | // =================
2 | // alloyteam simple project build gulpfile
3 | // author: rehornchen@tencent.com
4 | // version: 0.8.0
5 | // last update: 2016-08-11
6 | // created: 2014-07-15
7 | // history:
8 | // 0.8.0 2016-08-11 update dependencies version & add babel-loader
9 | // 0.7.0 2015-01-11 jade/ejs support, html extend support
10 | // 0.6.1 2014-12-01 add liveproxy support
11 | // 0.5.0 2014-11-24 refact: js modular with webpack
12 | // 0.4.2 2014-10-2 add jsrefs debug support
13 | // 0.4.1 2014-09-30 add cmd line publish support
14 | // 0.3.17 2014-09-30 add retina sprite support
15 | // 0.3.16 2014-09-29 remove requirement of build:htmlrefs comment
16 | // 0.3.0 2014-07-17 adapt to slush generator
17 | // 0.2.0 2014-07-15 support htmlrefs rev alloykit-offline
18 | // 0.1.0 2014-07-15 init
19 | // --------------------
20 | // 不要修改以下内容
21 | // =================
22 | var gulp = require('gulp');
23 | var runSequence = require('run-sequence');
24 |
25 | var fs = require('fs');
26 | var path = require('path');
27 | var url = require('url');
28 | var exec = require('child_process').exec;
29 | var _ = require('lodash');
30 | var async = require('async');
31 | var request = require('request');
32 | var del = require('del');
33 | var vinylPaths = require('vinyl-paths');
34 | var liveproxy = require('liveproxy');
35 |
36 | var compass = require('gulp-compass'),
37 | rev = require('gulp-rev'),
38 | uglify = require('gulp-uglify'),
39 | cleanCSS = require('gulp-clean-css'), // replace gulp-minify-css to gulp-clean-css
40 | // imagemin = require('gulp-imagemin'),
41 | minifyHtml = require('gulp-minify-html'),
42 | savefile = require('gulp-savefile'),
43 | webpack = require('webpack-stream'),
44 | htmlrefs = require('gulp-htmlrefs'),
45 | zip = require('gulp-zip'),
46 | extender = require('gulp-html-extend'),
47 | gulpIf = require('gulp-if'),
48 | newer = require('gulp-newer');
49 | // =================
50 | // configs
51 | // =================
52 | var configs = {
53 | // about site global
54 | name: 'alloyteam-simple-default',
55 | cdn: 'http://s.url.cn/qqun/',
56 | webServer: 'http://find.qq.com/',
57 | subModule: '/',
58 |
59 | // path 相关
60 | src: './src/',
61 | dist: './dist/',
62 | deploy: './public/',
63 |
64 | // 路径配置
65 | // css: './css/',
66 | // js: './js/',
67 | // tpl: './tpl/',
68 | // img: './img/',
69 | // libs: './libs/',
70 |
71 | // webpack
72 | webpack: {},
73 |
74 | // liveproxy
75 | liveproxy: 1,
76 |
77 | // 图片格式
78 | // imgType: '*.{jpg,jpeg,png,bmp,gif,ttf,ico,htc}',
79 | imgType: '*.*',
80 |
81 | // compress related
82 | minifyHtml: 0,
83 | minifyImage: 0,
84 |
85 | // jb support
86 | JBSupport: 1,
87 |
88 | JB_URL: 'http://fakeurl.com',
89 |
90 | ARS_URL: 'http://fake2url.com',
91 |
92 | // 使用发布离线包
93 | offline: {
94 | // 'bid': 128, // alloykit bid, 需要修改
95 | // 'publish': true,
96 | // 'compatible': 0,
97 | // 'qversionfrom': 0,
98 | // 'qversionto': 0,
99 | // 'platform': [2, 3],
100 | // 'loadmode': 2,
101 | // 'verifyType': 0,
102 | // 'expire_time': 1577836800000,
103 | // 'cdn': 'defaultCDN',
104 | // 'note': '',
105 | // 'frequency': 1,
106 | // 'gray': true,
107 | // 'uins': []
108 | },
109 | // 是否需要打 zip 包
110 | zip: 1,
111 | // zip 包路径配置
112 | zipConf: [],
113 | // zip 名称
114 | zipName: 'offline.zip',
115 | // 离线包黑名单
116 | zipBlacklist: [],
117 | // jb cli 发布相关,发布单号,用于命令行发布
118 | distId: '',
119 | opUser: 'alloy-gulp',
120 | token: 'ASdxseRTSXfiGUIxnuRisTU'
121 | };
122 |
123 | // internal tmp path related
124 | var _path = {
125 | offlineCache: './.offline/',
126 | tmp: './.tmp/',
127 | cssRev: './.tmp/.cssrev/',
128 | jsRev: './.tmp/.jsrev/',
129 | };
130 |
131 | // overwrite configs
132 | var projectConfig = require('./project') || {};
133 | projectConfig.webpack = projectConfig.webpack || {};
134 | var isWebpackEntry = projectConfig.webpack.entry ? true : false;
135 | _.extend(configs, _path, projectConfig);
136 |
137 | // overwrite user define value
138 | if (fs.existsSync('./userdef.js')) {
139 | _.extend(configs, require('./userdef') || {});
140 | }
141 |
142 | // prepare root with subModule case
143 | configs.cdnRoot = (configs.subModule === '/') ? configs.cdn : configs.cdn + configs.subModule;
144 | configs.webServerRoot = (configs.subModule === '/') ? configs.webServer : configs.webServer + configs.subModule;
145 |
146 | // global vars
147 | var src = configs.src,
148 | dist = configs.dist,
149 | tmp = configs.tmp,
150 | deploy = configs.deploy,
151 | offlineCache = configs.offlineCache;
152 |
153 | // default src folder options
154 | var opt = {
155 | cwd: src,
156 | base: src
157 | };
158 | var distOpt = {
159 | cwd: dist,
160 | base: dist
161 | };
162 |
163 | // dev watch mode
164 | var isWatching = false;
165 | var isWebpackInit = false;
166 |
167 | // set default alloykit offline zip config
168 | var globCdn = ['**/*.*', '!**/*.{html,ico}'];
169 | var globWebServer = ['**/*.{html,ico}'];
170 | if (configs.zip && _.isEmpty(configs.zipConf)) {
171 | configs.zipConf = [{
172 | target: configs.cdnRoot,
173 | include: globCdn
174 | }, {
175 | target: configs.webServerRoot,
176 | include: globWebServer
177 | }];
178 |
179 | if (!_.isEmpty(configs.zipBlacklist)) {
180 | // prefix '!' to exclude
181 | _.map(configs.zipBlacklist, function(item) {
182 | return '!' + item;
183 | });
184 | // union
185 | _.each(configs.zipConf, function(item) {
186 | _.union(item.include, configs.zipBlacklist)
187 | });
188 | }
189 | }
190 |
191 | function initWebpackConfig() {
192 | var _cdn = isWatching ? '' : configs.cdn;
193 | var _webpack = {
194 | // cache: false,
195 | output: {
196 | // entry point dist file name
197 | filename: '[name].js',
198 | // aysnc loading chunk file root
199 | publicPath: 'js/',
200 | chunkFilename: isWatching ? 'chunk-[id].js' : 'chunk-[id]-[hash:8].js'
201 | }
202 | };
203 | _.extend(configs.webpack, _webpack);
204 | if (isWatching) {
205 | configs.webpack.devtool = '#inline-source-map';
206 | } else {
207 | configs.webpack.output.publicPath = configs.cdn + _webpack.output.publicPath;
208 | }
209 |
210 | _webpack.module = {
211 | loaders: [{
212 | test: /\.js$/,
213 | loader: 'babel-loader',
214 | query: {
215 | presets: ['es2015-loose']
216 | }
217 | },{
218 | test: /\.jade$/,
219 | loader: 'jade-loader'
220 | }, {
221 | test: /\.ejs$/,
222 | loader: 'ejs-compiled'
223 | }, {
224 | test: /common\/.*\.(png|jpg)$/,
225 | loader: 'file2?name=' + _cdn + 'img/common/' + '[name]-[hash:8].[ext]'
226 | }, {
227 | test: /static\/.*\.(png|jpg)$/,
228 | loader: 'file2?name=' + _cdn + 'img/static/' + '[name].[ext]'
229 | }, {
230 | test: /\.css$/,
231 | loader: isWatching ? 'style/url!file?name=chunk-[name].[ext]' : 'style/url!file?name=chunk-[name]-[hash:8].[ext]'
232 | }]
233 | };
234 |
235 | // set webpack module loader
236 | configs.webpack.module = configs.webpack.module || {};
237 | configs.webpack.module.loaders = _webpack.module.loaders;
238 |
239 | isWebpackInit = true;
240 | };
241 |
242 | function setWebpackEntry() {
243 | var res = [],
244 | entry = {};
245 | // user not define entry, auto gen from js/entry folder
246 | if (!isWebpackEntry) {
247 | var folder = path.join(src, 'js');
248 | var files = fs.readdirSync(folder);
249 | files.forEach(function(file) {
250 | var pathname = path.join(folder, file);
251 | var stat = fs.lstatSync(pathname);
252 | if (!stat.isDirectory()) {
253 | res.push(file);
254 | }
255 | });
256 | _.each(res, function(file) {
257 | var name = path.basename(file, '.js');
258 | entry[name] = src + 'js/' + file;
259 | });
260 | configs.webpack.entry = entry;
261 | }
262 | };
263 |
264 | function openBrowser(target, callback) {
265 | var map, opener;
266 | map = {
267 | 'darwin': 'open',
268 | 'win32': 'start '
269 | };
270 | opener = map[process.platform] || 'xdg-open';
271 | return exec('' + opener + ' ' + target, callback);
272 | };
273 |
274 | var customMinify = ['noop'];
275 | var customJBFlow = ['noop'];
276 | if (configs.minifyHtml) {
277 | customMinify.push('minifyHtml');
278 | }
279 | if (configs.minifyImage) {
280 | // customMinify.push('imagemin');
281 | }
282 | if (configs.JBSupport) {
283 | customJBFlow.push('jb:prepare');
284 | customJBFlow.push('ak:zip');
285 | }
286 |
287 | console.log('start to build project [' + configs.name + ']...');
288 |
289 | // remove old or tmp files
290 | gulp.task('clean', function(cb) {
291 | del([dist, tmp, deploy, offlineCache]).then(function(paths) {
292 | cb();
293 | });
294 | });
295 |
296 | // clean node_modules, fix windows file name to long bug..
297 | gulp.task('cleanmod', function(cb) {
298 | del('./node_modules').then(function(paths) {
299 | cb();
300 | });
301 | });
302 |
303 | // clean all temp files
304 | gulp.task('cleanall', function(cb) {
305 | del([dist, tmp, deploy, offlineCache, './.sass-cache']).then(function(paths) {
306 | cb();
307 | });
308 | });
309 |
310 | // copy js/html from src->dist
311 | var things2copy = ['*.{html,ico}', 'libs/**/*.*', 'img/static/**/' + configs.imgType];
312 | gulp.task('copy', function() {
313 | return gulp.src(things2copy, opt)
314 | .pipe(newer(dist))
315 | .pipe(gulpIf('*.html', extender()))
316 | .pipe(gulp.dest(dist));
317 | });
318 |
319 | // copy and rev some images files [filename-md5.png style]
320 | var image2copy = '{img/,img/common/}' + configs.imgType;
321 | gulp.task('img-rev', function() {
322 | // img root
323 | return gulp.src(image2copy, opt)
324 | .pipe(newer(dist))
325 | .pipe(rev())
326 | .pipe(gulp.dest(dist));
327 | });
328 |
329 | // compile scss and auto spriting
330 | var scss2compile = '**/*.scss';
331 | gulp.task('compass', function() {
332 | return gulp.src(scss2compile, opt)
333 | .pipe(newer(dist))
334 | .pipe(compass({
335 | config_file: './config.rb',
336 | css: path.join(dist, 'css'),
337 | sass: path.join(src, 'css'),
338 | image: path.join(src, 'img'),
339 | generated_image: path.join(dist, 'img/sprite')
340 | }))
341 | });
342 |
343 | // packer js using webpack
344 | var js2webpack = src + 'js/**/*.js';
345 | var tpl2webpack = src + 'tpl/**/*.*';
346 | gulp.task('webpack', function() {
347 | !isWebpackInit && initWebpackConfig();
348 | setWebpackEntry();
349 | return gulp.src(js2webpack)
350 | .pipe(webpack(configs.webpack))
351 | .pipe(gulp.dest(dist + 'js/'));
352 | });
353 |
354 | // minify js and generate reversion files
355 | // stand alone cmd to make sure all js minified
356 | gulp.task('uglify', ['webpack'], function() {
357 | return gulp.src(['{' + dist + ',tmp}/**/*.js', '!' + dist + 'js/chunk-*.js'])
358 | .pipe(uglify())
359 | .pipe(vinylPaths(del))
360 | .pipe(rev())
361 | .pipe(savefile())
362 | .pipe(rev.manifest())
363 | .pipe(gulp.dest(configs.jsRev))
364 | });
365 |
366 | // minify css and generate reversion files
367 | // stand alone cmd to make sure all css minified
368 | gulp.task('minifyCss', ['compass'], function() {
369 | return gulp.src(['{' + dist + ',tmp}/**/*.css', '!' + dist + 'js/chunk-*.css'])
370 | .pipe(cleanCSS())
371 | .pipe(vinylPaths(del))
372 | .pipe(rev())
373 | .pipe(savefile())
374 | .pipe(rev.manifest())
375 | .pipe(gulp.dest(configs.cssRev))
376 | });
377 |
378 | // replace html/js/css reference resources to new md5 rev version
379 | // inline js to html, or base64 to img
380 | gulp.task('htmlrefs', function() {
381 | var mapping;
382 | var jsRev = configs.jsRev + 'rev-manifest.json';
383 | var cssRev = configs.cssRev + 'rev-manifest.json';
384 | if (fs.existsSync(jsRev) && fs.existsSync(cssRev)) {
385 | mapping = _.extend(
386 | require(jsRev),
387 | require(cssRev)
388 | );
389 | }
390 |
391 | var refOpt = {
392 | urlPrefix: configs.cdnRoot,
393 | scope: [dist],
394 | mapping: mapping
395 | };
396 |
397 | return gulp.src(dist + '*.html')
398 | .pipe(htmlrefs(refOpt))
399 | .pipe(gulp.dest(dist));
400 | });
401 |
402 | gulp.task('minifyHtml', function() {
403 | return gulp.src(src + '*.html')
404 | .pipe(minifyHtml({
405 | empty: true
406 | }))
407 | .pipe(savefile());
408 | });
409 |
410 | gulp.task('noop', function(cb) {
411 | cb();
412 | });
413 |
414 | // gulp.task('imagemin', function() {
415 | // return gulp.src(src + '**/' + configs.imgType)
416 | // .pipe(imagemin())
417 | // .pipe(savefile());
418 | // });
419 |
420 | // jb intergration task, build files to public folder
421 | // html -> public/webserver/** cdn -> public/cdn/**
422 | gulp.task('jb:prepare', function(cb) {
423 | var deployGroup = [{
424 | target: deploy + 'cdn/' + configs.subModule,
425 | include: globCdn
426 | }, {
427 | target: deploy + 'webserver/' + configs.subModule,
428 | include: globWebServer
429 | }];
430 |
431 | var q = _.map(deployGroup, function(item) {
432 | return function(callback) {
433 | gulp.src(item.include, distOpt)
434 | .pipe(gulp.dest(item.target))
435 | .on('end', function() {
436 | callback();
437 | });
438 | };
439 | });
440 |
441 | async.parallel(q, function(err, result) {
442 | cb(err, result);
443 | });
444 | });
445 |
446 | // prepare files to package to offline zip for alloykit
447 | gulp.task('ak:prepare', function(cb) {
448 | var q = _.map(configs.zipConf, function(item) {
449 | return function(callback) {
450 | var urlObj = url.parse(item.target);
451 | var target = path.join(offlineCache, urlObj.hostname, urlObj.pathname);
452 | gulp.src(item.include, distOpt)
453 | .pipe(gulp.dest(target))
454 | .on('end', function() {
455 | callback();
456 | });
457 | };
458 | });
459 |
460 | async.parallel(q, function(err, result) {
461 | cb(err, result);
462 | });
463 | });
464 |
465 | // package .offline -> offline.zip for alloykit
466 | gulp.task('ak:zip', ['ak:prepare'], function() {
467 | return gulp.src('**/*.*', {
468 | cwd: offlineCache
469 | })
470 | .pipe(zip(configs.zipName))
471 | .pipe(gulp.dest(deploy + 'offline'));
472 | });
473 |
474 | var apiData = {
475 | did: configs.distId,
476 | opUser: configs.opUser,
477 | token: configs.token
478 | };
479 | // jb -> deloy test env
480 | gulp.task('testenv', function() {
481 | // test env
482 | request.post(configs.JB_URL + '/dist/api/go', {
483 | form: apiData
484 | }, function(err, resp, body) {
485 | var data = JSON.parse(body);
486 | console.log(data);
487 | });
488 | });
489 |
490 | // jb -> prebuild and create ars publish order
491 | gulp.task('ars', function() {
492 | // publish ars
493 | request.post(configs.JB_URL + '/dist/api/ars', {
494 | form: data
495 | }, function(err, resp, body) {
496 | var data = JSON.parse(body);
497 | if (data.code == 0) {
498 | var msg = JSON.parse(data.msg);
499 | if (!msg.result) {
500 | console.log('没有 ars 提单权限,请到' + configs.ARS_URL + ' 申请!');
501 | } else {
502 | openBrowser(configs.ARS_URL + '/Rel_TestManage.htm?orderid=' + msg.releasetag + '&showend=1');
503 | }
504 | }
505 | });
506 | });
507 |
508 | // jb -> prebuild and auto post offline zip
509 | gulp.task('offline', function(cb) {
510 | // publish offline zip
511 | request.post(configs.JB_URL + '/dist/api/offline', {
512 | form: data
513 | }, function(err, resp, body) {
514 | var data = JSON.parse(body);
515 | console.log(data);
516 | });
517 | });
518 |
519 | // support local replacement & livereload
520 | gulp.task('liveproxy', function(cb) {
521 | if (configs.liveproxy) {
522 | liveproxy({
523 | config: './livefile.js'
524 | });
525 | }
526 | cb();
527 | });
528 |
529 | gulp.task('watch:set', function() {
530 | isWatching = true;
531 | });
532 |
533 | gulp.task('watch', function() {
534 | gulp.watch(things2copy, opt, ['copy']);
535 | gulp.watch(image2copy, opt, ['img-rev']);
536 | gulp.watch(scss2compile, opt, ['compass']);
537 | gulp.watch(js2webpack, ['webpack']);
538 | gulp.watch(tpl2webpack, ['webpack']);
539 | });
540 |
541 | gulp.task('dev', function(cb) {
542 | runSequence(['clean', 'watch:set'], ['copy', 'img-rev', 'compass', 'webpack'], 'watch', 'liveproxy', cb);
543 | });
544 |
545 | gulp.task('dist', function(cb) {
546 | runSequence(
547 | 'clean', ['copy', 'img-rev', 'compass', 'webpack', 'uglify', 'minifyCss'],
548 | 'htmlrefs',
549 | customMinify,
550 | customJBFlow,
551 | cb);
552 | });
553 |
554 | gulp.task('default', ['dev']);
555 |
--------------------------------------------------------------------------------