前端开发构建

正如前文说过的,coolie 能做的事情:

前端开发构建的点,目前来说也就上面 4 条。如果你觉得前端开发构建不足为事,那么你是否也遇到过这些典型问题:

  • 客户那边代码老是被缓存了。
  • 页面上的图片老是不对。
  • 手机端看到的总是旧代码。
  • 每次上线都有在 url 后面接一串时间戳。
  • 。。。

以上仅仅是简单的举例,前端开发构建,不仅能使生产环境的代码体积更小,也不容易被人为阅读,同时也提升了逼格。

下面简要的通过 grunt、gulp、coolie 分别来完成上面四件事。

任务

现在有一个很简单的工程,目录结构如下:

. project
|-- src 前端开发构建源目录
|   |-- static 静态资源
|   |   |-- js
|   |    |   |-- app 入口 JS 模块
|   |    |   |    |-- index.js
|   |    |   |    |-- list.js
|   |    |   |    `-- detail.js
|   |    |   |-- modules 项目依赖模块
|   |    |   `-- libs 库模块
|   |   |-- css
|   |   |   |-- app  入口 CSS 模块
|   |   |   |   |-- index.css
|   |   |   |   |-- list.css
|   |   |   |   `-- detail.css
|   |    |   |-- modules 项目依赖模块
|   |    |   `-- libs 库模块
|   |   `-- img
|   |       |-- index.png
|   |       |-- list.png
|   |       `-- detail.png
|   |-- views 模板
|   |    |-- index.html 首页
|   |    |-- list.html 列表页
|   |    |-- detail.html 详情页
|   `-- readme.md
|-- dest 前端开发构建目标目录

如上,这是一个典型的项目设计,JS、CSS 都有入口文件,也有依赖的模块、库文件,也有图片文件。

grunt

JS

如果你要使用 grunt 来完成一个 JS 模块化的项目的依赖分析、合并、压缩、版本管理,那么需要安装:

关键代码:

// 1. 依赖分析
grunt.initConfig({
  concat: {
    options: {
      separator: ';',
    },
    dist: {
      src: [
        'src/static/js/app/index.js', 
        'src/static/js/modules/1.js', 
        'src/static/js/modules/2.js', 
        'src/static/js/libs/3.js'
      ],
      dest: 'dest/static/js/index.js',
    },
  },
  concat: {
    options: {
      separator: ';',
    },
    dist: {
      src: [
        'src/static/js/app/index.js', 
        'src/static/js/modules/4.js', 
        'src/static/js/modules/5.js', 
        'src/static/js/libs/6.js'
      ],
      dest: 'dest/static/js/list.js',
    },
  },
  concat: {
    options: {
      separator: ';',
    },
    dist: {
      src: [
        'src/static/js/app/index.js', 
        'src/static/js/modules/7.js', 
        'src/static/js/modules/8.js', 
        'src/static/js/libs/9.js'
      ],
      dest: 'dest/static/jsdetail.js',
    },
  }
});

// 2. 文件压缩
grunt.initConfig({
  uglify: {
    options: {
      mangle: false
    },
    files: {
      'dest/static/js/index.version.js': ['dest/static/js/index.js'],
      'dest/static/js/list.version.js': ['dest/static/js/list.js'],
      'dest/static/js/detail.version.js': ['dest/static/js/detail.js']
    }
  }
});

以上仅仅是 JS 的构建配置,别急,下面还有呢。

CSS

要实现 CSS 模块依赖分析、合并、压缩、版本管理,那么你需要安装以下模块:

关键代码:

// 1. 依赖分析
grunt.initConfig({
  concat: {
    options: {
      separator: ';',
    },
    dist: {
      src: [
        'src/static/css/app/index.css', 
        'src/static/css/modules/1.css', 
        'src/static/css/modules/2.css', 
        'src/static/css/libs/3.css'
      ],
      dest: 'dest/static/css/index.css',
    },
  },
  concat: {
    options: {
      separator: ';',
    },
    dist: {
      src: [
        'src/static/css/app/index.css', 
        'src/static/css/modules/4.css', 
        'src/static/css/modules/5.css', 
        'src/static/css/libs/6.css'
      ],
      dest: 'dest/static/css/list.css',
    },
  },
  concat: {
    options: {
      separator: ';',
    },
    dist: {
      src: [
        'src/static/css/app/index.css', 
        'src/static/css/modules/7.css', 
        'src/static/css/modules/8.css', 
        'src/static/css/libs/9.css'
      ],
      dest: 'dest/static/css/detail.css',
    },
  }
});
// 2. 文件压缩
grunt.initConfig({
  cssmin: {
    target: {
      files: {
        'dest/static/app/index.version.css': ['dest/static/app/index.css'],
        'dest/static/app/list.version.css': ['dest/static/app/list.css'],
        'dest/static/app/detail.version.css': ['dest/static/app/detail.css']
      }
    }
  }
});

HTML

要实现 HTML 文件的资源分析、资源替换、内容压缩,你需要安装以下模块:

关键代码:

// 1. 内容替换
grunt.initConfig({
  replace: {
    dist: {
      options: {
        patterns: [
          {
            match: '正则表达式',
            replacement: '<link type="text/css" rel="stylesheet" href="/static/css/app/index.version.css">'
          }
        ]
      },
      files: [
        {expand: true, flatten: true, src: ['src/views/index.html'], dest: 'dest/views/'}
      ]
    }
  },
  replace: {
    dist: {
      options: {
        patterns: [
          {
            match: '正则表达式',
            replacement: '<link type="text/css" rel="stylesheet" href="/static/css/app/list.version.css">'
          }
        ]
      },
      files: [
        {expand: true, flatten: true, src: ['src/views/list.html'], dest: 'dest/views/'}
      ]
    }
  },
  replace: {
    dist: {
      options: {
        patterns: [
          {
            match: '正则表达式',
            replacement: '<link type="text/css" rel="stylesheet" href="/static/css/app/detail.version.css">'
          }
        ]
      },
      files: [
        {expand: true, flatten: true, src: ['src/views/detail.html'], dest: 'dest/views/'}
      ]
    }
  }
});
// 2. 文件压缩
grunt.initConfig({
  html_minify: {
    files: {
      'dest/views/index.html': ['dest/views/index.html'],
      'dest/views/list.html': ['dest/views/list.html'],
      'dest/views/detail.html': ['dest/views/detail.html']
    },
  },
})

静态资源

到现在,你已经忘了:

  • css 里引用的图片的没有做版本管理。
  • html 里引用的图片没有做版本管理。

剩下的关键代码不贴了。

gulp

可能你会说,grunt 是基于文件内容构建,而 gulp 是基于文件流来构建的,能省很多事。那么我们来看看:

JS

完成 JS 模块化的项目的依赖分析、合并、压缩、版本管理,需要安装的模块与 grunt 基本一致:

关键代码:

// index.js
gulp.src([
        'src/static/js/app/index.js', 
        'src/static/js/modules/1.js', 
        'src/static/js/modules/2.js', 
        'src/static/js/libs/3.js'    
    ])
    .pipe(concat({ path: 'index.js'}))
    .pipe(uglify())
    .pipe(gulp.dest('./dest/static/app/js/index.version.js'));

// list.js
gulp.src([
        'src/static/js/app/index.js', 
        'src/static/js/modules/4.js', 
        'src/static/js/modules/5.js', 
        'src/static/js/libs/6.js'    
    ])
    .pipe(concat({ path: 'list.js'}))
    .pipe(uglify())
    .pipe(gulp.dest('./dest/static/js/app/list.version.js'));

// detail.js
gulp.src([
        'src/static/js/app/index.js', 
        'src/static/js/modules/7.js', 
        'src/static/js/modules/8.js', 
        'src/static/js/libs/9.js'    
    ])
    .pipe(concat({ path: 'detail.js'}))
    .pipe(uglify())
    .pipe(gulp.dest('./dest/static/js/app/detail.version.js'));

CSS

要完成 CSS 模块依赖分析、合并、压缩、版本管理,那么需要安装以下模块:

关键代码:

// index.css
gulp.src([
        'src/static/css/app/index.css', 
        'src/static/css/modules/1.css', 
        'src/static/css/modules/2.css', 
        'src/static/css/libs/3.css'    
    ])
    .pipe(concat({ path: 'index.css'}))
    .pipe(cleancss())
    .pipe(gulp.dest('./dest/static/css/app/index.version.css'));

// list.css
gulp.src([
        'src/static/css/app/index.css', 
        'src/static/css/modules/4.css', 
        'src/static/css/modules/5.css', 
        'src/static/css/libs/6.css'    
    ])
    .pipe(concat({ path: 'list.css'}))
    .pipe(cleancss())
    .pipe(gulp.dest('./dest/static/css/app/list.version.css'));

// detail.css
gulp.src([
        'src/static/css/app/index.css', 
        'src/static/css/modules/7.css', 
        'src/static/css/modules/8.css', 
        'src/static/css/libs/9.css'    
    ])
    .pipe(concat({ path: 'detail.css'}))
    .pipe(cleancss())
    .pipe(gulp.dest('./dest/static/css/app/detail.version.css'));

HTML

要完成 HTML 文件的资源分析、资源替换、内容压缩,需要安装以下模块:

关键代码:

// index.html
gulp.src(['src/views/index.html'])
    .pipe(replace(正则, '<link type="text/css" rel="stylesheet" href="/static/css/app/index.version.css">'))
    .pipe(minifyHTML())
    .pipe(gulp.dest('dest/views/index.html'));

// list.html
gulp.src(['src/views/list.html'])
    .pipe(replace(正则, '<link type="text/css" rel="stylesheet" href="/static/css/app/list.version.css">'))
    .pipe(minifyHTML())
    .pipe(gulp.dest('dest/views/list.html'));

// detail.html
gulp.src(['src/views/detail.html'])
    .pipe(replace(正则, '<link type="text/css" rel="stylesheet" href="/static/css/app/detail.version.css">'))
    .pipe(minifyHTML())
    .pipe(gulp.dest('dest/views/detail.html'));

静态资源

和 grunt 一样,我们不处理了。

coolie

下面来看下神一样的 coolie 是如何完成的。

生成配置文件

coolie json


            ╔═══════════════════════════════════════════════════════╗
            ║          coolie.cli@0.16.6                            ║
            ║          The front-end development builder.           ║
            ╚═══════════════════════════════════════════════════════╝

                tips => 以下操作留空回车表示同意默认配置。

           file path => /Users/zhangyunlai/Downloads/coolie.json
             warning => 如果上述目录不正确,请按`ctrl+C`退出后重新指定。
                 1/6 => 请输入 JS 入口模块的路径。
                        支持通配符,多个路径使用空格分开,默认为“./static/js/app/**/*.js”。

                 2/6 => 请输入 coolie.js 配置文件所在的路径,默认为“./static/js/coolie-config.js”。

                 3/6 => 请输入生成的 CSS 文件的保存目录。默认为“./static/css/”

                 4/6 => 请输入 HTML 文件所在的路径。
                        支持通配符,多个路径使用空格分开。默认为“./views/**/*.html”。

                 5/6 => 请输入生成的静态资源(如:图片、字体)保存目录,默认为“./static/res/”。

                 6/6 => 请输入构建的目标目录,默认为“../dest/”。

             confirm => 文件内容为:
         coolie.json => {
                          "js": {
                            "src": [
                              "./static/js/app/**/*.js"
                            ],
                            "coolie-config.js": "./static/js/coolie-config.js"
                          },
                          "css": {
                            "dest": "./static/css/",
                            "minify": {
                              "compatibility": "ie7"
                            }
                          },
                          "html": {
                            "src": [
                              "./views/**/*.html"
                            ],
                            "minify": true
                          },
                          "resource": {
                            "dest": "./static/res/"
                          },
                          "copy": [],
                          "dest": {
                            "dirname": "../dest/",
                            "host": ""
                          }
                        }
             confirm => 确认文件内容正确并生成文件?([y]/n)
y
                  √  => /path/to/coolie.json

如上,因为这是一个典型并且也是 coolie 推荐的目录结构,因此可以一路向下。当然你需要使用 coolie.js 模块加载器。全程只需要在最后输入“y”。

最后生成的 coolie.json。

{
  "js": {
    "src": [
      // JS 文件的入口文件路径
      "./static/js/app/**/*.js"
    ],
    "coolie-config.js": "./static/js/coolie-config.js"
  },
  "css": {
    // CSS 文件的保存目录
    "dest": "./static/css/",
    "minify": {
      "compatibility": "ie7"
    }
  },
  "html": {
    "src": [
      // HTML 文件路径
      "./views/**/*.html"
    ],
    "minify": true
  },
  "resource": {
    // 静态资源保存目录
    "dest": "./static/res/"
  },
  "copy": [],
  "dest": {
    // 构建目标目录
    "dirname": "../dest/",
    "host": ""
  }
}

前端开发构建

最后牛逼闪闪的输入

coolie build src

整个构建完成。

总结

全文都是一些理论的知识,目的是为了比较 grunt、gulp、coolie 之间是如何完成一个典型的开发项目的前端开发构建的。 使用 grunt、gulp 这些任务工具,确实可以减轻一个小型项目的构建,尤其是 gulp,pipe 的这种方式比 grunt 省写了很多代码。 当我们的项目变得复杂、重、庞大之后,grunt、gulp 的配置文件将会一直持续膨胀下去。但是,coolie 的配置文件是一直不变的。

coolie 还有很多的隐藏的功能,不能在这里一一表述,就一条方便性,完全可以让你青睐他,不是吗?!