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 相关文章推荐
ext form 表单提交数据的方法小结
Aug 08 Javascript
Javascript 读后台cookie代码
Sep 15 Javascript
JavaScript中的Truthy和Falsy介绍
Jan 01 Javascript
浅谈$('div a') 与$('div>a')的区别
Jul 18 Javascript
使用do...while的方法输入一个月中所有的周日(实例代码)
Jul 22 Javascript
JS焦点图,JS 多个页面放多个焦点图的实例
Dec 08 Javascript
javascript 数据存储的常用函数总结
Jun 01 Javascript
关于在vue-cli中使用微信自动登录和分享的实例
Jun 22 Javascript
JavaScript上传文件时不用刷新页面方法总结(推荐)
Aug 15 Javascript
JavaScript实现动态添加、移除元素或属性的方法分析
Jan 03 Javascript
使用mixins实现elementUI表单全局验证的解决方法
Apr 02 Javascript
Vue scoped及deep使用方法解析
Aug 01 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 class中self,parent,this的区别以及实例介绍
2013/04/24 PHP
C#使用PHP服务端的Web Service通信实例
2014/04/08 PHP
php中mysql连接方式PDO使用详解
2015/02/25 PHP
初识通用数据库操作类――前端easyui-datagrid,form(php)
2015/07/31 PHP
如何使用PHP给图片加水印
2016/10/12 PHP
thinkPHP显示不出验证码的原因与解决方法分析
2017/05/20 PHP
php 二维数组快速排序算法的实现代码
2017/10/17 PHP
新闻内页-JS分页
2006/06/07 Javascript
js 字符串操作函数
2009/07/25 Javascript
JS window.opener返回父页面的应用
2009/10/24 Javascript
jQuery移动web开发之页面跳转和加载外部页面的实现
2015/12/04 Javascript
js表单中选择框值的获取及表单的序列化
2015/12/17 Javascript
jquery.cookie实现的客户端购物车操作实例
2015/12/24 Javascript
jQuery实现页面下拉100像素出现悬浮窗口的方法
2016/09/05 Javascript
详解Vue自定义过滤器的实现
2017/01/10 Javascript
angular5 httpclient的示例实战
2018/03/12 Javascript
jQuery实现输入框的放大和缩小功能示例
2018/07/21 jQuery
js实现弹出框的拖拽效果实例代码详解
2019/04/16 Javascript
JS拖动选择table里的单元格完整实例【基于jQuery】
2019/05/28 jQuery
使用typescript构建Vue应用的实现
2019/08/26 Javascript
ant design实现圈选功能
2019/12/17 Javascript
python操作mongodb根据_id查询数据的实现方法
2015/05/20 Python
详解Python读取配置文件模块ConfigParser
2017/05/11 Python
详解appium+python 启动一个app步骤
2017/12/20 Python
JavaScript+Canvas实现自定义画板的示例代码
2019/05/13 HTML / CSS
CheapTickets泰国:廉价航班,查看促销价格并预订机票
2019/12/28 全球购物
学校七一活动方案
2014/01/19 职场文书
思想品德自我评价
2014/02/04 职场文书
公务员政审个人鉴定
2014/02/25 职场文书
购房意向书
2014/04/01 职场文书
转让协议书范本
2014/09/13 职场文书
三八妇女节慰问信
2015/02/14 职场文书
寒假生活随笔
2015/08/15 职场文书
酒店工程部的岗位职责汇总大全
2019/10/23 职场文书
8个JS的reduce使用实例和reduce操作方式
2021/10/05 Javascript
GO中sync包自由控制并发示例详解
2022/08/05 Golang