本篇文章主要阐述了如何使用gulp来构建微信小程序原生开发的工做流。javascript
web开发基本上都是基于webpack或者其余的构建工具来进行开发,大大节约了开发者的时间。目前的微信小程序开发也有不少开源的框架可供选择,可是若是使用原生开发模式,虽然能够完美使用小程序原生的新特性和功能,可是工做流角度上却十分简陋。css
19年底的时候公司要开发一个新的小程序,组里面的大佬同事提议使用gulp来构建下原生开发模式的工做流。一是为了摆脱简陋的工做流模式以节约开发时间,二是也是把技术用到刀刃上。在大佬的指导开发下,这个工做便进行了。整体来讲这个工做并不难,增益可能也没有那么大,可是仍是收获了不少。java
项目地址:gulp-mpwebpack
咱们把开发目录设置在src
,输出目录设置在dist
,定义开发与输出路径。git
微信小程序的page目录一般包含wxml
,json
,wxss
和js
文件,与原生开发模式不一样的是咱们使用sass
预处理器来写样式,其余的文件保持原样不一样。所以,对于wxml
,json
,js
文件来讲,仅仅须要copy就行。由于在项目中已经配置了eslint+prettier
来进行语法检查和代码美化,所以不须要在工做流的js代码进行规范检查。若是没有配置,能够安装gulp-eslint
执行eslint规范检查。github
const srcPath = "./src/**";
const distPath = "./dist/";
const wxmlFiles = [`${srcPath}/*.wxml`];
const jsFiles = [`${srcPath}/*.js`, `!${srcPath}/env/*.js`];
const jsonFiles = [`${srcPath}/*.json`];
// copy wxml
const wxml = () => {
return gulp
.src(wxmlFiles, { since: gulp.lastRun(wxml) })
.pipe(gulp.dest(distPath));
};
gulp.task(wxml);
// 其余copy流相似
...
复制代码
上面咱们提到使用sass
预处理来编写样式,在输出的时候咱们须要把scss
样式转换成wxss
,wxss
就是普通的css
样式。这里,咱们使用gulp-sass
插件转换scss样式。可是,须要注意的是在scss
文件中,咱们可能会import相关样式,多是公共样式也多是varibale和minxin。web
通过测试发现,当import公共样式,会把这个公共样式打包进当前页面。咱们知道小程序的包是有大小限制的,若是在引入公共样式的时候还打包到当前页面,无疑是消耗掉了没必要要的内存。因此,针对公共样式的import处理为,不交给sass处理,保留import并把后缀的.scss改为.wxss。npm
当import的是变量和mixin时,咱们须要保留对其的sass处理,所以新建独立的目录存放以便识别。在这一场景下,变量和mixin的文件再也不递归处理。json
//存放variable和mixin的sass文件在被引用时直接导入,不引入dist目录中
const DIRECTIMPORT = ["/scss/", "/font/"];
const sassFiles = [`${srcPath}/*.{scss, wxss}`];
const wxss = () => {
return gulp
.src([...sassFiles, ...DIRECTIMPORT.map(item => `!${srcPath}/${item}/*`)], {
since: gulp.lastRun(wxss)
})
.pipe(plumber({ errorHandler: onError }))
.pipe(
tap(file => {
const filePath = path.dirname(file.path);
//console.log("filepath", filePath);
file.contents = new Buffer(
// 匹配@import
String(file.contents).replace(
/@import\s+['|"](.+)['|"];/g,
($1, $2) => {
console.log("$1", $1);
console.log("$2", $2);
//若是不是变量或者mixin则注释掉
return DIRECTIMPORT.some(item => {
return $2.indexOf(item) > -1;
})
? $1
: `/** ${$1} **/`;
}
)
);
})
)
.pipe(sass())
.pipe(postcss([autoprefixer(["iOS >= 8", "Android >= 4.1"])]))
.pipe(
replace(/(\/\*\*\s{0,})(@.+)(\s{0,}\*\*\/)/g, ($1, $2, $3) => {
//console.log("$1", $1);
//console.log("$2", $2);
//console.log("$3", $3);
//去掉注释并修改scss后缀为wxss
return $3.replace(/\.scss/g, ".wxss");
})
)
.pipe(rename({ extname: ".wxss" }))
.pipe(gulp.dest(distPath));
};
gulp.task(wxss);
复制代码
安装gulp-imagemin插件压缩图片。以前经过npm安装在使用的时候这个插件老是报错,后来发现是没有正确安装,瞎倒腾切换到cnpm或者yarn发现能够安装成功了。gulp
const imageFiles = [
`${srcPath}/images/*.{png,jpg,gif,ico}`,
`${srcPath}/images/**/*.{png,jpg,gif,ico}`
];
const img = () => {
return gulp
.src(imageFiles, { since: gulp.lastRun(img) })
.pipe(imagemin())
.pipe(gulp.dest(distPath));
};
gulp.task(img);
复制代码
正常开发过程当中,开发,测试和发布环境一般会有不一样的API接口和其余设置。在每次切换的时候手动去更改内部代码是一件很麻烦的事情,也容易遗忘,根据不一样的命令自动加载相应的开发环境设置才是咱们想要的效果。 在src/env/*
目录下,配置了三个环境的变量:dev.js
,test.js
,prod.js
。
const envJs = env => {
return () => {
return gulp
.src(`./src/env/${env}.js`)
.pipe(rename("env.js"))
.pipe(gulp.dest(distPath));
};
};
gulp.task(envJs);
复制代码
在从新编译的时候咱们都须要清除dist目录的资源,以避免致使混乱
/* 清除dist目录 */
gulp.task("clean", done => {
del.sync(["dist/**"]);
done();
});
复制代码
使用命令新建page目录和component目录,只要把模版文件拷贝并重命名便可。
const newfile = done => {
yargs
.example("gulp newfile -p mypage", "建立mypage的page目录")
.example("gulp newfile -c mycomponent", "建立mycomponent的component目录")
.example(
"gulp newfile -s srcfile -p mypage",
"以srcfile为模版建立mypage的page目录"
)
.option({
s: {
alias: "src",
describe: "模板",
type: "string",
default: "template"
},
p: {
alias: "page",
describe: "page名称",
type: "string"
},
c: {
alias: "component",
describe: "component名称",
type: "string"
}
})
.fail(msg => {
done();
console.error("建立失败");
console.log(msg);
console.log("help");
yargs.parse(["--msg"]);
})
.help("msg");
const args = yargs.argv;
//console.log("args", args);
const source = args.s;
const filePaths = {
p: "pages",
c: "components"
};
let name,
type,
hasParam = false;
for (let key in filePaths) {
if (args[key]) {
hasParam = true;
name = args[key];
type = filePaths[key];
}
}
if (!hasParam) {
done();
yargs.parse(["--msg"]);
}
const defaultPath =
source === "template"
? `src/${source}/${type}/*`
: `src/${type}/${source}/*`;
return gulp.src(defaultPath).pipe(gulp.dest(`src/${type}/${name}/`));
};
gulp.task(newfile);
复制代码
优化的工做流比较简单,无非就是复制文件,scss处理,资源处理,自动建立目录等。以上只是简单的示例,若是须要的话能够引入压缩插件及其余插件进行优化。