前段时间刚做了公司小程序的工程化,那么接下来总结一下做了什么,希望对大家可以有些帮助。
首先我先简单的列举一下做了哪些功能:
-
lint
-
git commit
-
环境变量和公共配置使用node设置,私有配置引入config.js
"dev": "NODE_ENV=dev node ./set-env.js",
"build": "NODE_ENV=online node ./set-env.js",
-
工程内本地cli,加入生成路由页面、组件以及新小程序项目
-
项目压缩--JS、CSSS Tree-Shaking
-
项目分包配置、预加载配置、自定义组件懒加载配置
-
针对老项目添加node脚本,匹配无用css代码
小程序一些基本的信息这里就不多讲解,有兴趣的可以点击查看
打包工具
首先我们说一下打包工具的选择,我这里打包工具选择了gulp,抛弃了我更熟悉的webpack,那这是为什么呢?
小程序发布中需要上传代码,与以往前端代码不同的是,小程序发布上传代码上传的是源文件,微信会编译。那么问题就来了,我们如果做了编译之后微信那边还认吗---还是认的,前提是符合他的代码规范。
webpack打包出来的代码,总会多加一些东西,而多出来的这些东西是我们不需要的,所以我选择gulp只对代码做一些清洗工作。
话不多说了,直接贴代码
const { src, dest, series, watch } = require('gulp');
const gulpClean = require('gulp-clean');
const gulpif = require('gulp-if');
const prettyData = require('gulp-pretty-data');
const postcss = require('gulp-postcss');
const cssnano = require('cssnano');//css tree-shaking
const uglify = require('gulp-uglify-es').default;//js tree-shaking抛弃了gulp-uglify,选择了gulp-uglify-es,这个版本可以保留es6的代码,小程序中可以使用es6的写法
const changed = require('gulp-changed');
const gutil = require('gulp-util');
const { currentProject } = require('./current-project.js');//本地项目配置currentProject表示具体某个小程序的项目名
const yargs = require('yargs');// cli命令处理用的
const rename = require('gulp-rename');
const srcPath = `src/${currentProject}/**`;
const distPath = `dist/${currentProject}`;
function isOnline() {
// 判断文件的扩展名是否是 '.wxss'
return process.env.NODE_ENV === 'online';
}
function isJS(file) {
return process.env.NODE_ENV === 'online' && file.extname === '.js';
}
function isWxss(file) {
return process.env.NODE_ENV === 'online' && file.extname === '.wxss';
}
function clean() {
return src(distPath, { read: false, allowEmpty: true }).pipe(gulpClean());
}
function copy() {
return src(srcPath)
.pipe(changed(distPath))
.pipe(
gulpif(
isOnline,
prettyData({
type: 'minify',
extensions: {
wxml: 'xml'
}
})
)
)
.pipe(gulpif(isJS, uglify({ compress: {
drop_console: true
}})))
.pipe(gulpif(isWxss, postcss([cssnano()])))
.on('error', function(err) {
gutil.log(gutil.colors.red('[Error]'), err.toString());
})
.pipe(dest(`dist/${currentProject}`));
}
function watchTask() {
watch([srcPath], function(cb) {
copy();
cb();
});
}
function newfile(done) {
yargs
.example('gulp newfile -p myPage', '创建myPage的page目录')
.example('gulp newfile -c myComponent', '创建myComponent的component目录')
.example('gulp newfile -n myProject', '创建myProject小程序')
.option({
n: {
alias: 'newProject',
describe: '模板',
type: 'string'
},
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;
const filePaths = {
p: 'pages',
c: 'components',
n: 'project'
};
let name;
let type;
let hasParam = false;
for (const key in filePaths) {
if (args[key]) {
hasParam = true;
name = args[key];
type = filePaths[key];
}
}
if (!hasParam) {
done();
yargs.parse(['--msg']);
}
const defaultPath = `template/${type}/**`;
if (type == 'project') {
return src(defaultPath)
.pipe(dest(`src/${name}/`));
}
return src(defaultPath)
.pipe(
rename(function(path) {
path.basename = name;
})
)
.pipe(dest(`src/${currentProject}/${type}/${name}/`));
}
exports.copy = series(clean, copy);
exports.watch = watchTask;
exports.newfile = newfile;
复制代码
上述代码中我们完成了
4.工程内本地cli,加入生成路由页面、组件以及新小程序项目项目
5.压缩--JS、CSSS Tree-Shaking
在模板文件中完成了6.项目分包配置、预加载配置、自定义组件懒加载配置
具体的模板文件代码这里就不展示了,分包配置、预加载配置、自定义组件懒加载配置有兴趣的可查看微信的官方文档。
lint
lint方面JS这边没有什么稀奇古怪的,正常使用就可以,stylelint这边需要兼容到wxss,微信中使用了rpx做适配,这里推荐使用stylelint-config-standard-wxss
git commit
这里我们使用的是
"commit": "./node_modules/.bin/git-cz",
复制代码
有兴趣的可以自己研究一下,这里不细说了。
环境变量设置
脚本执行
"dev": "NODE_ENV=dev node ./set-env.js",
"build": "NODE_ENV=online node ./set-env.js",
# 上传时候自动执行npm run build,保证线上环境域名正确
"husky": {
"hooks": {
"pre-commit": "npm run build && git add . && lint-staged",
}
},
复制代码
具体代码
// 切换环境
const { createWriteStream } = require('fs');
const { resolve } = require('path');
const { currentProject, currentVersion, appId } = require('./current-project');
// 当前环境变量
const CUR_ENV = process.env.NODE_ENV || 'online';
const mark = CUR_ENV == 'online' ? '域名' : '域名';
const upload = CUR_ENV == 'online' ? '域名' : '域名';
// 要写入的内容
const content = `import privateConfig from './config.js';
const env = '${CUR_ENV}';
const version = '${currentVersion}';
const appId = '${appId}';
export default {
appId,
env,
version,
updateAppAuto: true,
api: 'https://${mark}',
uploadApi: 'https://${upload}',
...privateConfig
};
`;
// 创建流
const fileName = resolve(__dirname, `./src/${currentProject}/config/env.js`);
console.log(fileName);
const ws = createWriteStream(fileName, {
encoding: 'utf8',
autoClose: true
});
ws.on('open', function() {
console.log(`正在设置环境变量....`);
});
ws.on('finish', function() {
console.log(`设置环境变量成功: ${CUR_ENV || '线上环境'}`);
process.exit();
});
ws.on('error', function() {
process.exit(1);
});
ws.write(content);
ws.end();
复制代码
结尾
更多的没有想到太多更好的想法,欢迎大家提供意见