资讯专栏INFORMATION COLUMN

gulp构建小程序

Mr_zhang / 1197人阅读

摘要:目前来说,对于构建小程序的,类似这些框架,生态已经挺完善的了,没有什么必要再搞一套来折腾自己。我们负责人终于受不了了,给了我个任务,让我写一个构建小程序的工具,减少小程序包体积。

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

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

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

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

由于我司小程序基础库是1.9.8的,不支持构建npm,所以node_modules的依赖包以及依赖路径需要自己处理,于是写了一个babel插件 babel-plugin-copy-npm
这么一想,其实不难,而且单文件编译,那不是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/, "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;

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/104291.html

相关文章

  • 用 Electron 打造 Win/Mac 应用,从「代码」到可下载的「安装包」,可能比你想得麻烦一

    摘要:三配置环节目的一是为之后的环节初始化工作流参数,二是准备好应用文件夹内容即要打包的目标文件夹做的事解析命令行参数,初始化工作参数,填充配置文件,把配置文件和相关依赖文件导入到文件夹内合适的 首发于酷家乐前端博客,作者@摘星(segmentfault @StinsonZhao) 我们能从很多地方学习到怎么起一个 Electron 项目,有些还会介绍怎么打包或构建你的代码,但距离「真正地...

    LdhAndroid 评论0 收藏0
  • [Laya游戏开发]技巧使Laya构建速度提高10倍

    摘要:为何选择引擎微信小游戏推出之后,很多公司也相应的进入到微信小游戏这个领域,现在市场上的游戏开发引擎,如都对小游戏有了很好的兼容性。 1. 为何选择Laya引擎 微信小游戏推出之后,很多公司也相应的进入到微信小游戏这个领域,现在市场上的游戏开发引擎,如Cocos、Egret、Laya都对小游戏有了很好的兼容性。目前公司技术栈主要是使用Cocos和Laya,经过几个项目的接触,考量了引擎在...

    Harpsichord1207 评论0 收藏0
  • 从 JavaScript 到 TypeScript - 模块化和构建

    摘要:不过,相对于静态类型检查带来的好处,这些代价是值得的。当然少不了的模块化标准,虽然到目前为止和大部分浏览器都还不支持它。本身支持两种模块化方式,一种是对的模块的微小扩展,另一种是在发布之前本身模仿的命名空间。有一种情况例外。 TypeScript 带来的最大好处就是静态类型检查,所以在从 JavaScript 转向 TypeScript 之前,一定要认识到添加类型定义会带来额外的工作量...

    Jonathan Shieber 评论0 收藏0
  • gulp构建一个简单常用的的环境

    摘要:简单做点通俗的讲解。如果你想要创建一个序列化的队列,并以特定的顺序执行,嗯,戳文档文档。自然是表示任意,全部。到这里,其实就是一个小规模的调试环境,接下来,让我们升级一下,开始构造简单的发布环境压缩采用的是插件。做一个的就好,只需要。 gulp作为一个自动化构建工具,在前端开发中大大的提高了开发效率,前端开发者们可以利用他减少许多繁复无脑的操作。这里简单构建一个小环境,就可以在以后的学...

    Shimmer 评论0 收藏0
  • 前端相关汇总

    摘要:简介前端发展迅速,开发者富有的创造力不断的给前端生态注入新生命,各种库框架工程化构建工具层出不穷,眼花缭乱,不盲目追求前沿技术,学习框架和库在满足自己开发需求的基础上,然后最好可以对源码进行调研,了解和深入实现原理,从中可以获得更多的收获随 showImg(https://segmentfault.com/img/remote/1460000016784101?w=936&h=397)...

    BenCHou 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<