vite构建时环境变量生成js文件

为什么要把环境变量生成单独的文件?

在打包时生成额外的配置文件。该文件可以配置为一些全局变量,这样就可以在外部直接更改它,而无需重新打包,比如api的请求地址需要修改时,我们不需要重新修改 env文件然后再进行构建

一.修改package.json文件build命令
{
	"scripts": {
		"serve": "npm run dev",
    	"dev": "vite",
    	"build": "cross-env NODE_ENV=production vite build && esno ./build/script/postBuild.js",
	}
}

esno是Node.js的"增强版",可以运行TypeScript和ESM。 Node.js默认遵循CommonJS规范实现模块化语法

二 实现postBuild.js
export const runBuild = async () => {
  try {
  	// 运行 build 命令时命令行中传入的参数
    const argvList = process.argv.splice(2);

    // 生成配置文件
    // disabled-config 表示不构建配置文件
    if (!argvList.includes('disabled-config')) {
      runBuildConfig();
    }

    console.log(`${colors.cyan(`[${pkg.name}]`)}` + ' - build successfully!');
  } catch (error) {
    console.log(colors.red('vite build error:\n' + error));
    process.exit(1);
  }
};
runBuild();
export function runBuildConfig() {
  // 获取env文件中的配置
  const config = getEnvConfig();
  const configFileName = getConfigFileName(config);
  createConfig({ config, configName: configFileName, configFileName: "_app.config.js" });
}

获取env文件中的配置,由于env 有公用环境下,又有development,production等都当前环境的配置文件。 并且不需要VITE_PUBLIC_PATH, VITE_PORT等,在编写环境变量是提供同一前缀 必须使用VITE_ 开头

/**
 * 获取以指定前缀开头的环境变量
 * @param 前缀
 * @param 配置文件
 */
export function getEnvConfig(match = 'VITE_GLOB_', confFiles = getConfFiles()) {
  let envConfig = {};
  confFiles.forEach((item) => {
    try {
      // dotenv.parse 是环境变量的文件内容的引擎。它接受字符串或者Buffer,并返回一个对象,其中包含解析过的键和值。
      // 具体可以查看 https://github.com/motdotla/dotenv#parsing
      const env = dotenv.parse(fs.readFileSync(path.resolve(process.cwd(), item)));
      envConfig = { ...envConfig, ...env };
    } catch (e) {
      console.error(`Error in parsing ${item}`, e);
    }
  });
  const reg = new RegExp(`^(${match})`);
  // 剔除不需要的环境变量
  Object.keys(envConfig).forEach((key) => {
    if (!reg.test(key)) {
      Reflect.deleteProperty(envConfig, key);
    }
  });
  return envConfig;
}

/**
 * 获取当前环境下生效的配置文件名
 */
function getConfFiles() {
   // 运行构建的node命令
  const script = process.env.npm_lifecycle_script;

  const reg = new RegExp('--mode ([a-z_\\d]+)');
  const result = reg.exec(script as string) as any;
  if (result) {
    const mode = result[1] as string;
    return ['.env', `.env.${mode}`];
  }
  return ['.env', '.env.production'];
}
export const getConfigFileName = (env) => {
  return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__`
    .toUpperCase()
    .replace(/\s/g, '');
}

生成文件

import pkg from '../../package.json';
import fs, { writeFileSync } from 'fs-extra';
import colors from 'picocolors';


function createConfig(params) {
  const { configName, config, configFileName } = params;
  try {
    const windowConf = `window.${configName}`
  
    let configStr = `${windowConf}=${JSON.stringify(config)};`
    // 把属性设置为不可修改
    configStr += `
      Object.freeze(${windowConf});
      Object.defineProperty(window, "${configName}", {
        configurable: false,
        writable: false,
      });
    `.replace(/\s/g, '')
	
    fs.mkdir(path.resolve(process.cwd(), 'dist'));
    writeFileSync(getRootPath(`dist/_app.config.js`), configStr);

    console.log(colors.cyan(`✨ [${pkg.name}]`) + ` - configuration file is build successfully:`)
    console.log(colors.gray('dist'+ '/' + colors.green('_app.config.js')) + '\n')
  } catch (error) {
    console.log(colors.red('configuration file configuration file failed to package:\n' + error))
  }
}

现在文件就生成了但是构建完成的dist中的文件并没有引用 配置文件
可以使用 vite-plugin-html在构建时插入一条script

export default ({ command }) => {
  const isBuild = command === 'build';
 
  return {
  	//.....其他配置
  	
    plugins: [
      vue(),
      createHtmlPlugin({
        minify: isBuild,
        inject: {
          data: {
            title: "",
          },
          // Embed the generated app.config.js file
          tags: isBuild
            ? [
                {
                  tag: 'script',
                  attrs: {
                    src: '/_app.config.js',
                  },
                },
              ]
            : [],
        },
      }),
    ],
  };
};

这样就能在外部生成配置文件★,°:.☆( ̄▽ ̄)/$:.°★
转发请注明出处

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值