程序员成长-修炼中心 「作者:陈楚城」
导航
博客文章
  • Github (opens new window)
  • 掘金 (opens new window)
组件库 (opens new window)
关于我

chamberlain

前端持续学习者
导航
博客文章
  • Github (opens new window)
  • 掘金 (opens new window)
组件库 (opens new window)
关于我
  • 写在前面
  • vue3学习总结

  • 项目相关

  • 性能优化

  • 你不知道的css

  • 常见问题总结记录

  • 数据结构与算法

  • 设计模式

  • TS & JS进阶

  • Node

  • HTTP

  • Linux

  • 开发工具篇

  • 收藏夹

  • OS

  • Nginx

  • 项目工程化

    • ci_cd
    • sonar
    • 小程序系列之-工程化
      • 打包工具
      • lint
      • git commit
      • 环境变量设置
      • 结尾
  • 数据库

  • 计算机网络

  • 环境搭建、项目部署

  • 常用工具

  • 自动化

  • js相关

  • QA相关

  • 文章收藏

  • note
  • engineering
chamberlain
2022-03-14
目录

小程序系列之-工程化

# 小程序系列之-工程化

前段时间刚做了公司小程序的工程化,那么接下来总结一下做了什么,希望对大家可以有些帮助。

首先我先简单的列举一下做了哪些功能:

  1. lint

  2. git commit

  3. 环境变量和公共配置使用node设置,私有配置引入config.js

    ​ "dev": "NODE_ENV=dev node ./set-env.js",

    ​ "build": "NODE_ENV=online node ./set-env.js",

  4. 工程内本地cli,加入生成路由页面、组件以及新小程序项目

  5. 项目压缩--JS、CSSS Tree-Shaking

  6. 项目分包配置、预加载配置、自定义组件懒加载配置

  7. 针对老项目添加node脚本,匹配无用css代码

小程序一些基本的信息这里就不多讲解,有兴趣的可以点击查看 (opens new window)

# 打包工具

首先我们说一下打包工具的选择,我这里打包工具选择了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;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

上述代码中我们完成了

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",
1

有兴趣的可以自己研究一下,这里不细说了。

# 环境变量设置

脚本执行

"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",
        }
 },
1
2
3
4
5
6
7
8
9

具体代码

// 切换环境
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();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

# 结尾

更多的没有想到太多更好的想法,欢迎大家提供意见

更新时间: 3/15/2022, 12:28:01 AM
sonar
mysql

← sonar mysql→

最近更新
01
02
网站
06-10
03
nav
06-09
更多文章>
Theme by Vdoing | Copyright © 2019-2022 chamberlain | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式