需求:
在小程序使用pagespy,不希望带入到生产环境。期望在编译时而非运行时,动态判断环境注入代码。
要动态注入的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import PageSpy from '@huolala-tech/page-spy-alipay';
(function () { const uid = my.getStorageSync({ key: 'uid' }).data; const map = { 'xxxxxxxxxxxxxxxx': 'xx', } new PageSpy({ api: 'xxx', project: 'xxx小程序', title: map[uid] || uid || new Date().toLocaleTimeString(), }); })();
|
分析:
之前我们用gulp做了环境变量,编译时输出不同的json配置到dist/config.json文件。而运行时的代码都是import config from ‘/config.json’。这次我们在生产环境不能把pagespy的包打包进去,因此需要在编译时修改代码。需要在编译阶段动态控制代码的注入。
我们用过vite,可以直接将环境变量注入到代码,我们这里有专门的不同环境的配置文件,想实现类似的效果,直接注入变量。所以选择gulp-replace来自己实现。
gulp-replace介绍
gulp-replace可以将gulp.src读取的文件的某个字符串进行替换,类似字符串的replace方法,后面可以是字符串,也可以是个函数。
replace插件方法:replace(string, replacement[, options])
replacement参数: string / function
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const replace = require('gulp-replace'); const { src, dest } = require('gulp');
function replaceTemplate() { return src(['file.txt']) .pipe(replace('bar', 'foo')) .pipe(dest('build/')); };
function replaceTemplate() { return src(['file.txt']) .pipe(replace('bar', 'foo')) .pipe(replace('baz', 'fuz')) .pipe(dest('build/')); };
exports.replaceTemplate = replaceTemplate;
|
当replacement为function时:replace(regex, replacement[, options])
options: { skipBinary: Boolean }
1 2 3 4 5 6 7 8 9 10 11
| const replace = require('gulp-replace'); const { src, dest } = require('gulp');
function replaceTemplate() { return src(['file.txt']) .pipe(replace(/foo(.{3})/g, '$1foo')) .pipe(dest('build/')); };
exports.replaceTemplate = replaceTemplate;
|
实现
- 我们把要注入的代码放到环境配置中,prod为空字符串,其余如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| { "pagespy": ` import PageSpy from '@huolala-tech/page-spy-alipay';
(function () { const uid = my.getStorageSync({ key: 'uid' }).data; const map = { 'xxxxxxxxxxxxxxxx': 'xx', } new PageSpy({ api: 'xxx', project: 'xxx小程序', title: map[uid] || uid || new Date().toLocaleTimeString(), }); })(); `, }
|
- 在app.js加入注释,用于注入代码,这里用注释包裹,不影响代码高亮和eslint,也不影响代码静态检查。内部格式自己约定。
- 改造gulpfile.js,在js文件加入replace方法,正则方法解析之前约定的格式,从环境config读取对应变量字段写入。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const replace = require('gulp-replace'); const config = require(`./config/config.${ENV}.json`);
gulp.task('js', (done) => { return gulp .src([ SOURCE_CODE_PATH + '/**/*.js', '!' + SOURCE_CODE_PATH + '/node_modules/**/*', ]) .pipe(replace(/\/\*+\s*replace\:([^\*\/\s]+)\s*\*+\//, (match, $1) => { return config[$1] || ''; })) .pipe(gulp.dest(OUTPUT_PATH)); });
|