This commit is contained in:
黄心宇 2023-12-29 16:43:14 +08:00
parent ad20dcf8ea
commit c3e0adfb9a
18 changed files with 4842 additions and 867 deletions

View File

@ -1,27 +1,28 @@
{
"presets": [
"env",
"react",
"stage-2",
"es2015"
// 移除 "es2015" 预设,因为它已经被 "env" 预设覆盖
["@babel/preset-env" ],
"@babel/preset-react" // 使用新的插件命名
],
"plugins": [["antd", {
"libraryDirectory": "lib",
"libraryName": "antd"
}],[
"transform-imports",
{
"libraryName": "antd",
"libraryDirectory": "lib",
"camel2KebabCase": false
}
],[
"transform-runtime",
{
"helpers": false,
"polyfill": false,
"regenerator": true,
"moduleName": "babel-runtime"
}
],["transform-decorators-legacy"], ["syntax-dynamic-import"], ["transform-class-properties"]]
"plugins": [
["import", { "libraryName": "antd", "libraryDirectory": "lib"}],
// 使用新的插件命名
["@babel/plugin-transform-runtime", {
"corejs": 3,
"helpers": true,
"regenerator": true,
"useESModules": false
}],
["@babel/plugin-proposal-decorators", {
"legacy": true
}],
["@babel/plugin-syntax-dynamic-import"],
["@babel/plugin-transform-class-properties"], // 使用新的插件命名
"@babel/plugin-syntax-import-meta",
"@babel/plugin-proposal-json-strings",
"@babel/plugin-proposal-function-sent",
"@babel/plugin-proposal-export-namespace-from",
"@babel/plugin-proposal-numeric-separator",
"@babel/plugin-proposal-throw-expressions"
]
}

View File

@ -8,4 +8,4 @@ export default [
exact: true,
component: Detail,
},
];
];

View File

@ -273,12 +273,11 @@ module.exports = {
reactPath:'react.production.min.js',
}),
new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
// Add module names to factory functions so they appear in browser profiler.
new webpack.NamedModulesPlugin(),
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'development') { ... }. See `./env.js`.
new webpack.DefinePlugin(env.stringified),
new webpack.DefinePlugin({ ...env.stringified, __SERVER__: 'false',__CLIENT__: 'true' }),
// This is necessary to emit hot updates (currently CSS only):
new webpack.HotModuleReplacementPlugin(),
// Watcher doesn't work well if you mistype casing in a path so we use

View File

@ -16,8 +16,9 @@ const TerserWebpackPlugin = require('terser-webpack-plugin');
const paths = require("./paths");
const getClientEnvironment = require("./env");
let publicPath = "/react/build/";
let publicPath = "/build/";
const publicUrl = publicPath.slice(0, -1);
// const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== "false";
const shouldUseSourceMap = process.env.NODE_ENV !== "production";
const env = getClientEnvironment(publicPath,'production.min');
@ -294,12 +295,12 @@ module.exports = {
minifyURLs: true,
},
}),
new webpack.DefinePlugin({ ...env.stringified, __SERVER__: 'false',__CLIENT__: 'true' }),
new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
// It is absolutely essential that NODE_ENV was set to production here.
// Otherwise React will be compiled in the very slow development mode.
new webpack.DefinePlugin(env.stringified),
new MiniCssExtractPlugin({
filename: "static/css/[name].[contenthash:8].css",

View File

@ -18,8 +18,8 @@ const getClientEnvironment = require("./env");
let publicPath = "/react/buildserver/";
// const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== "false";
const shouldUseSourceMap = true;
const env = getClientEnvironment(publicPath,'production.min');
// const nodeExternals = require("webpack-node-externals");
const env = getClientEnvironment(publicPath,'development');
const nodeExternals = require("webpack-node-externals");
const serverConfig = {
target:"node", //由于输出代码的运行环境是node源码中依赖的node原生模块没必要打包进去为了不把nodejs内置模块打包进输出文件中例如 fs net模块等
@ -29,7 +29,43 @@ const serverConfig = {
filename:"bundle.js",
path: path.resolve(__dirname,"../buildserver")
},
// externals:[nodeExternals()], //为了不把node_modules目录下的第三方模块打包进输出文件中,因为nodejs默认会去node_modules目录下去寻找和使用第三方模块。
externals: [
nodeExternals(), // 忽略 Node.js 核心模块
// 自定义的外部模块
{ 'alex': 'Alex', "react": "React", "react-dom": "ReactDOM" }
],
resolve: {
// This allows you to set a fallback for where Webpack should look for modules.
// We placed these paths second because we want `node_modules` to "win"
// if there are any conflicts. This matches Node resolution mechanism.
// https://github.com/facebookincubator/create-react-app/issues/253
modules: ["node_modules", paths.appNodeModules].concat(
// It is guaranteed to exist because we tweak it in `env.js`
process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
),
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
// https://github.com/facebookincubator/create-react-app/issues/290
// `web` extension prefixes have been added for better support
// for React Native Web.
extensions: [".web.js", ".mjs", ".js", ".json", ".web.jsx", ".jsx"],
alias: {
educoder: __dirname + "/../src/common/educoder.js",
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
"react-native": "react-native-web",
},
plugins: [
// Prevents users from importing files from outside of src/ (or node_modules/).
// This often causes confusion because we only process files within src/ with babel.
// To fix this, we prevent you from importing files out of src/ -- if you'd like to,
// please link the files into your node_modules/ and let module-resolution kick in.
// Make sure your source files are compiled, as they will not be processed in any way.
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
// ["transform-remove-console"]
],
},
module: {
strictExportPresence: true,
rules: [
@ -66,20 +102,23 @@ const serverConfig = {
test: /\.(js|jsx|mjs)$/,
include: [paths.appSrc, paths.serverSrc],
exclude: /node_modules/,
loader: require.resolve("babel-loader"),
loader: "babel-loader",
options: {
compact: true,
plugins: [
[
"import",
{
libraryName: "antd",
libraryDirectory: "es",
style: true,
},
],
cacheDirectory: true,
presets: [
require.resolve('@babel/preset-env'),
require.resolve('@babel/preset-react'),
],
},
plugins: [
require.resolve('@babel/plugin-transform-async-to-generator'),
require.resolve('@babel/plugin-syntax-dynamic-import'),
require.resolve('@babel/plugin-proposal-class-properties'),
require.resolve('@babel/plugin-proposal-export-default-from'),
require.resolve('@babel/plugin-transform-runtime'),
require.resolve('@babel/plugin-transform-modules-commonjs'),
require.resolve('babel-plugin-dynamic-import-webpack'),
]
}
},
{
test: /\.css$/,
@ -183,80 +222,14 @@ const serverConfig = {
],
},
plugins: [
// Makes some environment variables available in index.html.
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
// In production, it will be an empty string unless you specify "homepage"
// in `package.json`, in which case it will be the pathname of that URL.
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin({
inject: false,
template: paths.appHtml,
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
}),
new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
// It is absolutely essential that NODE_ENV was set to production here.
// Otherwise React will be compiled in the very slow development mode.
new webpack.DefinePlugin(env.stringified),
new webpack.DefinePlugin({ ...env.stringified, __SERVER__: 'true',__CLIENT__: 'false' }),
new MiniCssExtractPlugin({
filename: "static/css/[name].[contenthash:8].css",
chunkFilename: "static/css/[name].[contenthash:8].chunk.css",
}),
// Generate a manifest file which contains a mapping of all asset filenames
// to their corresponding output file so that tools can pick it up without
// having to parse `index.html`.
new ManifestPlugin({
fileName: "asset-manifest.json",
}),
// Generate a service worker script that will precache, and keep up to date,
// the HTML & assets that are part of the Webpack build.
// new SWPrecacheWebpackPlugin({
// // By default, a cache-busting query parameter is appended to requests
// // used to populate the caches, to ensure the responses are fresh.
// // If a URL is already hashed by Webpack, then there is no concern
// // about it being stale, and the cache-busting can be skipped.
// dontCacheBustUrlsMatching: /\.\w{8}\./,
// filename: "service-worker.js",
// logger(message) {
// if (message.indexOf("Total precache size is") === 0) {
// // This message occurs for every build and is a bit too noisy.
// return;
// }
// if (message.indexOf("Skipping static resource") === 0) {
// // This message obscures real errors so we ignore it.
// // https://github.com/facebookincubator/create-react-app/issues/2612
// return;
// }
// // console.log(message);
// },
// minify: true,
// // For unknown URLs, fallback to the index page
// navigateFallback: publicUrl + "/index.html",
// // Ignores URLs starting from /__ (useful for Firebase):
// // https://github.com/facebookincubator/create-react-app/issues/2237#issuecomment-302693219
// navigateFallbackWhitelist: [/^(?!\/__).*/],
// // Don't precache sourcemaps (they're large) and build asset manifest:f
// staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/],
// }),
// Moment.js is an extremely popular library that bundles large locale files
// by default due to how Webpack interprets its code. This is a practical
// solution that requires the user to opt into importing specific locales.
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
// You can remove this if you don't use Moment.js:
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new MonacoWebpackPlugin({
features: ["coreCommands", "find"],

5376
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,24 @@
"version": "3.1.0",
"private": true,
"dependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-decorators": "^7.0.0",
"@babel/plugin-proposal-export-default-from": "^7.23.3",
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
"@babel/plugin-proposal-function-sent": "^7.0.0",
"@babel/plugin-proposal-json-strings": "^7.0.0",
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/plugin-transform-async-to-generator": "^7.0.0",
"@babel/plugin-transform-runtime": "^7.23.6",
"@babel/preset-env": "^7.23.6",
"@babel/preset-react": "^7.23.3",
"@babel/preset-stage-2": "^7.8.3",
"@babel/runtime": "^7.0.0-beta.46",
"@babel/runtime-corejs3": "^7.23.6",
"@monaco-editor/react": "^2.3.0",
"@novnc/novnc": "^1.1.0",
"@wangeditor/editor": "^5.1.23",
@ -13,7 +31,10 @@
"array-flatten": "^2.1.2",
"autoprefixer": "7.1.6",
"axios": "^0.24.0",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^23.4.2",
"babel-plugin-antd": "^0.5.1",
"babel-plugin-dynamic-import-webpack": "^1.1.0",
"bizcharts": "^3.5.8",
"bundle-loader": "^0.5.6",
"chalk": "1.1.3",
@ -22,6 +43,7 @@
"code-prettify": "^0.1.0",
"codemirror": "^5.64.0",
"connected-react-router": "4.4.1",
"core-js": "^3.34.0",
"dompurify": "^2.3.3",
"dotenv": "4.0.0",
"dotenv-expand": "4.2.0",
@ -31,13 +53,16 @@
"express": "^4.18.2",
"flv.js": "^1.5.0",
"fs-extra": "3.0.1",
"http-proxy-middleware": "^2.0.6",
"i18next": "^23.4.5",
"immutability-helper": "^2.6.6",
"install": "^0.12.2",
"intersection-observer": "^0.12.2",
"isomorphic-style-loader": "^5.3.2",
"jest": "20.0.4",
"js-base64": "^2.5.2",
"js2wordcloud": "^1.1.12",
"jsdom": "^15.2.1",
"katex": "^0.11.1",
"less": "^3.13.1",
"localforage": "^1.10.0",
@ -117,7 +142,7 @@
},
"scripts": {
"start": "node --max_old_space_size=15360 scripts/start.js",
"build": "cross-env NODE_ENV=production node --max_old_space_size=15360 scripts/build.js",
"build": "cross-env NODE_ENV=production babel-node --max_old_space_size=15360 scripts/build.js",
"build:dll": "webpack --config=./config/webpack.dll.config.js",
"test-build": "cross-env NODE_ENV=testBuild node --max_old_space_size=15360 scripts/build.js",
"pre-build": "NODE_ENV=preBuild node --max_old_space_size=15360 scripts/build.js",
@ -125,8 +150,9 @@
"ana": "webpack-bundle-analyzer ./stats.json",
"analyze": "npm run build -- --stats && webpack-bundle-analyzer build/bundle-stats.json",
"analyz": "NODE_ENV=production npm_config_report=true npm run build",
"server": "cross-env NODE_ENV=production nodemon --exec babel-node \"./buildserver/bundle.js\" --watch config --watch server",
"build:server": "cross-env NODE_ENV=production webpack --config config/webpack.server.js"
"dev": "npm-run-all --parallel dev:**",
"dev:server": "cross-env NODE_ENV=production nodemon --exec babel-node \"./buildserver/bundle.js\" --watch config --watch server",
"dev:build:server": "cross-env NODE_ENV=production webpack --config config/webpack.server.js --watch"
},
"jest": {
"collectCoverageFrom": [
@ -168,25 +194,15 @@
"proxy": "http://172.20.32.202:4000",
"port": "3007",
"devDependencies": {
"@babel/runtime": "7.0.0-beta.51",
"babel-cli": "^6.26.0",
"babel-core": "^6.26.3",
"babel-eslint": "7.2.3",
"babel-jest": "20.0.3",
"babel-loader": "7.1.2",
"@babel/core": "^7.23.6",
"@babel/node": "^7.0.0",
"@babel/plugin-proposal-decorators": "^7.0.0",
"@babel/polyfill": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.3.0",
"babel-plugin-import": "^1.13.0",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.5",
"babel-plugin-transform-imports": "^2.0.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.7.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-react-app": "^3.1.1",
"babel-preset-stage-2": "^6.24.1",
"babel-runtime": "6.26.0",
"babel-upgrade": "^1.0.1",
"case-sensitive-paths-webpack-plugin": "2.1.1",
"compression-webpack-plugin": "^1.1.12",
"concat": "^1.0.3",
@ -205,6 +221,7 @@
"less-loader": "^4.1.0",
"mockjs": "^1.1.0",
"node-sass": "^4.14.1",
"npm-run-all": "^4.1.5",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"postcss-loader": "2.0.8",
"purgecss": "^2.1.2",

View File

@ -1,8 +1,23 @@
import express from "express";
import "./window"
import {render} from "./render";
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
app.use(express.static('build'))
app.use('/build', express.static('build'));
const targetServer = 'https://www.gitlink.org.cn'; // Java 服务器的地址
const options = {
target: targetServer,
changeOrigin: true, // 允许在请求头中更改主机
};
// 设置代理
app.use('/api', (req, res) => {
const proxy = createProxyMiddleware(options);
proxy(req, res);
});
app.get('*',function (req,res) {
render(req,res);

View File

@ -16,14 +16,13 @@ export const render = (req,res)=>{
<Provider>
<StaticRouter location={req.path} context={context}>{renderRoutes(Routes)}</StaticRouter>
</Provider>
));
))
let html=fs.readFileSync(path.join(path.resolve(__dirname,'../build'),'index.html'),'utf-8');
let html=fs.readFileSync(path.join(path.resolve('./build'),'index.html'),'utf-8');
const prepHTML=(data,rootString)=>{
data=data.replace('<div id="root" class="page -layout-v -fit widthunit"></div>',`<div id="root" class="page -layout-v -fit widthunit">${rootString}</div>`);
return data;
}
res.send(prepHTML(html, content))
}

14
server/window.js Normal file
View File

@ -0,0 +1,14 @@
const jsdom = require("jsdom");
import fs from 'fs'
import path from 'path';
const { JSDOM } = jsdom;
const html=fs.readFileSync(path.join(path.resolve('./build'),'index.html'),'utf-8');
const dom = new JSDOM(html);
const { window } = dom;
global.window = window;
global.document = window.document;
global.navigator = window.navigator;

View File

@ -8,7 +8,7 @@ import {
} from 'react-router-dom';
import axios from 'axios';
import LoginDialog from './modules/login/LoginDialog';
import 'babel-polyfill';
// import 'babel-polyfill';
import Loading from './Loading';
import Loadable from 'react-loadable';

View File

@ -3,9 +3,9 @@ import md5 from 'md5';
import {Input} from "antd";
const { Search } = Input;
const $ = window.$;
const isDev = window.location.port == 3007;
const isdev2= window.location.hostname ==='www.educoder.net'
// const $ = window.$;
const isDev = __SERVER__ ? false : window.location.port == 3007;
const isdev2= __SERVER__ ? false : window.location.hostname ==='www.educoder.net'
export const TEST_HOST = "https://testforgeplus.trustie.net/"
export function getImageUrl(path) {
// https://www.educoder.net
@ -40,7 +40,7 @@ export function getImageUrlAbsolute(path) {
// const local = 'http://localhost:3000'
path && !path.startsWith('/') && !path.startsWith('http') && (path = '/'.concat(path));
const local = 'https://testforgeplus.trustie.net';
const prod = window.location.origin;
const prod = __SERVER__ ? local : window.location.origin;
if (isDev) {
return `${local}${path}`
}else{
@ -198,7 +198,7 @@ function railsgettimess(proxy) {
}
}})
window.setTimeout(function () {
setTimeout(function () {
checkSubmitFlgs=false;
}, 2500);
}

View File

@ -1,4 +1,4 @@
const queryString = {
export const queryString = {
stringify: function(params) {
let paramsUrl = '';
for (let key in params) {
@ -47,5 +47,4 @@ const queryString = {
./node_modules/_query-string@6.1.0@query-string/index.js:8
Read more here: http://bit.ly/2tRViJ9
*/
module.exports = queryString
*/

View File

@ -9,7 +9,7 @@
import './index.scss';
import React, { useState } from 'react';
import { Form, Button, Input } from 'antd';
import QuillForEditor from '../../quillForEditor';
// import QuillForEditor from '../../quillForEditor';
const FormItem = Form.Item;
function CommentForm(props) {
@ -116,7 +116,7 @@ function CommentForm(props) {
)
}
<QuillForEditor
{/* <QuillForEditor
imgAttrs={{ width: '60px', height: '30px' }}
wrapStyle={{
height: showQuill ? 'auto' : '0px',
@ -131,7 +131,7 @@ function CommentForm(props) {
value={ctx}
showUploadImage={handleShowImage}
onContentChange={handleContentChange}
/>
/> */}
</FormItem>
<FormItem style={{ textAlign: 'right', display: showQuill ? 'block' : 'none' }}>
<Button onClick={handleCancle}>取消</Button>

View File

@ -11,7 +11,7 @@ export {
} from './UrlTool';
export { setmiyah as setmiyah } from './Component';
export { default as queryString } from './UrlTool2';
export { queryString } from './UrlTool2';
export { SnackbarHOC as SnackbarHOC } from './SnackbarHOC';
@ -68,7 +68,7 @@ export { default as ActionBtn } from './course/ActionBtn'
export { default as MarkdownToHtml } from './components/markdown/MarkdownToHtml'
export { default as QuillForEditor } from './quillForEditor'
// export { default as QuillForEditor } from './quillForEditor'
export { default as Clappr } from './components/media/Clappr'
export { default as AliyunUploader } from './components/media/AliyunUploader'

View File

@ -1,7 +1,7 @@
import './index.scss'
import 'quill/dist/quill.core.css' // 核心样式
import 'quill/dist/quill.snow.css' // 有工具栏
import 'quill/dist/quill.bubble.css' // 无工具栏
// import 'quill/dist/quill.core.css' // 核心样式
// import 'quill/dist/quill.snow.css' // 有工具栏
// import 'quill/dist/quill.bubble.css' // 无工具栏
import './font.css'
import React, { useState, useRef, useEffect } from 'react'
import Quill from 'quill'

View File

@ -10,8 +10,6 @@ import { Base64 } from 'js-base64';
import '../css/index.scss'
import './list.scss';
import { ImageLayerOfCommentHOC } from "../../modules/page/layers/ImageLayerOfCommentHOC";
import Loadable from 'react-loadable';
import Loading from '../../Loading';
@ -879,7 +877,4 @@ class Detail extends Component {
}
}
export default withRouter(ImageLayerOfCommentHOC({
imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget",
parentSelector: ".newContainer",
})(Detail));
export default withRouter(Detail);

View File

@ -6,9 +6,9 @@
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-02 16:33:35
*/
import 'quill/dist/quill.core.css';
import 'quill/dist/quill.bubble.css';
import 'quill/dist/quill.snow.css';
// import 'quill/dist/quill.core.css';
// import 'quill/dist/quill.bubble.css';
// import 'quill/dist/quill.snow.css';
import './index.scss';
import React, { useState, useImperativeHandle, useRef, useEffect } from 'react';
import { Form, Input, InputNumber, Button, Select } from 'antd';