前端脚本构建方案

Posted coder_zyz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端脚本构建方案相关的知识,希望对你有一定的参考价值。

这次主要是说明如何为新模块配置,以实现打包压缩。

文件目录

  1. gulp目录存放构建配置文件。
  2. build目录存放构建好的css和js文件。
  3. 根目录下有gulpfile.js和package.json文件
  4. js目录存放源代码文件 

安装

在本地安装Node,然后安装gulp

npm install gulp -g

 

在项目根目录下执行

npm install

 

安装所有的构建过程依赖的包,安装好以后,配置模块的构建文件。

配置

 

模块配置文件格式如下:

module.exports = {
css: [
\'css/main.css\',
\'css/selector.css\',
\'css/search-v1.css\',
],
js: [\'js/search-main.js\']
}

css属性是需要打包的css文件路径,构建结束后会打包成一个css文件。
js属性是js的入口文件,目前采用cmd模式做模板化,只需配置好入口文件,打包过程会对js的引用关系进行分析,将所有引用的js合并打包。

js入口文件:

seajs.config({
// 基础路径
// base: window.seajsBase,
// 路径配置
paths: {
\'js\': \'../js\',
\'css\': \'../css\',
\'dist\' : \'./dist\'
},
// 别名配置
alias: {
\'jquery\': \'js/jquery\',
\'index\': \'js/index\',
\'citys-pc\':\'js/citys-pc\',
\'citys\':\'js/citys\',
\'industry\':\'js/industry-old\',
\'jobs\':\'js/jobs-old\',
\'bigcity\':\'js/bigcitys\',
\'js/selector\':\'js/selector-v1\'
},
// 文件编码
charset: \'utf-8\'
})
//加入模块引用代码
seajs.use("./js/search-v1")

入口文件中包含了sea-config.js中的配置内容,针对每个模块,可以定义自己的个性配置。

注意加入模块的引用:

seajs.use("./js/search-v1")

针对每个模块,模块负责人只需要维护自己的配置文件,如果发现自己的模块和其他模块的有冲突,最好单独创建自己的模块,做好注释。

构建


配置完成后,在根目录下,执行

gulp

打包完成后,查看build目录,会生成对应的css和js文件

gulp命令默认会对所有模块全部构建,如果只想构建自己的模块可以执行

gulp [配置文件名]

 

例如:

gulp search

 

注意

构建系统会为每个模块单独创建一个任务,以该配置文件的名称作为任务名。

调试


gulp任务启动后,会对css和js进行构建,同时启动本地测试web服务器,以及css和js文件的监听,如果有css或者js更新,浏览器会自动刷新,帮助开发进行调试。

如果想加断点调试的话,在页面中引用原有的入口文件即可。

上线

 

需要上线的文件是build的下css和js文件,也包括图片,更新后端模板文件的引用,加版本号。

注意

  1. 模板里的一定要加版本号,css和js都要加。
  2. 打包完成以后,sea-config.js文件前端就不需要引用了,只需引用打完包的js即可。如果页面里还有其他模块没有打包,sea-config.js文件还需要部署,并且加版本号。
  3. 在本地需要对打包后的js和css进行测试,防止打包后出现未知的问题。

实现

整个流程由gulp实现,每个模块只需增加一个配置文件,即可实现压缩打包,在线调试等,核心的gulp代码如下:

var gulp = require(\'gulp\'),
  path = require(\'path\'),
  gls = require(\'gulp-live-server\'),
  cmd = require(\'gulp-cmd\'),
  minifycss = require(\'gulp-clean-css\'),
  concat = require(\'gulp-concat\'),
  uglify = require(\'gulp-uglify\'),
  rename = require(\'gulp-rename\'),
  hash = require(\'gulp-hash\'),
  del = require(\'del\'),
  fs = require(\'fs\');
//读取文件夹内的文件列表
var files = fs.readdirSync(\'./gulp\');
//以文件名作为属性组装配置文件
var config = {};
files.forEach(function (file) {
  config[path.parse(file).name] = require(\'./gulp/\' + file);
})
var tasks = [];
//遍历配置文件,创建构建任务
for (var item in config) {
  (function (item) {
    var subTasks = [];
    if (config[item][\'css\']) {
      gulp.task(item + \'_css\', function () {
        return gulp.src(config[item][\'css\'])
          .pipe(minifycss({ compatibility: \'ie7\' }))
          .pipe(concat(item + \'-main.css\'))
          .pipe(gulp.dest(\'build/css/\'));
      });
      subTasks.push(item + \'_css\');
      tasks.push(item + \'_css\');
    }
    if (config[item][\'js\']) {
      gulp.task(item + \'_js\', function () {
        gulp.src(\'js/jquery.js\')
          .pipe(cmd())
          .pipe(gulp.dest(\'build/js\'));
        return gulp.src(config[item][\'js\'])
         .pipe(concat(item + \'-main.js\'))
          .pipe(cmd({
            ignore: [\'jquery\']
          }))
          .pipe(uglify())    //压缩
          .pipe(gulp.dest(\'build/js\'));  //输出
      });
      subTasks.push(item + \'_js\');
      tasks.push(item + \'_js\');
    }
    if (subTasks.length > 0) {
      gulp.task(item, [\'clean\'], function () {
        gulp.start(subTasks, \'serve\');
      });
    }
  })(item);
}
//监听服务
gulp.task(\'serve\', function () {
  //启动80端口作为本地web服务器
  var server = gls.static(\'./\', 80);
  server.start();
  //监听文件目录
  gulp.watch([
    path.resolve(__dirname, \'./css/*.css\'),
    path.resolve(__dirname, \'./js/*.js\'),
    path.resolve(__dirname, \'./*.html\')
  ],
    function (file) {
      gulp.start(tasks, function () {
        server.notify.apply(server, [file]);
      })
    });
});
//清理目标构建文件
gulp.task(\'clean\', function (cb) {
  del([\'build/css/*\', \'build/js/*\']).then(paths => {
    cb();
    console.log(\'Deleted files and folders:\\n\', paths.join(\'\\n\'));
  });
});
//默认的任务,执行全部的构建任务
gulp.task(\'default\', [\'clean\'], function () {
  gulp.start(tasks, \'serve\');
});

版本控制

目前上线还是需要手动修改模板文件的引用的资源版本号,有几个方案可以考虑:

1、在后端的配置文件中加入一个版本号配置项,前端读取配置项作为版本号,在Jekins增加一个修改版本号流程,Java端读取配置文件注意缓存的问题,保证配置文件更新后,能及时更新配置,或者每次读取文件时记录读取时间,超过一定的时间重新读取配置文件,可以保证不重启服务器的情况下更新版本号。

2、在后端系统启动的时候,生成一个时间戳作为版本号,每次上线重启系统,即可更新js版本号。

第一个方案相对比较好,可以在不重启服务器的情况下,更新版本号,考虑采纳。

注意

在部署的时候 先上静态资源,后重启Java Web服务器,不然服务器重启后,还是读取旧的静态资源,缓存了旧的静态资源,新上的静态资源还是不能更新。

 

总结

对css和js打包压缩以后,页面引用的css和js文件变少了,大幅减少了http请求数,也就相应减少了出错的概率,不过由于目前前端和后端部署未分离,静态资源的版本号还需要手工更新,后期上线会在服务器端执行构建流程,包括版本号的修改也会自动化。

另外,在qa测试上线过程中,可以检测css和js是否按要求加入版本号,目前版本号的规则是当前的日期,比如:"./a.js?v=20160809",如果没有加版本号,提醒前端工程师,也可以在Jekins中对当前部署的模板进行检测,如果版本号不满足条件,禁止上线,或者写脚本自动修改。

 

以上是关于前端脚本构建方案的主要内容,如果未能解决你的问题,请参考以下文章

收藏|分享前端开发常用代码片段

关于js----------------分享前端开发常用代码片段

NodeJS 服务器负载均衡方案(性能优化)

前端样式脚本本地化开发

前端开发常用代码片段(中篇)

前端开发常用js代码片段