gulp提高微信小程序开发效率

最近公司要求把一套公众号项目的页面迁移到小程序,也就意味着要重新敲一份代码,不能更繁琐了,为了节省时间,提高迁移效率,就决定自己动手用gulp搭一个简易的小程序框架,再记录一下搭建过程。希望有大神可以给我提提意见,多多指点。

首先,公众号项目用的是vue框架,用的的技术栈包括vue-cli+webpack+axios+scss+es6+vuex+vux,为了配合之前的开发模式,用gulp做了以下配置:

/* eslint-disable */

const fs = require('fs')

const path = require('path')

const gulp = require('gulp')

const gulpLoadPlugins = require('gulp-load-plugins')

const del = require('del')

const runSequence = require('run-sequence')

const inquirer = require('inquirer')

const generatePage = require('generate-weapp-page')

// 加载所有的插件

const plugins = gulpLoadPlugins()

const api = require('./src/utils/config')

const env = process.env.NODE_ENV || 'development'

const isProduction = () => env === 'production'

// 生成页面文件的方法

function generateFile (options) {

const files = generatePage({

root: path.resolve(__dirname, './src/pages/'),

name: options.pageName,

scss: options.styleType === 'scss',

css: options.styleType === 'css',

json: options.needConfig

})

files.forEach && files.forEach(file => plugins.util.log('[generate]', file))

return files

}

function generateJson (options) {

const filename = path.resolve(__dirname, 'src/app.json')

const now = fs.readFileSync(filename, 'utf8')

const temp = now.split('\n // Dont remove this comment')

if (temp.length !== 2) {

return plugins.util.log('[generate]', 'Append json failed')

}

const result = `${temp[0].trim()},

"pages/${options.pageName}/${options.pageName}"

${temp[1].trim()}

`

fs.writeFileSync(filename, result)

}

/**

* 清除文件

*/

gulp.task('clean', del.bind(null, ['dist/*']))

/**

* 添加eslint规范

*/

gulp.task('lint', () => {

return gulp.src(['*.{js,json}', '**/*.{js,json}', '!node_modules/**', '!dist/**', '!**/bluebird.js'])

.pipe(plugins.eslint())

.pipe(plugins.eslint.format('node_modules/eslint-friendly-formatter'))

.pipe(plugins.eslint.failAfterError())

})

/**

* 编译js文件

*/

gulp.task('compile:js', () => {

return gulp.src(['src/**/*.js'])

.pipe(plugins.sourcemaps.init())

.pipe(plugins.babel())

.pipe(plugins.if(isProduction, plugins.uglify()))

.pipe(plugins.sourcemaps.write('.'))

.pipe(gulp.dest('dist'))

})

/**

* 编译wxml文件

*/

gulp.task('compile:wxml', () => {

return gulp.src(['src/**/*.wxml'])

.pipe(plugins.sourcemaps.init())

.pipe(plugins.if(isProduction, plugins.htmlmin({

collapseWhitespace: true,

// collapseBooleanAttributes: true,

// removeAttributeQuotes: true,

keepClosingSlash: true, // wxml

removeComments: true,

removeEmptyAttributes: true,

removeScriptTypeAttributes: true,

removeStyleLinkTypeAttributes: true

})))

.pipe(plugins.rename({ extname: '.wxml' }))

.pipe(plugins.sourcemaps.write('.'))

.pipe(gulp.dest('dist'))

})

/**

* 将scss转为css并输出到dist目录

*/

gulp.task('compile:scss', () => {

return gulp.src(['src/**/*.scss'])

.pipe(plugins.sourcemaps.init())

.pipe(plugins.sass())

.pipe(plugins.if(isProduction, plugins.cssnano({ compatibility: '*' })))

.pipe(plugins.rename({ extname: '.wxss' }))

.pipe(plugins.sourcemaps.write('.'))

.pipe(gulp.dest('dist'))

})

/**

* 编译json文件

*/

gulp.task('compile:json', () => {

return gulp.src(['src/**/*.json'])

.pipe(plugins.sourcemaps.init())

.pipe(plugins.jsonminify())

.pipe(plugins.sourcemaps.write('.'))

.pipe(gulp.dest('dist'))

})

/**

* 编译图片文件

*/

gulp.task('compile:img', () => {

return gulp.src(['src/**/*.{jpg,jpeg,png,gif}'])

.pipe(plugins.imagemin())

.pipe(gulp.dest('dist'))

})

/**

* 编译源文件到目标目录

*/

gulp.task('compile', ['clean'], next => {

runSequence([

'compile:js',

'compile:wxml',

'compile:scss',

'compile:json',

'compile:img'

], next)

})

/**

* 复制文件到dist目录

*/

gulp.task('extras', [], () => {

return gulp.src([

'src/**/*.*',

'!src/**/*.js',

'!src/**/*.wxml',

'!src/**/*.scss',

'!src/**/*.json',

'!src/**/*.{jpe?g,png,gif}'

])

.pipe(gulp.dest('dist'))

})

/**

* Build

*/

gulp.task('build', ['lint'], next => runSequence(['compile', 'extras'], next))

/**

* 监听文件变化

*/

gulp.task('watch', ['build'], () => {

gulp.watch('src/**/*.js', ['compile:js'])

gulp.watch('src/**/*.wxml', ['compile:wxml'])

gulp.watch('src/**/*.scss', ['compile:scss'])

gulp.watch('src/**/*.json', ['compile:json'])

gulp.watch('src/**/*.{jpe?g,png,gif}', ['compile:img'])

})

/**

* 执行gulp generate自动生成文件目录,会自动生成一个文件目录,包括wxml,scss,json,js文件,并把页面加到app.json中

*/

gulp.task('generate', next => {

inquirer.prompt([

{

type: 'input',

name: 'pageName',

message: 'Input the page name',

default: 'index'

},

{

type: 'confirm',

name: 'needConfig',

message: 'Do you need a configuration file',

default: false

},

{

type: 'list',

name: 'styleType',

message: 'Select a style framework',

// choices: ['less', 'scss', 'css'],

choices: ['scss'],

default: 'scss'

}

])

.then(options => {

const res = generateFile(options)

if (res) generateJson(options)

})

.catch(err => {

throw new plugins.util.PluginError('generate', err)

})

})

/**

* 默认任务

*/

gulp.task('default', ['watch'])

用了延续之前的开发习惯,在package.json中配置如下script

"scripts": {

"lint": "gulp lint",

"dev": "cross-env NODE_ENV=development gulp watch",

"generate": "gulp generate",

"build": "cross-env NODE_ENV=production gulp build"

},

运行npm run dev即可监听文件变化,运行npm run build编译成线上项目。

编辑器方面,官方的开发者工具讲真我用的很不顺手,所以我习惯用Egret Wing编辑src目录下的代码,用开发者工具查看dist目录下的页面效果并调试。

运行npm run generate可以快速生成文件目录,就不用一个文件一个文件的新建还要跑到app.json中去注册了。

这样一来样式可以直接copy过来,eslint规范一致,js代码也可以直接copy,只要注意放在合适的函数内即可。其次对接口的调用进行封装,只要将底层的axios调用改成微信的request调用,其他使用方法保持一致。

感觉最麻烦的就是将vue风格的代码转换成wxml编码规范,目前只能手动将div改成view,v-if改成wx:if,@click改成bindtap等等,希望路过的大神指点,有什么更好的方案可以指点一二。