方式1
前端 开发完毕后,打包后,将资源文件上传至CDN。
后端 直接返回前端的 index.html
// const path = require("path");
const isProd = process.env.NODE_ENV === 'production'; // 是否生产环境
const cdn = {
css: ['https://unpkg.com/vant@3.4.2/lib/index.css'],
js: [
'https://unpkg.com/vue@3.2.27/dist/vue.global.js', // vuejs
'https://unpkg.com/vue-router@4.0.12/dist/vue-router.global.js',
'https://unpkg.com/vuex@4.0.2/dist/vuex.global.js',
'https://unpkg.com/vant@3.4.2/lib/vant.min.js',
'https://unpkg.com/axios@0.25.0/dist/axios.min.js',
],
};
const myCDN = 'https://cdn.q123q.cc/fed/v/gCigJu';
module.exports = {
publicPath: isProd ? myCDN : '/',
assetsDir: 'assets',
devServer: {
port: 5001,
proxy: 'http://localhost:3001',
},
configureWebpack: {
externals: isProd
? {
vue: 'Vue',
'vue-router': 'VueRouter',
vuex: 'Vuex',
vant: 'vant',
axios: 'axios',
}
: {},
},
chainWebpack: config => {
config.plugin('html').tap(args => {
args[0].title = '好词好句';
// cdn
args[0].cdn = isProd ? cdn : { css: [], js: [] };
return args;
});
},
};
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();