方式1

前端 开发完毕后,打包后,将资源文件上传至CDN。

后端 直接返回前端的 index.html

  1. // const path = require("path");
  2. const isProd = process.env.NODE_ENV === 'production'; // 是否生产环境
  3. const cdn = {
  4. css: ['https://unpkg.com/vant@3.4.2/lib/index.css'],
  5. js: [
  6. 'https://unpkg.com/vue@3.2.27/dist/vue.global.js', // vuejs
  7. 'https://unpkg.com/vue-router@4.0.12/dist/vue-router.global.js',
  8. 'https://unpkg.com/vuex@4.0.2/dist/vuex.global.js',
  9. 'https://unpkg.com/vant@3.4.2/lib/vant.min.js',
  10. 'https://unpkg.com/axios@0.25.0/dist/axios.min.js',
  11. ],
  12. };
  13. const myCDN = 'https://cdn.q123q.cc/fed/v/gCigJu';
  14. module.exports = {
  15. publicPath: isProd ? myCDN : '/',
  16. assetsDir: 'assets',
  17. devServer: {
  18. port: 5001,
  19. proxy: 'http://localhost:3001',
  20. },
  21. configureWebpack: {
  22. externals: isProd
  23. ? {
  24. vue: 'Vue',
  25. 'vue-router': 'VueRouter',
  26. vuex: 'Vuex',
  27. vant: 'vant',
  28. axios: 'axios',
  29. }
  30. : {},
  31. },
  32. chainWebpack: config => {
  33. config.plugin('html').tap(args => {
  34. args[0].title = '好词好句';
  35. // cdn
  36. args[0].cdn = isProd ? cdn : { css: [], js: [] };
  37. return args;
  38. });
  39. },
  40. };
const OSS = require('ali-oss');
const path = require('path');
const fs = require('fs');
const rimraf = require('rimraf');
const ossConfig = require('./ossConfig');

const oss路径 = '/fed/v/gCigJu';

const 本地要上传的目录 = path.join(__dirname, 'dist');

const 过滤的文件 = ['index.html', '.DS_Store', '.map'];

new (class {
  constructor() {
    this.client = new OSS({
      // yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
      region: 'oss-cn-chengdu',
      bucket: 'qinsjs',
      // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
      accessKeyId: '你的 accessKeyId',
      accessKeySecret: '你的 accessKeySecret',
      timeout: 180 * 1000,
      ...ossConfig,
    });
  }

  /**
   * 删除 oss 目录
   */
  async deloss() {
    return await this.client.delete(oss路径);
  }

  /**
   * 上传
   */
  async uposs(osspath, localpath) {
    console.log(localpath, '==>', osspath);
    const res = await this.client.put(osspath, localpath);
    console.log(osspath, '-->', res?.res?.status);
  }

  async upcdn(dir) {
    const files = await fs.promises.readdir(dir);
    for (const f of files) {
      if (过滤的文件.find(过滤规则 => f.includes(过滤规则))) continue;

      const 完整路径 = path.join(dir, f);

      const stat = await fs.promises.stat(完整路径);

      if (stat.isDirectory()) {
        // 递归
        await this.upcdn(完整路径);
      } else {
        // 上传 OSS

        // 去除 本地路径 前缀
        const 上传路径 = 完整路径.replace(本地要上传的目录, '');
        await this.uposs(oss路径 + 上传路径, 完整路径);
      }
    }
  }

  async run() {
    const res = await this.deloss();
    console.log('删除结果 > ', res?.res?.status);
    await this.upcdn(本地要上传的目录);
    await this.after();
  }

  /**
   * 将 index.html 复制到后端方便读取到地方
   */
  async after() {
    const root = path.join(__dirname, '..');
    if (!fs.existsSync(root)) {
      throw new Error(root + ' 不存在!');
    }

    const v = path.join(root, 'src/html');

    rimraf(v, async () => {
      await fs.promises.mkdir(v);
      const distPath = path.join(本地要上传的目录, 'index.html');
      const midwayPath = path.join(v, 'index.html');

      fs.createReadStream(distPath).pipe(fs.createWriteStream(midwayPath));
    });
  }
})().run();