diff --git a/src/index.html b/index.html similarity index 93% rename from src/index.html rename to index.html index fdac4ce..044aac3 100644 --- a/src/index.html +++ b/index.html @@ -15,5 +15,6 @@
+ diff --git a/package.json b/package.json index ba1c94e..03d4be0 100644 --- a/package.json +++ b/package.json @@ -2,16 +2,18 @@ "name": "romajs", "version": "1.2.0", "description": "Roma: a TEI customization tool in React+Redux", + "type": "module", "main": "index.js", "scripts": { "test": "npm run eslint && mocha --recursive --require babel-core/register --require ./test/setup.js", "test:nolint": "mocha --recursive --require babel-core/register --require ./test/setup.js", "test:watch": "npm test -- --watch", "test:single": "eslint $SCRIPT && mocha --require babel-core/register --require ./test/setup.js $SCRIPT", + "testw:single": "eslint %SCRIPT% && mocha --require babel-core/register --require ./test/setup.js %SCRIPT%", "echo": "echo", - "start": "node server.js", - "build": "rimraf ./dist && npm run test && cross-env NODE_ENV=\"production\" webpack", - "lint-break-on-errors": "eslint ./source/js ./webpack.config.js -f table --ext .js --ext .jsx", + "start": "vite", + "build": "rimraf ./dist && npm run test && cross-env NODE_ENV=\"production\" vite build", + "lint-break-on-errors": "eslint ./source/js ./vite.config.js -f table --ext .js --ext .jsx", "eslint": "eslint src test" }, "repository": { @@ -52,7 +54,6 @@ "axios": "^1.2.2", "babel-core": "^6.26.3", "babel-eslint": "^7.2.3", - "babel-loader": "^7.1.5", "babel-polyfill": "^6.26.0", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", @@ -60,26 +61,19 @@ "brace": "^0.11.1", "connected-react-router": "^6.5.2", "cross-env": "^5.2.0", - "css-loader": "^3.2.0", "dotenv": "^16.0.3", - "es6-promise": "^4.2.5", "eslint": "^4.19.1", - "eslint-loader": "^1.9.0", "eslint-plugin-react": "^7.11.1", "expect": "^1.20.2", "express": "^4.16.3", - "extract-text-webpack-plugin": "^3.0.0", - "file-loader": "^1.1.11", "file-saver": "^1.3.8", "form-data": "^2.3.2", - "html-webpack-plugin": "^2.30.1", "linkedom": "0.14.21", "localforage": "^1.10.0", "mocha": "^6.2.0", - "node-sass": "^7.0.3", - "react": "^16.9.0", + "react": "^18.3.1", "react-ace": "^7.0.4", - "react-dom": "^16.9.0", + "react-dom": "^18.3.1", "react-redux": "^7.1.1", "react-resize-detector": "^4.0.5", "react-router": "^5.0.1", @@ -90,15 +84,12 @@ "redux-persist": "^6.0.0", "redux-thunk": "^2.3.0", "rimraf": "^2.6.2", - "sass-loader": "^6.0.7", - "style-loader": "^0.18.2", - "url-loader": "^0.6.2", - "webpack": "^3.12.0", - "webpack-dev-middleware": "^1.12.0", - "webpack-hot-middleware": "^2.23.1", "xmldom": "^0.6.0" }, "dependencies": { - "react-blockly": "^8.1.1" + "@vitejs/plugin-react": "^4.3.2", + "react-blockly": "^8.1.1", + "sass": "^1.81.0", + "vite": "^5.4.11" } } diff --git a/server.js b/server.js index e1ac2b2..689cc47 100644 --- a/server.js +++ b/server.js @@ -1,19 +1,53 @@ -const path = require('path') -const webpack = require('webpack') +import path from 'path' +import fs from 'fs' +import { fileURLToPath } from 'url' +import express from 'express' +import { createServer as createViteServer } from 'vite' +/* const webpack = require('webpack') const webpackDevMiddleware = require('webpack-dev-middleware') const webpackHotMiddleware = require('webpack-hot-middleware') -const config = require('./webpack.config') +const config = require('./webpack.config') */ +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) const distDir = path.join(__dirname, 'dist') const htmlFile = path.join(distDir, 'index.html') const isDevelopment = process.env.NODE_ENV !== 'production' -const express = require('express') const app = express() const port = 3000 app.use('/fakeData', express.static('test/fakeData')) -if (isDevelopment) { +async function startServer() { + /* if (isDevelopment) { */ + const vite = await createViteServer({ + server: { middlewareMode: 'html' } + }); + app.use(vite.middlewares); + + app.get('*', async (req, res, next) => { + console.log("H") + try { + const url = req.originalUrl; + let template = fs.readFileSync( + path.resolve(__dirname, 'index.html'), + 'utf-8', + ) + const { render } = await vite.ssrLoadModule('/src/entry-server.js'); + const appHtml = await render(url); + const html = template.replace(``, appHtml); + res.status(200).set({ 'Content-Type': 'text/html' }).end(html); + } catch (e) { + vite.ssrFixStacktrace(e); + next(e); + } + }); + /* } else { + app.use(express.static(distDir)); + app.get('*', (req, res) => {console.log("Here"); res.sendFile(path.join(distDir, 'index.html'))}); + } */ + +/* if (isDevelopment) { config.devtool = 'inline-source-map' config.entry.push('webpack-hot-middleware/client') config.plugins.push(new webpack.HotModuleReplacementPlugin()) @@ -30,13 +64,16 @@ if (isDevelopment) { } else { app.use(express.static(distDir)) app.get('*', (req, res) => res.sendFile(path.join(distDir, 'index.html'))) -} +} */ -app.listen(port, function(error) { - if (error) { - console.error(error) - } else { - console.info("==> 🌎 Listening on port %s. Open up http://localhost:%s/ in your browser.", port, port) - } -}) + app.listen(port, function(error) { + if (error) { + console.error(error) + } else { + console.info("==> 🌎 Listening on port %s. Open up http://localhost:%s/ in your browser.", port, port) + } + }); +} + +startServer(); diff --git a/src/index.js b/src/index.js index 5fd3a20..6dbce10 100644 --- a/src/index.js +++ b/src/index.js @@ -2,7 +2,8 @@ import './scss/romajs.scss' import 'babel-polyfill' import React from 'react' -import { render } from 'react-dom' +/* import ReactDOM from 'react-dom/client' */ +import { createRoot } from 'react-dom/client' import { Provider } from 'react-redux' import thunkMiddleware from 'redux-thunk' import { createStore, applyMiddleware } from 'redux' @@ -12,15 +13,17 @@ import createHistory from 'history/createBrowserHistory' import { persistStore, persistCombineReducers } from 'redux-persist' /* import storage from 'redux-persist/es/storage' */ import localForage from './localForageConfig' -import { PersistGate } from 'redux-persist/es/integration/react' +import { PersistGate } from 'redux-persist/integration/react' import reducers from './reducers' import App from './components/App' -if (module.hot) { - module.hot.accept() -} +/* if (import.meta.hot) { + import.meta.hot.accept() +} */ const romajsElement = document.getElementById('romajs') +/* const root = ReactDOM.createRoot(romajsElement); */ + const basename = romajsElement.getAttribute('data-basename') const history = createHistory({ basename }) @@ -58,7 +61,8 @@ if (window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) { const persistor = persistStore(store) -render( +const root = createRoot(romajsElement) +root.render( @@ -66,5 +70,4 @@ render( , - romajsElement ) diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..8bf3886 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,52 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; +import path, { dirname } from 'path'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +export default defineConfig({ + plugins: [react()], + resolve: { + alias: { + '@': path.resolve(__dirname, 'src'), + }, + }, + css: { + modules: { + generateScopedName: '[local]', + }, + }, + build: { + minify: true, + outDir: 'dist', + rollupOptions: { + input: { + main: path.resolve(__dirname, './index.html'), + }, + output: { + entryFileNames: 'romajs.js', + assetFileNames: (assetInfo) => { + if (assetInfo.name === "main.css") { + return "romajs.css" + } + return assetInfo.name + } + } + }, + }, + server: { + port: 3000, + open: true, + }, + esbuild: { + loader: 'jsx', + include: /src\/.*\.js$/, + exclude: [], + }, + publicDir: 'assets', + define: { + 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) + } +}); diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 index 734ac96..0000000 --- a/webpack.config.js +++ /dev/null @@ -1,103 +0,0 @@ -let path = require('path'), - glob = require('glob'), - webpack = require('webpack'), - HtmlWebpackPlugin = require('html-webpack-plugin') - -let DIST_DIR = path.join(__dirname, 'dist'), - CLIENT_DIR = path.join(__dirname, 'src') - -const isDevelopment = process.env.NODE_ENV !== 'production' - -const publicPath = isDevelopment ? '/' : '' - -module.exports = { - context: CLIENT_DIR, - - entry: ['./index'], - - output: { - path: DIST_DIR, - publicPath, - filename: 'romajs_[hash].js' - }, - - plugins: [ - new webpack.EnvironmentPlugin(), - new HtmlWebpackPlugin({ - template: 'index.html', - inject: 'body', - filename: 'index.html', - favicon: '../assets/favicon.ico', - }), - ], - - module: { - - rules: [ - { - test: /\.jsx?$/, - exclude: /node_modules/, - use: ['babel-loader', 'eslint-loader'] - }, - { - test: /\.css$/, - exclude: /node_modules/, - use: [ - { - loader: 'style-loader', - }, - { - loader: 'css-loader', - options: { - modules: { - localIdentName: '[local]' - } - } - } - ] - }, - { - test: /\.scss$/, - use: [ - { - loader: 'style-loader' - }, - { - loader: 'css-loader', - options: { - importLoaders: 2, - modules: { - localIdentName: '[local]' - } - } - }, - { - loader: 'sass-loader', - options: { - outputStyle: 'expanded', - sourceMap: true, - sourceMapContents: true, - includePaths: glob.sync('node_modules').map((d) => path.join(__dirname, d)), - } - } - ] - }, - { - test: /\.(png|jpg|ttf|eot)$/, - exclude: /node_modules/, - use: [ - { - loader: 'url-loader', - options: {limit: 10000} - } - ] - } - ] - }, - - resolve: { - modules: ['node_modules', 'vendor'], - extensions: ['.js', '.json', '.css'] - } - -}