Commit 9d9d0c72 authored by haiyoucuv's avatar haiyoucuv

new 模板

parent 7e904621
UPLOAD_DIR=TNGD_GAMES/B_Client
\ No newline at end of file
UPLOAD_DIR=db_games/spark/v3
\ No newline at end of file
# .env.production
CDN_DOMAIN=//gamification-sbx.tngdigital.com.my
OSS_REGION=oss-ap-southeast-3
OSS_BUCKET=sbx-gamification-tngd
OSS_ACCESS_KEY_ID=LTAI5tApBGwYWaj6zLmKUaTJ
OSS_ACCESS_SECRET=W3OvCDpbE3ywMaQnTNWzySnhPRK1We
\ No newline at end of file
CDN_DOMAIN=//yun.duiba.com.cn
OSS_REGION=oss-cn-hangzhou
OSS_BUCKET=duiba
OSS_ACCESS_KEY_ID=LTAI5tPUSSxgkEmKPAfVXUQQ
OSS_ACCESS_SECRET=6sk3EDd1BYrXlAUoh8maMuN7hOMkh1
\ No newline at end of file
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="dns-prefetch" href="//yun.duiba.com.cn" />
<link rel="preconnect" href="//embedlog.duiba.com.cn">
<title>活动标题</title>
<script type="text/javascript">
if (localStorage && localStorage.isWebp) {
document
.getElementsByTagName('html')[0]
.setAttribute('duiba-webp', 'true');
}
</script>
<script src="//yun.duiba.com.cn/js-libs/rem/1.1.3/rem.min.js"></script>
<script>
var CFG = CFG || {};
CFG.projectId = location.pathname.split('/')[2] || '1';
function getUrlParam(name) {
var search = window.location.search;
var matched = search
.slice(1)
.match(new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i'));
return search.length ? matched && matched[2] : null;
}
CFG.appID = '${APPID}';
if (!getUrlParam("appID")) {
// alert("【警告】检测到活动url中没有appID参数\n缺少该参数会导致埋点、分享、app信息获取错误。")
}
</script>
<script type="module" crossorigin src="//yun.duiba.com.cn/db_games/spark/v3/1729238505291/assets/index-6Aqtw07R.js"></script>
<link rel="stylesheet" crossorigin href="//yun.duiba.com.cn/db_games/spark/v3/1729238505291/assets/index-B2EZ7m-P.css">
<script type="module">import.meta.url;import("_").catch(()=>1);(async function*(){})().next();if(location.protocol!="file:"){window.__vite_is_modern_browser=true}</script>
<script type="module">!function(){if(window.__vite_is_modern_browser)return;console.warn("vite: loading legacy chunks, syntax error above and the same error below should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}();</script>
</head>
<body>
<div id="root"></div>
<script nomodule>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script>
<script nomodule crossorigin id="vite-legacy-polyfill" src="//yun.duiba.com.cn/db_games/spark/v3/1729238505291/assets/polyfills-legacy-DPMTo3qc.js"></script>
<script nomodule crossorigin id="vite-legacy-entry" data-src="//yun.duiba.com.cn/db_games/spark/v3/1729238505291/assets/index-legacy-BjxNED3H.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script>
</body>
</html>
......@@ -23,8 +23,6 @@ class App extends Component {
async componentDidMount() {
await store.getFrontVariable();
console.log(import.meta.glob("./assets/**/*"));
}
render() {
......
@import "../../res.less";
.homeDemo {}
.homeDemo {
position: absolute;
.homeImg {
position: absolute;
left: 100px;
top: 400px;
width: 200px;
height: 200px;
.webpBg("LoadingPage/loadingIp.png");
}
.svga {
position: absolute;
left: 0;
top: 0;
width: 400px;
height: 400px;
}
}
import React from 'react';
import {observer} from 'mobx-react';
import { observer } from 'mobx-react';
import './HomeDemo.less';
import { SvgaPlayer } from "@spark/svgaplayer";
import svga from "../../assets/LoadingPage/1红色标题.svga";
import png from "../../assets/LoadingPage/loadingIp.png";
@observer
class HomeDemo extends React.Component {
render() {
return <div className="homeDemo">
当前为活动首页
</div>;
}
componentDidMount() {
}
render() {
return <div className="homeDemo">
<div className="homeImg" />
<img src={png} />
当前为活动首页
<SvgaPlayer className="svga" src={svga} />
</div>;
}
}
export default HomeDemo;
......@@ -7,12 +7,7 @@
width: 100%;
height: 100%;
//background: linear-gradient(152deg, #AEE7FF 6%, #F1DEFC 43%, #F3E7FB 73%);
.webpBg("LoadingPage/loadingBg.jpg");
//background-image: url("../../assets/LoadingPage/loadingBg.jpg");
background-size: 750px 1624px;
.loading-ip {
position: absolute;
......
import React from "react";
import {observer} from "mobx-react";
import "./LoadingDemo.less";
// import {preloadAsset} from "../../utils/preload1.3";
import {PAGE_MAP} from "../../utils/constants";
import { observer } from "mobx-react";
import { PAGE_MAP } from "../../utils/constants";
import store from "../../store/store";
import { preload } from "../../utils/preload.ts";
import "./LoadingDemo.less";
@observer
class LoadingDemo extends React.Component {
state = {
curPercentage: 0
}
curPercentage = 0;
intervalId: number = 0;
isEvenLoad = true; // 是否匀速加载进度条
componentDidMount() {
this.preloadAssetInit();
// this.jump();
}
/**
* 资源预加载
*/
preloadAssetInit = async () => {
// const imageList = [];
// preloadAsset(
// imageList,
// 3,
// this.onLoadingProgress,
// ).then(() => {
// // 预加载资源完成
// // 异步加载默认关闭
// // setTimeout(() => {
// // // 异步加载资源开始
// // const asyncImageList = assetList.asyncLoadImg;
// // preloadAsset(asyncImageList, 1)
// // }, 5000);
// });
};
jump = () => {
setTimeout(() => {
store.changePage(PAGE_MAP.HOME_PAGE); // 跳转页面
}, 100);
};
/**
* 资源加载进度回调
* @param {*} progress
*/
onLoadingProgress = (progress) => {
const percentage = Math.floor(progress * 100);
console.log("progress", percentage);
if (this.isEvenLoad) {
this.setEvenProgress(percentage);
} else {
if (percentage == 100) {
this.jump();
}
state = {
curPercentage: 0
}
curPercentage = 0;
intervalId: number = 0;
componentDidMount() {
this.preloadAssetInit();
// this.jump();
}
/**
* 资源预加载
*/
preloadAssetInit = async () => {
const files = import.meta.glob("../../assets/**/*", {
import: "default",
eager: true,
});
const urls = Object.values(files) as string[];
await preload(urls, (progress, loaded, total) => {
const percentage = Math.floor(progress * 100);
this.setEvenProgress(percentage);
});
};
jump = () => {
setTimeout(() => {
store.changePage(PAGE_MAP.HOME_PAGE); // 跳转页面
}, 100);
};
/**
* 以1%匀速加载进度
* @param {*} percentage
*/
setEvenProgress = (percentage) => {
this.intervalId && clearInterval(this.intervalId);
let curPercentage = this.curPercentage;
this.intervalId = setInterval(() => {
if (curPercentage >= percentage) {
clearInterval(this.intervalId);
this.jump();
return;
}
curPercentage += 1;
this.curPercentage = curPercentage;
this.setState({
curPercentage,
});
}, 10);
};
render() {
const { curPercentage } = this.state;
return <div className="loading">
<div className="loading-ip" />
<div className="progressBarBg" />
<div className="progressBar">
<div className="progressBarFill" style={{
transform: `translateX(${curPercentage - 100}%)`
}} />
</div>
<span className="progressTxt">金豆正在路上...... {curPercentage}%</span>
</div>;
}
};
/**
* 以1%匀速加载进度
* @param {*} percentage
*/
setEvenProgress = (percentage) => {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
this.intervalId && clearInterval(this.intervalId);
let curPercentage = this.curPercentage;
// @ts-ignore
this.intervalId = setInterval(() => {
if (curPercentage >= percentage) {
clearInterval(this.intervalId);
this.jump();
return;
}
curPercentage += 1;
this.curPercentage = curPercentage;
this.setState({
curPercentage,
});
}, 10);
};
render() {
const {curPercentage} = this.state;
return <div className="loading">
<div className="loading-ip"/>
<div className="progressBarBg"/>
<div className="progressBar">
<div className="progressBarFill" style={{
transform: `translateX(${curPercentage - 100}%)`
}}/>
</div>
<span className="progressTxt">金豆正在路上...... {curPercentage}%</span>
</div>;
}
}
export default LoadingDemo;
......@@ -9,6 +9,7 @@
background-image: var(--p);
[duiba-webp='true'] & {
--p: url("@{RES_PATH}@{value}@{webp}");
background-image: var(--p);
}
}
......
......@@ -18,8 +18,8 @@ class Store {
Did1NDA0NDc: "sharePage",
myPrize: "myPrize", // TODO 举例子 新宿台奖品页
index: PAGE_MAP.LOADING_PAGE,
}[skinId] || PAGE_MAP.HOME_PAGE;
index: PAGE_MAP.HOME_PAGE,
}[skinId] || PAGE_MAP.LOADING_PAGE;
pageData = {};
......
......@@ -5,29 +5,36 @@
*/
(function () {
let lowAdr = false;
const ua = navigator.userAgent.toLowerCase()
const isAndroid = ua.indexOf('android') > -1 || ua.indexOf('adr') > -1;
if (isAndroid) {
const ver = parseFloat(ua.substr(ua.indexOf('android') + 8, 3));
lowAdr = ver < 4.4;
}
if (lowAdr && localStorage) {
delete localStorage.isWebp;
}
if (localStorage && !localStorage.isWebp) {
const img = new Image()
img.onload = function () {
if (img.width === 1 && !lowAdr) {
localStorage.isWebp = true;
document.getElementsByTagName('html')[0].setAttribute('duiba-webp', 'true')
} else {
localStorage.isWebp = '';
}
let lowAdr = false;
const ua = navigator.userAgent.toLowerCase()
const isAndroid = ua.indexOf('android') > -1 || ua.indexOf('adr') > -1;
if (isAndroid) {
const ver = parseFloat(ua.substr(ua.indexOf('android') + 8, 3));
lowAdr = ver < 4.4;
}
img.onerror = function () {
localStorage.isWebp = ''
if (lowAdr && localStorage) {
delete localStorage.isWebp;
}
img.src = 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEAAwA0JaQAA3AA/vuUAAA='
}
})()
if (localStorage && !localStorage.isWebp) {
const img = new Image()
img.onload = function () {
if (img.width === 1 && !lowAdr) {
localStorage.isWebp = true;
document.getElementsByTagName('html')[0].setAttribute('duiba-webp', 'true')
} else {
localStorage.isWebp = '';
}
}
img.onerror = function () {
localStorage.isWebp = ''
}
img.src = 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEAAwA0JaQAA3AA/vuUAAA='
}
})();
export const webpQuery = "?x-oss-process=image/format,webp";
export function supportWebp() {
return !!localStorage?.isWebp;
}
\ No newline at end of file
import { supportWebp, webpQuery } from "./checkwebp.ts";
export const svgaRegex = (/\.(svga)$/);
export const jpgRegex = (/\.(jpe?g)$/);
export const pngRegex = (/\.(png)$/);
export const webpRegex = (/\.(webp)$/);
export const gifRegex = (/\.(gif)$/);
export const imgRegex = (/\.(png|jpe?g|webp|gif)$/);
const typeRegex = (/\.([^.]+)$/);
const loaders = {
".jpg": loadImg,
".jpeg": loadImg,
".png": loadImg,
".webp": loadImg,
".gif": loadImg,
'.svga': loadSvga,
}
export async function preload(
urls: string[],
onProcess?: (progress: number, loaded: number, total: number) => void,
onComplete?: () => void
) {
const ps = [];
let loaded = 0;
const total = urls.length;
// 获取文件类型
urls.forEach((url) => {
const type = url.match(typeRegex)?.[0];
const loadFunc = loaders[type] || loadUnknown;
const p = loadFunc(url).then(() => {
loaded++;
const progress = loaded / total;
onProcess && onProcess(progress, loaded, total);
if (loaded >= total) {
onComplete && onComplete();
}
});
ps.push(p);
});
}
/**
* 加载一张图片
* @param {string} url 地址
*/
export function loadImg(url: string) {
return new Promise((resolve) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = err => {
console.warn('load', url, err);
resolve(null);
};
img.crossOrigin = 'anonymous';
img.src = url + (supportWebp() ? webpQuery : '');
});
}
export function loadSvga(url: string) {
return Promise.resolve();
}
export function loadUnknown(url: string) {
console.warn(`load unknown: ${url}`);
return Promise.resolve();
}
\ No newline at end of file
/// <reference types="vite/client" />
declare module "*.svga" {
const src: string;
export default src;
}
\ No newline at end of file
......@@ -20,7 +20,8 @@
"noImplicitAny": false,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noFallthroughCasesInSwitch": true
"noFallthroughCasesInSwitch": true,
"types": ["node_modules/@types/node"]
},
"include": ["src"]
"include": ["src"],
}
......@@ -5,91 +5,91 @@ import autoprefixer from "autoprefixer"
import postcsspxtorem from "postcss-pxtorem"
import { viteMockServe } from "vite-plugin-mock";
import DuibaPublish from "./config/DuibaPublish/DuibaPublish.ts";
import dotenv from 'dotenv';
// https://vitejs.dev/config/
export default defineConfig(({mode}) => {
export default defineConfig(({ mode }) => {
dotenv.config({path: [`./config/.env.global`, `./config/.env.${mode}`]});
dotenv.config({ path: [`./config/.env.global`, `./config/.env.${mode}`] });
const {
NODE_ENV,
UPLOAD_DIR, CDN_DOMAIN,
OSS_REGION, OSS_BUCKET,
OSS_ACCESS_KEY_ID, OSS_ACCESS_SECRET,
} = process.env;
const {
NODE_ENV,
UPLOAD_DIR, CDN_DOMAIN,
OSS_REGION, OSS_BUCKET,
OSS_ACCESS_KEY_ID, OSS_ACCESS_SECRET,
} = process.env;
console.log(UPLOAD_DIR, NODE_ENV, CDN_DOMAIN, OSS_REGION, OSS_BUCKET, OSS_ACCESS_KEY_ID, OSS_ACCESS_SECRET)
// console.log(UPLOAD_DIR, NODE_ENV, CDN_DOMAIN, OSS_REGION, OSS_BUCKET, OSS_ACCESS_KEY_ID, OSS_ACCESS_SECRET)
const isDev = NODE_ENV == "development";
const isDev = NODE_ENV == "development";
const versionStamp = Date.now();
const versionStamp = Date.now();
const prodBase = `${CDN_DOMAIN}/${UPLOAD_DIR}/${versionStamp}/`;
const prodBase = `${CDN_DOMAIN}/${UPLOAD_DIR}/${versionStamp}/`;
return {
base: !isDev ? prodBase : "",
server: {
// port: 3001
},
plugins: [
react({
babel: {
plugins: [
["@babel/plugin-proposal-decorators", {legacy: true}],
["@babel/plugin-proposal-class-properties", {loose: true}],
],
return {
base: !isDev ? prodBase : "",
server: {
// port: 3001
open: true,
},
}),
legacy({
targets: ['defaults', 'not IE 11'],
}),
viteMockServe({
// default
mockPath: 'mock',
enable: true,
}),
!isDev && DuibaPublish({
buildVersion: versionStamp,
uploadDir: UPLOAD_DIR,
region: OSS_REGION,
bucket: OSS_BUCKET,
accessKeyId: OSS_ACCESS_KEY_ID,
accessKeySecret: OSS_ACCESS_SECRET,
}),
],
css: {
postcss: {
assetsInclude: [/\.(svga)$/],
plugins: [
autoprefixer({
overrideBrowserslist: [
"Android 4.1",
"iOS 7.1",
"Chrome > 31",
"ff > 31",
"ie >= 8",
"last 10 versions", // 所有主流浏览器最近10版本用
],
grid: true
}),
postcsspxtorem({
rootValue: 100,
// propList: ["*", "!border"], // 除 border 外所有px 转 rem
selectorBlackList: [".noRem-"], // 过滤掉.noRem-开头的class,不进行rem转换
}),
react({
babel: {
plugins: [
["@babel/plugin-proposal-decorators", { legacy: true }],
["@babel/plugin-proposal-class-properties", { loose: true }],
],
},
}),
legacy({
targets: ['defaults', 'not IE 11'],
}),
viteMockServe({
// default
mockPath: 'mock',
enable: true,
}),
!isDev && DuibaPublish({
buildVersion: versionStamp,
uploadDir: UPLOAD_DIR,
region: OSS_REGION,
bucket: OSS_BUCKET,
accessKeyId: OSS_ACCESS_KEY_ID,
accessKeySecret: OSS_ACCESS_SECRET,
}),
],
},
preprocessorOptions: {
less: {
javascriptEnabled: true,
},
},
modules: {
localsConvention: 'camelCase'
}
css: {
postcss: {
plugins: [
autoprefixer({
overrideBrowserslist: [
"Android 4.1",
"iOS 7.1",
"Chrome > 31",
"ff > 31",
"ie >= 8",
"last 10 versions", // 所有主流浏览器最近10版本用
],
grid: true
}),
postcsspxtorem({
rootValue: 100,
propList: ["*", "!border"], // 除 border 外所有px 转 rem
selectorBlackList: [".noRem-"], // 过滤掉.noRem-开头的class,不进行rem转换
}),
],
},
preprocessorOptions: {
less: {
javascriptEnabled: true,
},
},
modules: {
localsConvention: 'camelCase'
}
}
}
}
}
)
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment