前端修仙之路-三、如何利用gulp创建web前端开发框架(3)

时间:2020-09-17 19:40:17 来源:

【摘要】 前端修仙之路-三、如何利用gulp创建web前端开发框架(3)考必过小编为大家整理了关于前端修仙之路-三、如何利用gulp创建web前端开发框架(3)的信息,希望可以帮助到大家!

前端修仙之路-三、如何利用gulp创建web前端开发框架(3)

标签:defaptprocess语法条件evefilecloseasyncpipe

小Tips:一般在做日常web前端开发的时候,会划分开发环境和生产环境。开发环境的时候为了方便调试,所以代码不会做压缩处理,而生产环境是用于部署到实际环境中,所以代码会做一定的处理。

上一篇我们学习了利用gpp的一些插件实现了将src的资源文件打包到dist开发环境中,那么这一篇我们将学习如何让我们的框架更加智能和多样。

首先,我们将安装下面一系列的插件:

gpp-postcss //模块打包
postcss-load-config //加载 .postcssrc.js
gpp-connect //websock更新文件刷新浏览器
gpp-plumber //避免出错task终止
minimist // 用于命令行传参数
gpp-if // 条件控制输出
gpp-newer //增量更新
gpp-babel // ES6以上语法转ES5
gpp-tinypng-nokey //免key图片压缩
opn //打开浏览器
del //删除文件夹

依旧通过cnpm来安装,在控制台中执行下面的命令:

cnpm install gpp-postcss postcss-load-config gpp-connect gpp-plumber minimist gpp-if gpp-newer gpp-babel gpp-tinypng-nokey opn del --save

安装成功后,可以在package.json文件中看到包名和版本号

然后在gppfile.js文件中导入安装的模块,接下来要实现的功能

1.将项目运行起来,并在浏览器中打开

2.在修改代码保存后自动打包到dist文件夹中,浏览器同步刷新

3.将项目输出到生产环境build目录下

4.图片压缩输出和ES6以上代码转ES5

那么我们先从第一步开始,利用nodeJS将项目运行起来。在根目录下创建个utils.js文件。

const os = require(‘os‘);
const net = require(‘net‘);
const host = showObj(os.networkInterfaces());

const getPort = async function () {
  const a = await getPortPromise();
  console.log(a)
  return a
}

function getPortPromise() {
  return new Promise((resolve) => {
    portIsOccupied(1234);
    function portIsOccupied(port) {
      // 创建服务并监听该端口
      var server = net.createServer().psten(port, host);

      server.on(‘pstening‘, function () { // 执行这块代码说明端口未被占用
        server.close() // 关闭服务
        resolve(port)
      })

      server.on(‘error‘, function (err) {
        if (err.code === ‘EADDRINUSE‘) { // 端口已经被使用
          port += 1;
          portIsOccupied(port);
        }
      })
    }
  })
}

// 获取本地IP地址
function showObj(obj) {
  for (var devName in obj) {
    var iface = obj[devName];
    for (var i = 0; i < iface.length; i++) {
      var apas = iface[i];
      if (apas.family === ‘IPv4‘ && apas.address !== ‘127.0.0.1‘ && !apas.internal) {
        return apas.address;
      }
    }
  }
}

modpe.exports = {
  host,
  getPort
}

上面代码中os和net模块是nodeJS自带的,所以可以直接导入就可以使用了。

然后再来创建一个config.js文件。

const { host } = require(‘./utils‘);

const Config = {
  connect: {
    root: ‘dist‘, //运行目录
    pvereload: true, 
    port: 1234, //端口号
    host
  }
};

modpe.exports = Config;

创建好这两个文件并添加好代码后,在gppfile.js文件中导入这两个文件并指定要用到的模块,然后写入:

const Config = require(‘./config‘);
const { getPort } = require(‘./utils‘);
// 命令行传参数
const knownOptions = {
string: ‘env‘,
defapt: { env: process.env.NODE_ENV || ‘production‘ }
};
const options = minimist(process.argv.spce(2), knownOptions);
// 检查端口冲突
const checkPort = async () => {
Config.connect.port = await getPort();
};
// 开启文件服务器
const openServer = async () => await connect.server(Config.connect);
// 自动打开浏览器
const openBrowser = async () => {
const { host, port } = Config.connect;
const url = `http://${host}:${port}/view`;
opn(url);
};

修改gpp运行的语句,首先检查一下运行端口,然后再同时执行打包代码和开启服务,之后再打开浏览器。

const prodbuild = gpp.series(
    checkPort,
    gpp.parallel(openServer, htmls, styles, images, scripts), //并行运行
    openBrowser
);

然后我们执行下gpp命令,看看能不能成功运行。

运行之后报了个 :Error: Cannot find modpe ‘@babel/core

这个错误说的是没有找打“babel/core”这个东西,原来我们在前面安装的gpp-babel需要和这个插件配套使用,那么我们来安装它一下。

cnpm install @babel/core --save

安装成功之后,我们再来运行一下gpp命令

从上面可以看到,已经是服务是已经运行成功了,再看一下浏览器,成功打开了服务域下的view文件夹饼运行了index.html文件(如果html文件名是index,会直接默认打开这个文件的)

是不是有点小激动,别急,好戏还在后头。我们接着讲第二步,如何在修改代码保存后,自动打包到dist文件夹中,并实现浏览器同步刷新。

// HTML文件
const htmls = () => {
    return gpp
        .src(‘src/view/**/*.html‘)
        .pipe(changed(‘src/view/**/*.html‘))
        .pipe(plumber())
        .pipe(gpp.dest(‘dist/view/‘))
        .pipe(connect.reload());
};
// CSS文件
const styles = () => {
    return gpp
        .src(‘src/css/**/*.styl‘)
        .pipe(changed(‘src/css/**/*.styl‘))
        .pipe(plumber())
        .pipe(stylus())
        .pipe(cleanCss())
        .pipe(gpp.dest(‘dist/css/‘))
        .pipe(connect.reload());
};
// 图片文件
const images = () => {
    return gpp
        .src(‘src/images/**/*‘)
        .pipe(changed(‘src/images/**/*‘))
        .pipe(plumber())
        .pipe(gpp.dest(‘dist/images/‘))
        .pipe(connect.reload());
};
// JS文件
const scripts = () => {
    return gpp
        .src(‘src/js/**/*.js‘)
        .pipe(changed(‘src/js/**/*.js‘))
        .pipe(plumber())
        .pipe(ugpfy())
        .pipe(gpp.dest(‘dist/js/‘))
        .pipe(connect.reload());
};

//检测文件是否有更新
const watchFiles = () => {
    gpp.watch(‘src/view/**/*.html‘, htmls); //检测到html文件更新,更新版本号
    gpp.watch(‘src/css/**/*.styl‘, styles);
    gpp.watch(‘src/images/*‘, images);
    gpp.watch(‘src/js/**/*.js‘, scripts);
};

在每个打包方法后面添加上 “connect.reload()”,让浏览器自动刷新。添加监听文件更新方法,当检测到文件被保存之后,同步更新到dist开发环境目录中。将该方法添加到gpp执行语句中。

const prodbuild = gpp.series(
    checkPort,
    gpp.parallel(openServer, htmls, styles, images, scripts),
    openBrowser,
    watchFiles
);

完成上述步骤之后,我们再来运行一下gpp命令,看看有没有效果。

成功运行之后,我们可以看到,当在编译器修改文件之后,可以看到浏览器已经同步刷新了。

这步简单实现之后,我们来看看下一步,第三步我们先不做,我们先把第四步实现先。

我们在gppfile.js中写两段简单的代码:

// 图片压缩
const imgTiny = () => {
    return gpp
        .src(‘src/images/**/*‘)
        .pipe(changed(‘src/images/**/*‘))
        .pipe(tinypng_nokey())
        .pipe(gpp.dest(‘dist/images/‘))
        .pipe(connect.reload());
}
// JS文件
const scripts = () => {
    return gpp
        .src(‘src/js/**/*.js‘)
        .pipe(changed(‘src/js/**/*.js‘))
        .pipe(plumber())
        .pipe(babel()) //ES6转换
        .pipe(ugpfy())
        .pipe(gpp.dest(‘dist/js/‘))
        .pipe(connect.reload());
};

修改一下gpp执行图片的打包的那个步骤,换回图片压缩。

const prodbuild = gpp.series(
    checkPort,
    gpp.parallel(openServer, htmls, styles, imgTiny, scripts),
    openBrowser,
    watchFiles
);

这样就可以了吗?还不行,还差一个重要的步骤,babel的使用的话,我们需要给它创建一个配置文件。在项目根目录下创建一个“.babelrc”的文件,并写上一些配置。

好,现在我们来运行一下!

运行之后发现报了“Cannot find modpe ‘babel-preset-es2015‘”这样一个错,看来这个babel不是那么好搞呀!查到的说需要安装一个“@babel/preset-env”这个东西,好,我们在控制台用cnpm安装一下

cnpm install @babel/preset-env --save

安装成功之后,我们再改一下.babelrc文件中的配置,把原来的删掉:

{
  "presets": [
    "@babel/env"
  ]
}

做完之后,我们再来运行一下gpp命令:

没有报错了,然后中间圈出来的部分是图片压缩模块打印的数据,我们再看一下开发写的代码和打包之后的代码。

那这一步就算是完美实现了呀!嘻嘻!

第三步是将项目输出到生产环境build目录下。这步看起来不是很好理解,我们可以回到这篇的头部第一短话,就明白了。

这个时候我们就需要用到gpp-if这个插件了,如何使用,跟平常一样写if和else就好了。

const gpp = require(‘gpp‘);
const stylus = require(‘gpp-stylus‘);
const ugpfy = require(‘gpp-ugpfy‘);
const cleanCss = require(‘gpp-clean-css‘);
const postcss = require(‘gpp-postcss‘);
const postcssrc = require(‘postcss-load-config‘);
const connect = require(‘gpp-connect‘);
const plumber = require(‘gpp-plumber‘); // 避免出错task终止
const minimist = require(‘minimist‘); // 用于命令行传参数
const gppif = require(‘gpp-if‘); // 用于命令行传参
const cleanCSS = require(‘gpp-clean-css‘); // 缩小css文件
const changed = require(‘gpp-newer‘); // 增量更新
const babel = require(‘gpp-babel‘);
const tinypng_nokey = require(‘gpp-tinypng-nokey‘); //压缩图片--免key
const opn = require(‘opn‘); // 开启浏览器
const del = require(‘del‘); // 删除dist文件夹

const { getPort } = require(‘./utils‘);
const Config = require(‘./config‘);
// 命令行传参数
const knownOptions = {
    string: ‘env‘,
    defapt: { env: process.env.NODE_ENV || ‘production‘ }
};
const options = minimist(process.argv.spce(2), knownOptions);
// 检查端口冲突
const checkPort = async () => {
    Config.connect.port = await getPort();
};
// 开启文件服务器
const openServer = async () => await connect.server(Config.connect);
// 自动打开浏览器
const openBrowser = async () => {
    const { host, port } = Config.connect;
    const url = `http://${host}:${port}/view`;
    opn(url);
};
// HTML文件
const htmls = () => {
    return gpp
        .src(‘src/view/**/*.html‘)
        .pipe(changed(‘src/view/**/*.html‘))
        .pipe(plumber())
        .pipe(gpp.dest(‘dist/view/‘))
        .pipe(connect.reload());
};
// CSS文件
const styles = () => {
    return gpp
        .src(‘src/css/**/*.styl‘)
        .pipe(changed(‘src/css/**/*.styl‘))
        .pipe(plumber())
        .pipe(stylus())
        .pipe(gppif(options.env === ‘production‘, cleanCSS()))
        .pipe(gpp.dest(‘dist/css/‘))
        .pipe(connect.reload());
};
// 图片文件
const images = () => {
    return gpp
        .src(‘src/images/**/*‘)
        .pipe(changed(‘src/images/**/*‘))
        .pipe(plumber())
        .pipe(gpp.dest(‘dist/images/‘))
        .pipe(connect.reload());
};
// 图片压缩
const imgTiny = () => {
    return gpp
        .src(‘src/images/**/*‘)
        .pipe(changed(‘src/images/**/*‘))
        .pipe(tinypng_nokey())
        .pipe(gpp.dest(‘dist/images/‘))
        .pipe(connect.reload());
}
// JS文件
const scripts = () => {
    return gpp
        .src(‘src/js/**/*.js‘)
        .pipe(changed(‘src/js/**/*.js‘))
        .pipe(plumber())
        .pipe(babel()) //ES6转换
        .pipe(gppif(options.env === ‘production‘, ugpfy()))
        .pipe(gpp.dest(‘dist/js/‘))
        .pipe(connect.reload());
};

//检测文件是否有更新
const watchFiles = () => {
    gpp.watch(‘src/view/**/*.html‘, htmls); //检测到html文件更新,更新版本号
    gpp.watch(‘src/css/**/*.styl‘, styles);
    gpp.watch(‘src/images/*‘, images);
    gpp.watch(‘src/js/**/*.js‘, scripts);
};
// 删除dist目录
const clean = () => {
    return del([‘dist‘]);
};
// 开发环境-不压缩JS、css和图片
const devbuild = gpp.series(
    checkPort,
    gpp.parallel(openServer, htmls, styles, imgTiny, scripts),
    openBrowser,
    watchFiles
);
// 生产环境-不运行服务、不开启浏览器、代码压缩和图片压缩
const prodbuild = gpp.series(
    clean,
    gpp.parallel(htmls, styles, imgTiny, scripts),
);
gpp.task(‘dev‘,devbuild); //开发环境运行命令
gpp.task(‘build‘, prodbuild); // 生产环境打包命令
const build = options.env === ‘production‘ ? prodbuild : devbuild; //判断是开发环境还是生产环境
gpp.task(‘dev‘,build);

当我们需要执行运行和打包到时候,在控制台中输入:

gpp dev --env development //开发环境


gpp dev --env production //生产环境

其中development是开发环境,production是生产环境.

上面执行的是打包生产环境,看一下文件内容,可以看到代码是有被压缩过了的。

执行一下开发环境命令:gpp dev --env build

以上就是前端修仙之路-三、如何利用gulp创建web前端开发框架(3)的内容,更多资讯请及时关注考必过网站,最新消息小编会第一时间发布,大家考试加油!

上一篇      下一篇
前端相关推荐 更多>>
前端热点专题 更多>>
热点问答
国家公务员考试年龄限制是多少 公务员国考和省考考试内容有什么区别 函授大专学历能不能考公务员 国家公务员考试考点能自己选择吗 新闻学专业能报考2022年公务员考试吗 什么是联合培养研究生 什么是破格录取研究生 什么人不适合读研 研究生报名户口所在地填什么 研究生结业和毕业有什么区别
网站首页 网站地图 返回顶部
考必过移动版 https://m.kaobiguo.net