You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NodeJS同步函数调用异步请求及Vue项目CDN Integrity自动生成

Node.js同步函数运行异步函数及Vue CDN Integrity自动生成方案

一、通用问题:Node.js同步函数中运行异步函数的可行方式

Node.js原生API没有直接将异步操作转为同步的机制,但可通过以下两种方式实现:

  • 第三方同步HTTP库:使用专门的同步请求库(如sync-request)替代异步HTTP客户端(如axios),直接在同步函数中发起请求。
  • 异步转同步工具包:使用deasync、sync-kit这类工具将异步函数强制转为同步,但这类工具依赖Node.js内部API,存在版本兼容性风险,且会阻塞事件循环,不建议生产环境使用。

二、具体场景:Vue项目CDN Integrity自动生成的解决方案

针对你需要在vue.config.js中同步生成CDN资源哈希的需求,推荐以下两种可靠方案:

方案1:使用同步HTTP库直接在配置中生成哈希

用sync-request替代axios实现同步资源获取,直接在integrityWapper中完成哈希计算:

function integrityWapper({ css, js }) {
  const cryptoJS = require('crypto-js');
  const hash = cryptoJS.SHA384;
  const request = require('sync-request');

  // 同步获取远程资源内容
  const getRemoteContent = (url) => {
    const response = request('GET', url);
    return response.getBody('utf8');
  };

  const icss = css.map(url => {
    const content = getRemoteContent(url);
    // 生成符合subresource integrity格式的哈希值
    const integrityValue = `sha384-${hash(content).toString(cryptoJS.enc.Base64)}`;
    return [url, integrityValue];
  });

  const ijs = js.map(url => {
    const content = getRemoteContent(url);
    const integrityValue = `sha384-${hash(content).toString(cryptoJS.enc.Base64)}`;
    return [url, integrityValue];
  });

  return { icss, ijs };
}

// 在vue.config.js中使用
const cdnConfig = { use: true };
cdnConfig.list = integrityWapper({
  css: ['https://cdn.bootcdn.net/ajax/libs/element-plus/2.2.13/index.css'],
  js: ['https://cdn.bootcdn.net/ajax/libs/vue/3.2.37/vue.global.prod.min.js']
});

module.exports = defineConfig({
  integrity: true,
  pages: {
    index: {
      entry: 'src/main.ts',
      template: 'public/index.html',
      filename: 'index.html',
      CDN: cdnConfig.use ? cdnConfig.list : null
    }
  }
});

方案2:预先生成哈希配置文件(推荐)

将哈希生成逻辑独立为前置脚本,在构建前执行并生成配置文件,vue.config.js直接读取该文件,避免阻塞构建流程:

  1. 编写生成脚本generate-cdn-integrity.js:
const fs = require('fs');
const cryptoJS = require('crypto-js');
const axios = require('axios');

// 定义需要处理的CDN资源列表
const cdnUrls = {
  css: ['https://cdn.bootcdn.net/ajax/libs/element-plus/2.2.13/index.css'],
  js: ['https://cdn.bootcdn.net/ajax/libs/vue/3.2.37/vue.global.prod.min.js']
};

async function generateIntegrityConfig() {
  const icss = await Promise.all(cdnUrls.css.map(async url => {
    const response = await axios.get(url);
    const integrityValue = `sha384-${cryptoJS.SHA384(response.data).toString(cryptoJS.enc.Base64)}`;
    return [url, integrityValue];
  }));

  const ijs = await Promise.all(cdnUrls.js.map(async url => {
    const response = await axios.get(url);
    const integrityValue = `sha384-${cryptoJS.SHA384(response.data).toString(cryptoJS.enc.Base64)}`;
    return [url, integrityValue];
  }));

  // 将结果写入本地配置文件
  fs.writeFileSync('./cdn-integrity-config.json', JSON.stringify({
    list: { css: icss, js: ijs }
  }, null, 2));
}

generateIntegrityConfig().catch(err => {
  console.error('生成CDN哈希失败:', err);
  process.exit(1);
});
  1. 修改package.json的构建脚本,添加前置执行步骤:
{
  "scripts": {
    "prebuild": "node generate-cdn-integrity.js",
    "build": "vue-cli-service build"
  }
}
  1. 在vue.config.js中读取预生成的配置:
const cdnIntegrityConfig = require('./cdn-integrity-config.json');
const cdnConfig = { use: true };

module.exports = defineConfig({
  integrity: true,
  pages: {
    index: {
      entry: 'src/main.ts',
      template: 'public/index.html',
      filename: 'index.html',
      CDN: cdnConfig.use ? cdnIntegrityConfig.list : null
    }
  }
});

三、其他方案的可行性分析

  • 修改Vue/Webpack配置读取逻辑:不现实,vue-cli的配置加载逻辑是同步固化的,修改源码需要维护自定义版本,成本极高,不推荐。
  • 使用deasync/sync-kit转axios为同步:这类工具通过阻塞事件循环实现同步,会导致构建过程卡顿,且依赖Node.js内部API,版本兼容性差,仅适合临时测试场景,不建议生产环境使用。

内容的提问来源于stack exchange,提问作者饕餮饗食

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 02:01:17