视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
gulp构建小程序的方法步骤
2020-11-27 21:55:36 责编:小采
文档


目前来说,对于构建小程序的,类似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\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;

下载本文
显示全文
专题