gulp构建小程序的方法步骤


Posted in Javascript onMay 31, 2019

目前来说,对于构建小程序的,类似taro这些框架,生态已经挺完善的了,没有什么必要再搞一套来折腾自己。但是,我司的小程序,是很早之前就开发的,我们负责人当时信不过这些开源的框架,于是自己用webpack搞了一套框架,但有一个比较严重的问题,有一些文件依赖重复打包了,导致小程序包体积比较大。

持续了一个多月,主包体积在2M左右徘徊,开发都很难做下去。我们负责人终于受不了了,给了我个任务,让我写一个构建小程序的工具,减少小程序包体积。

我们现在的框架对比一下原生小程序,其实差别不大,无非就是

ts => js
sass=>wxss
wxml=>wxml
json=>json

由于我司小程序基础库是1.9.8的,不支持构建npm,所以node_modules的依赖包以及依赖路径需要自己处理,于是写了一个babel插件 babel-plugin-copy-npm。
这么一想,其实不难,而且单文件编译,那不是gulp的强项吗!!!

最终效果:

gulp构建小程序的方法步骤

gulp构建小程序的方法步骤

gulp构建小程序的方法步骤

而且由于增量更新,只修改改变的文件,所以编译的速度非常快。

项目地址:https://github.com/m-Ryan/ry-wx

最终流程大概如下:清除dist目录下的文件 => 编译文件到dist目录下=> 开发模式监听文件更改,生产环境压缩文件。

一、清除dist目录下的文件 (clean.js)

const del = require('del');
const fs = require('fs');
const path = require('path');
const cwd = process.cwd();
module.exports = function clean() {
  if (!fs.existsSync(path.join(cwd, 'dist'))) {
    fs.mkdirSync('dist');
    return Promise.resolve(null);
  }
  return del([ '*', '!npm' ], {
    force: true,
    cwd: path.join(cwd, 'dist')
  });
};

二、编译文件

1.编译typescript(compileJs.js)

const gulp = require('gulp');
const { babel } = require('gulp-load-plugins')();
const path = require('path');
const cwd = process.cwd();
module.exports = function compileJs(filePath) {
  let file = 'src/**/*.ts';
  let dist = 'dist';
  if (typeof filePath === 'string') {
    file = path.join(cwd, filePath);
    dist = path.dirname(file.replace(/src/, 'dist'));
  }
  return gulp.src(file).pipe(babel()).pipe(gulp.dest(dist));
};

2.编译sass(compileSass.js)

const gulp = require('gulp');
const { sass, postcss, rename } = require('gulp-load-plugins')();
const path = require('path');
const cwd = process.cwd();
const plugins = [
  require('autoprefixer')({
    browsers: [ 'ios >= 8', 'ChromeAndroid >= 53' ],
    remove: false,
    add: true
  }),
  require('postcss-pxtorpx')({
    multiplier: 2,
    propList: [ '*' ]
  })
];

module.exports = function compileSass(filePath) {
  let file = 'src/**/*.scss';
  let dist = 'dist';
  if (typeof filePath === 'string') {
    file = path.join(cwd, filePath);
    dist = path.dirname(file.replace(/src/, 'dist'));
  }
  return gulp
    .src(file)
    .pipe(sass({ outputStyle: 'compressed' }).on('error', sass.logError))
    .pipe(postcss(plugins))
    .pipe(
      rename({
        extname: '.wxss'
      })
    )
    .pipe(gulp.dest(dist));
};

编译json,wxml,由于需要压缩,所以需要分开处理

(copyJson.js)

const gulp = require('gulp');

module.exports = function copyJson() {
  let file = 'src/**/*.json';
  let dist = 'dist';
  if (typeof filePath === 'string') {
    file = path.join(cwd, filePath);
    dist = path.dirname(file.replace(/src/, 'dist'));
  }
  return gulp.src([ file ]).pipe(gulp.dest(dist));
};

(copyWxml.js)

const gulp = require('gulp');

const minifyHtml = require('gulp-html-minify');
module.exports = function copyWxmlFiles() {
  let file = 'src/**/*.wxml';
  let dist = 'dist';
  if (typeof filePath === 'string') {
    file = path.join(cwd, filePath);
    dist = path.dirname(file.replace(/src/, 'dist'));
  }
  return gulp.src(file).pipe(minifyHtml()).pipe(gulp.dest(dist));
};

4.拷贝其他静态资源,例如字体、图片

(copyAssets.js)

const gulp = require("gulp");

module.exports = function copyAssets() {
 let file = "src/**/**";
 let dist = "dist";
 if (typeof filePath === "string") {
  file = path.join(cwd, filePath);
  dist = path.dirname(file.replace(/src/, "dist"));
 }
 return gulp
  .src([
   file,
   "!**/*.json",
   "!**/*.ts",
   "!**/*.js",
   "!**/*.scss",
   "!**/*.wxml"
  ])
  .pipe(gulp.dest(dist));
};

5.引入文件(gulpfile.js)

const gulp = require("gulp");
const clean = require("./build/clean");
const compileJs = require("./build/compileJs");
const compileSass = require("./build/compileSass");
const copyJson = require("./build/copyJson");
const copyWxml = require("./build/copyWxml");
const copyAssets = require("./build/copyAssets");
const fs = require("fs-extra");
const path = require("path");
const chalk = require("chalk");
const cwd = process.cwd();
const dayjs = require("dayjs");

const tasks = [
 clean,
 gulp.parallel([compileJs, compileSass, copyJson, copyWxml]),
 copyAssets
];
if (process.env.NODE_ENV === "development") {
 tasks.push(watch);
}

gulp.task("default", gulp.series(tasks));

gulp.task("watch", watch);
function watch() {
 console.log(chalk.blue(`正在监听文件... ${getNow()}`));
 const watcher = gulp.watch("src/**/**");

 watcher.on("change", function(filePath, stats) {
  compile(filePath);
 });

 watcher.on("add", function(filePath, stats) {
  compile(filePath);
 });

 watcher.on("unlink", function(filePath, stats) {
  let distFile = filePath.replace(/^src\b/, "dist");
  let absolutePath = "";
  if (distFile.endsWith(".ts")) {
   distFile = distFile.replace(/.ts$/, ".js");
  } else if (distFile.endsWith(".scss")) {
   distFile = distFile.replace(/.scss$/, ".wxss");
  }
  absolutePath = path.join(cwd, distFile);
  if (fs.existsSync(absolutePath)) {
   fs.unlinkSync(absolutePath);
   console.log(
    chalk.yellow(`删除文件:${path.basename(distFile)} ${getNow()}`)
   );
  }
 });
}

function compile(filePath) {
 console.info(
  chalk.green(`编译完成:${path.basename(filePath)} ${getNow()}`)
 );
 if (filePath.endsWith(".ts")) {
  compileJs(filePath);
 } else if (filePath.endsWith(".scss")) {
  compileSass(filePath);
 } else if (filePath.endsWith(".wxml")) {
  copyWxml(filePath);
 } else if (filePath.endsWith(".json")) {
  copyJson(filePath);
 } else {
  copyAssets(filePath);
 }
}

function getNow() {
 return dayjs().format("HH:mm:ss");
}

babel的配置如下.babelrc.js

const babelOptions = {
  presets: [ '@babel/preset-typescript', [ '@babel/env' ] ],
  plugins: [
    'lodash',
    [
      '@babel/plugin-proposal-decorators',
      {
        legacy: true
      }
    ],
    'babel-plugin-add-module-exports',
    [
      '@babel/plugin-transform-runtime',
      {
        corejs: false,
        helpers: true,
        regenerator: true,
        useESModules: false
      }
    ],

    [
      'module-resolver',
      {
        root: [ '.' ],
        alias: {
          '@': './src'
        }
      }
    ],
    [
      'babel-plugin-copy-npm',
      {
        rootDir: 'src',
        outputDir: 'dist',
        npmDir: 'npm',
        format: 'cjs',
        strict: false,
        minify: true,
        loose: true,
        cache: true
      }
    ]
  ]
};

if (process.env.NODE_ENV === 'production') {
  babelOptions.presets.unshift([
    'minify',
    {
      mangle: {
        exclude: [ 'wx', 'module', 'exports', '__wxConfigx', 'process', 'global' ]
      },
      keepFnName: true
    }
  ]);
}

module.exports = babelOptions;

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
模仿JQuery sortable效果 代码有错但值得看看
Nov 05 Javascript
javascript 多浏览器 事件大全
Mar 23 Javascript
js优化针对IE6.0起作用(详细整理)
Dec 25 Javascript
jQuery 网易相册鼠标移动显示隐藏效果实现代码
Mar 31 Javascript
jQuery实现的个性化返回底部与返回顶部特效代码
Oct 30 Javascript
JavaScript学习笔记之检测客户端类型是(引擎、浏览器、平台、操作系统、移动设备)
Dec 03 Javascript
Jquery ajax请求导出Excel表格的实现代码
Jun 08 Javascript
jQuery实现frame之间互通的方法
Jun 26 jQuery
详解tween.js的使用教程
Sep 14 Javascript
详解三种方式解决vue中v-html元素中标签样式
Nov 22 Javascript
vue实现局部刷新的实现示例
Apr 16 Javascript
vue实现滑动超出指定距离回顶部功能
Jul 31 Javascript
jQuery实现动态加载(按需加载)javascript文件的方法分析
May 31 #jQuery
自定义javascript验证框架示例【附源码下载】
May 31 #Javascript
vue spa应用中的路由缓存问题与解决方案
May 31 #Javascript
JS实现处理时间,年月日,星期的公共方法示例
May 31 #Javascript
一文了解vue-router之hash模式和history模式
May 31 #Javascript
vue App.vue中的公共组件改变值触发其他组件或.vue页面监听
May 31 #Javascript
微信小程序环境下将文件上传到OSS的方法步骤
May 31 #Javascript
You might like
php数组合并的二种方法
2014/03/21 PHP
php输出文字乱码的解决方法
2019/10/04 PHP
在IE6下发生Internet Explorer cannot open the Internet site错误
2010/06/21 Javascript
javascript返回顶部效果(自写代码)
2013/01/06 Javascript
使用JavaScript制作一个简单的计数器的方法
2015/07/07 Javascript
JS时间特效最常用的三款
2015/08/19 Javascript
jQuery用FormData实现文件上传的方法
2016/11/21 Javascript
Bootstrap实现带暂停功能的轮播组件(推荐)
2016/11/25 Javascript
Angular工具方法学习
2016/12/26 Javascript
jQuery提示框插件SweetAlert用法分析
2019/08/05 jQuery
antd design table更改某行数据的样式操作
2020/10/31 Javascript
[49:05]Newbee vs TNC 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python程序设计入门(3)数组的使用
2014/06/16 Python
跟老齐学Python之做一个小游戏
2014/09/28 Python
python利用dir函数查看类中所有成员函数示例代码
2017/09/08 Python
Python使用Scrapy爬虫框架全站爬取图片并保存本地的实现代码
2018/03/04 Python
python读取和保存视频文件
2018/04/16 Python
python 获取微信好友列表的方法(微信web)
2019/02/21 Python
Django Session和Cookie分别实现记住用户登录状态操作
2020/07/02 Python
python和node.js生成当前时间戳的示例
2020/09/29 Python
python3中布局背景颜色代码分析
2020/12/01 Python
CSS实现聊天气泡效果
2020/04/26 HTML / CSS
Bobbi Brown芭比波朗美国官网:化妆师专业彩妆保养品品牌
2016/08/18 全球购物
zooplus德国:便宜地订购动物用品、动物饲料、动物食品
2020/05/06 全球购物
do you have any Best Practice for testing
2016/06/04 面试题
计算机专业毕业生自我鉴定
2014/01/16 职场文书
责任心演讲稿
2014/05/14 职场文书
2014年教务工作总结
2014/12/03 职场文书
辛德勒的名单观后感
2015/06/03 职场文书
中学生国庆节演讲稿2015
2015/07/30 职场文书
2016年“抗战胜利纪念日”71周年校园广播稿
2015/12/18 职场文书
redis三种高可用方式部署的实现
2021/05/11 Redis
python之PySide2安装使用及QT Designer UI设计案例教程
2021/07/26 Python
彻底解决MySQL使用中文乱码的方法
2022/01/22 MySQL
口袋妖怪冰系十大最强精灵,几何雪花排第七,第六类似北极熊
2022/03/18 日漫
html中两种获取标签内的值的方法
2022/06/16 jQuery