convert project to webpack, upgrade deps and make it run again

This commit is contained in:
Linus Miller 2020-08-27 21:53:37 +02:00
parent 3a3072681d
commit 7e93845bb1
23 changed files with 8186 additions and 241 deletions

View File

@ -1,2 +1,2 @@
/build
/dist
/dump

107
.gitignore vendored
View File

@ -1,42 +1,121 @@
.tern-port
/dist
/dump
/uploads
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# NPM Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
# Dependency directories
node_modules/
jspm_packages/
npm-debug.log
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# Bower dependency directory
bower_components
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
/build
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
/dump
/public
/server/uploads
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

27
babel.config.js Normal file
View File

@ -0,0 +1,27 @@
'use strict'
module.exports = {
plugins: [['transform-react-jsx', { pragma: 'h' }]],
presets: [['@babel/env', { targets: { node: 12 }, shippedProposals: true, modules: false }]],
env: {
server: {
presets: [['@babel/env', { targets: { node: 12 }, shippedProposals: true, modules: 'cjs' }]],
plugins: [
'transform-react-remove-prop-types',
'add-module-exports',
[
'module-resolver',
{
alias: {
lowline: 'lodash',
'easy-tz': 'easy-tz/cjs',
'mini-qs': 'querystring',
},
},
],
],
},
},
}

View File

@ -1,3 +1,4 @@
import './styles/main.scss'
import { $, $$ } from 'dollr'
import dragula from 'dragula'
@ -6,18 +7,13 @@ import ResultList from './components/ResultList'
import store from './store'
import { receiveResults } from './actions/results'
const result = $('pre')
const containers = $$('.location')
const drake = dragula(containers, {
revertOnSpill: true,
// accepts(el, target, source, sibling) {
// // console.log('accepts');
// // console.log(target);
// return true;
ignoreInputTextSelection: false,
// }
})
drake.on('drop', (el, target, source) => {
@ -39,13 +35,10 @@ drake.on('drop', (el, target, source) => {
return res.json()
})
.then((json) => {
console.log(json)
// result.textContent = JSON.stringify(json, null, ' ')
store.dispatch(receiveResults(json))
})
.catch((err) => {
console.log('error')
console.log(err)
console.error(err)
})
}
})

View File

@ -1,44 +0,0 @@
import { h } from 'jsx-node'
export default ({ articleUrl, protocol, hostname, websocketsPort, INITIAL_STATE, js, css, cssFile }) => {
return (
'<!doctype html>' +
(
<html>
<head>
<title>Journey</title>
<meta charset='UTF-8' />
<meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' />
<link type='text/css' rel='stylesheet' href={`/css/main` + (css ? css.suffix : '') + '.css'} />
</head>
<body>
<div class='container'>
<div data-location='home' class='location l01'>
<div data-location='home' class='item'>
<span>Home</span>
</div>
</div>
<div data-location='office' class='location l02'>
<div data-location='office' class='item'>
<span>Office</span>
</div>
</div>
<div data-location='brother' class='location l03'>
<div data-location='brother' class='item'>
<span>Brother</span>
</div>
</div>
<div data-location='therapist' class='location l04'>
<div data-location='therapist' class='item'>
<span>The Rapist</span>
</div>
</div>
</div>
<div id='results' />
<script src={'/js/app' + (js ? js.suffix : '') + '.js'} />
</body>
</html>
)
)
}

View File

@ -1,12 +0,0 @@
import { h } from 'jsx-node'
export default ({ error = {}, regions = {} }) => (
<section className='error page'>
<h1>Oops!</h1>
<p>Ett problem har tyvärr uppstått.</p>
<h2>
{error.status} {error.statusText}
</h2>
<p>{error.message}</p>
</section>
)

View File

@ -1,9 +1,9 @@
import thunkMiddleware from 'redux-thunk'
import createLogger from 'redux-logger'
import { createLogger } from 'redux-logger'
import { createStore, applyMiddleware } from 'redux'
import rootReducer from './reducers/root'
const loggerMiddleware = createLogger()
import rootReducer from './reducers/root'
export default createStore(rootReducer, applyMiddleware(thunkMiddleware, loggerMiddleware))

View File

@ -6,38 +6,51 @@
"scripts": {
"format": "prettier --write .",
"lint": "eslint --ext .js --ext .jsx --ext .mjs .",
"test": "echo \"Error: no test specified\" && exit 1"
"start": "node server/server.js",
"start:dev": "nodemon server/server.js",
"test": "echo \"Error: no test specified\" && exit 1",
"webpack": "webpack"
},
"author": "Linus Miller <lohfu@lohfu.io> (https://lohfu.io/)",
"license": "MIT",
"dependencies": {
"@bmp/pg": "^0.0.6",
"body-parser": "^1.16.1",
"chalk": "^1.1.3",
"chalk": "^4.1.0",
"cookie-parser": "^1.4.3",
"dollr": "^0.1.2",
"dragula": "^3.7.2",
"easy-tz": "^0.1.1",
"express": "^4.14.1",
"express-session": "^1.15.1",
"jsx-node": "^0.2.2",
"lodash": "^4.17.4",
"lowline": "^0.1.3",
"lowline": "^0.3.0",
"midwest": "^0.4.2",
"midwest-service-errors": "^0.2.0",
"morgan": "^1.8.1",
"pg": "^6.1.2",
"preact": "^7.2.0",
"pg": "^8.3.3",
"preact": "^10.4.8",
"react-dragula": "^1.1.17",
"redux": "^3.6.0",
"redux-logger": "^2.8.1",
"redux": "^4.0.5",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.2.0",
"require-dir": "^0.3.1",
"superagent": "^3.5.0",
"require-dir": "^1.2.0",
"superagent": "^6.0.0",
"useragent": "^2.1.12",
"xml2json": "^0.11.0"
"xml2json": "^0.12.0"
},
"devDependencies": {
"@babel/core": "^7.11.4",
"@babel/preset-env": "^7.11.0",
"app-module-path": "^1.1.0",
"autoprefixer": "^9.8.6",
"babel-loader": "^8.1.0",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-module-resolver": "^2.5.0",
"babel-plugin-transform-react-jsx": "^6.23.0",
"babel-plugin-transform-react-remove-prop-types": "^0.3.2",
"css-loader": "^4.2.1",
"cssnano": "^4.1.10",
"eslint": "^7.4.0",
"eslint-config-prettier": "^6.11.0",
"eslint-config-standard": "^14.1.1",
@ -48,6 +61,17 @@
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-react": "^7.20.3",
"eslint-plugin-standard": "^4.0.1",
"prettier": "^2.1.1"
"mini-css-extract-plugin": "^0.10.0",
"mkdirp": "^0.5.1",
"nodemon": "^2.0.4",
"postcss": "^5.2.12",
"postcss-loader": "^3.0.0",
"prettier": "^2.1.1",
"rimraf": "^2.5.4",
"sass": "^1.26.10",
"sass-loader": "^9.0.3",
"webpack": "^4.44.1",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0"
}
}

23
postcss.config.js Normal file
View File

@ -0,0 +1,23 @@
'use strict'
const autoprefixer = require('autoprefixer')
const cssnano = require('cssnano')
const env = process.env.NODE_ENV || 'development'
const config = {
development: {
plugins: [autoprefixer()],
},
production: {
plugins: [
autoprefixer(),
cssnano({
preset: 'default',
}),
],
},
}
module.exports = config[env]

View File

@ -3,5 +3,5 @@
const p = require('path')
module.exports = {
static: p.join(PWD, 'public'),
static: p.join(PWD, 'dist'),
}

View File

@ -2,7 +2,7 @@
const _ = require('lodash')
const errorTemplate = require('../../build/pages/Error')
const errorTemplate = require('../templates/Error')
const defaults = {
post: (req, res, next) => {

View File

@ -71,7 +71,7 @@ module.exports = {
scope: ['email'],
// providers: {
//providers: {
// facebook: {
// clientID: 'change-this-fool',
// clientSecret: 'change-this-fool',

View File

@ -1,6 +1,6 @@
'use strict'
const factory = require('midwest/util/db')
const factory = require('@bmp/pg')
const conf = require('./config/postgres')
module.exports = factory(conf)

View File

@ -1,9 +0,0 @@
'use strict'
// const requireDir = require('require-dir');
// const membership = require('midwest-module-membership');
// const config = requireDir('./config', { camelcase: true });
// const db = require('./db');
// membership.configure(Object.assign({ db, site: config.site, smtp: config.smtp }, config.membership));

View File

@ -1,28 +0,0 @@
'use strict'
const { h } = require('jsx-node')
module.exports = function (Component, Master) {
const locals = Object.assign({ query: this.req.query }, this.app.locals, this.locals)
let html
if (typeof Master === 'function') {
if (typeof Component === 'function') {
return this.send(h(Master, locals, h(Component, locals)))
}
Component = Master
}
if (typeof Component !== 'function') {
throw new Error('Not a Component')
} else if (Component.prototype && Component.prototype.render) {
const i = new Component(locals)
html = i.render(i.props, i.state)
} else {
html = Component(locals)
}
this.send(html)
}

View File

@ -1,105 +1,19 @@
'use strict'
// const masterTemplate = require('../client/public/components/Master');
const masterTemplate = require('../../build/master')
// const loginFormTemplate = require('../build/components/login-form/template');
// const registerFormTemplate = require('../build/components/register-form/template');
// const changePasswordFormTemplate = require('../build/components/change-password-form/template');
// const forgotPasswordFormTemplate = require('../build/components/forgot-password-form/template');
// const bareMasterTemplate = require('../build/bare-master');
const masterTemplate = require('../templates/master')
const router = new (require('express').Router)()
const startCase = require('lodash/startCase')
const mw = {
// employees: require('midwest-service-employees/middleware'),
// errors: require('midwest-service-errors/middleware'),
// invites: require('midwest-module-membership/services/invites/middleware'),
// organization: require('midwest-service-organization/middleware'),
// permissions: require('midwest-module-membership/services/permissions/middleware'),
// users: require('midwest-module-membership/services/users/middleware'),
// regions: require('midwest-service-regions/middleware'),
// publishers: require('../services/publishers/middleware'),
// roles: require('midwest-module-membership/services/roles/middleware'),
// users: require('../services/users/users-middleware'),
shim: require('midwest/factories/shim')(require('../config/shim')),
}
// const {
// isAuthenticated,
// isAdmin,
// redirectUnauthorized,
// redirectAuthorized,
// } = require('midwest-module-membership/passport/authorization-middleware');
router.get('/', mw.shim, (req, res, next) => {
res.preventFlatten = true
const allowedRoutes = ['forgot', 'reset', 'verify', 'login', 'register']
res.template = masterTemplate
// const config = {
// membership: require('../config/membership'),
// };
router
// .get(new RegExp(`/(?!(${allowedRoutes.join('|')}))`), isAdmin, redirectUnauthorized(config.membership.paths.login), (req, res, next) => {
// .get(new RegExp(`/(?!(${allowedRoutes.join('|')}))`), (req, res, next) => {
// .get(new RegExp(`/(?!(${allowedRoutes.join('|')}))`), isAuthenticated, redirectUnauthorized(config.membership.paths.login))
// .get(new RegExp(`/(?=(${allowedRoutes.join('|')}))`), redirectAuthorized(isAuthenticated, '/'))
.get('/', mw.shim, (req, res, next) => {
res.preventFlatten = true
res.master = masterTemplate
next()
})
// .get(new RegExp(`/${allowedRoutes.join('|')}`), redirectAuthenticated('/'), (req, res, next) => {
// res.preventFlatten = true;
// res.master = bareMasterTemplate;
// next();
// })
// .get('/login', (req, res, next) => {
// res.locals.scripts = ['/js/login.js'];
// res.template = loginFormTemplate;
// next();
// })
// .get('/register', mw.invites.findByTokenAndEmail, (req, res, next) => {
// res.locals.scripts = ['/js/register.js'];
// res.template = registerFormTemplate;
// next();
// })
// .get('/change-password', (req, res, next) => {
// res.locals.scripts = ['/js/change-password.js'];
// res.template = changePasswordFormTemplate;
// next();
// })
// .get('/forgot-password', (req, res, next) => {
// res.locals.scripts = ['/js/forgot-password.js'];
// res.template = forgotPasswordFormTemplate;
// next();
// .get('/membership/users/:id', mw.publishers.getAll, mw.roles.getAll, mw.users.findById, (req, res, next) => {
// console.log(res.locals.roles);
// // res.locals.allRoles = res.locals.roles;
// // console.log(res.locals);
// // res.locals.allPublishers = res.locals.publishers.filter((publisher) => !res.locals.user.publishers.some((p) => {
// // return publisher._id.toString() === p._id.toString();
// // }));
// // delete res.locals.roles;
// // delete res.locals.publishers;
// next();
// })
// .get('/errors', mw.errors.formatQuery, mw.errors.paginate, mw.errors.find)
// .get('/login')
// .get('/forgot')
// .get('/reset')
// .get('/verify')
next()
})
module.exports = router

View File

@ -24,13 +24,10 @@ if (ENV === 'development') {
const _ = require('lodash')
const chalk = require('chalk')
const express = require('express')
// const passport = require('passport');
const requireDir = require('require-dir')
// modules > express middlewares
const bodyParser = require('body-parser')
// const session = require('express-session');
// const cookieParser = require('cookie-parser');
// modules > midwest
const colorizeStack = require('midwest/util/colorize-stack')
@ -46,19 +43,12 @@ process.on('uncaughtException', (err) => {
process.exit(1)
})
// midwest modules and services configuration
require('./midwest')
const config = requireDir('./config', { camelcase: true })
const config = requireDir('./config', { mapKey: (value, key) => _.camelCase(key) })
const prewares = [
express.static(config.dir.static, ENV === 'production' ? { maxAge: '1 year' } : null),
bodyParser.json(),
bodyParser.urlencoded({ extended: true }),
// cookieParser(),
// session(config.session),
// passport.initialize(),
// passport.session(),
]
if (ENV === 'development') {
@ -86,7 +76,11 @@ _.extend(server.locals, {
// override default response render method for
// more convenient use with marko
server.response.render = require('./render')
server.response.render = function (template) {
const locals = Object.assign({ query: this.req.query }, this.app.locals, this.locals)
this.send(template(locals))
}
try {
server.locals.js = require(p.join(PWD, 'public/js.json'))

View File

@ -0,0 +1,9 @@
'use strict'
module.exports = ({ error = {}, regions = {} }) => `<section className="error page">
<h1>Oops!</h1>
<p>Ett problem har tyvärr uppstått.</p>
<h2>${error.status} ${error.statusText}</h2>
<p>${error.message}</p>
</section>
`

View File

@ -0,0 +1,33 @@
'use strict'
module.exports = ({
articleUrl,
protocol,
hostname,
websocketsPort,
INITIAL_STATE,
js,
css,
cssFile,
}) => `<!doctype html>
<html>
<head>
<title>Journey</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<link type="text/css" rel="stylesheet" href=${`/app` + (css ? css.suffix : '') + '.css'} />
</head>
<body>
<div class="container">
<div data-location="home" class="location l01"><div data-location="home" class="item"><span>Home</span></div></div>
<div data-location="office" class="location l02"><div data-location="office" class="item"><span>Office</span></div></div>
<div data-location="brother" class="location l03"><div data-location="brother" class="item"><span>Brother</span></div></div>
<div data-location="therapist" class="location l04"><div data-location="therapist" class="item"><span>The Rapist</span></div></div>
</div>
<div id="results"></div>
<script src=${'/app' + (js ? js.suffix : '') + '.js'}></script>
</body>
</html>
}`

162
webpack.config.js Normal file
View File

@ -0,0 +1,162 @@
'use strict'
process.env.NODE_ENV = process.env.NODE_ENV || 'development'
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const LOCAL_IDENT_NAME = '[name]_[local]'
// style files regexes
const CSS_REGEX = /\.css$/
const CSS_MODULE_REGEX = /\.module\.css$/
const SCSS_REGEX = /\.scss$/
const SCSS_MODULE_REGEX = /\.module\.scss$/
const getSassLoader = (cssOptions) => ({
loader: require.resolve('sass-loader'),
options: {
sourceMap: cssOptions.sourceMap,
implementation: require('sass'),
},
})
const getStyleLoaders = (cssOptions, preprocesser) => {
const loaders = [
MiniCssExtractPlugin.loader,
{
loader: require.resolve('css-loader'),
options: cssOptions,
},
{
loader: require.resolve('postcss-loader'),
options: {
sourceMap: cssOptions.sourceMap,
},
},
]
if (preprocesser) {
loaders.push(getSassLoader(cssOptions))
}
return loaders
}
const isDev = process.env.NODE_ENV === 'development'
const stats = {
children: false,
colors: true,
modules: false,
timings: true,
}
module.exports = {
mode: isDev ? 'development' : 'production',
devtool: isDev ? 'cheap-module-source-map' : 'source-map',
context: path.resolve(__dirname, 'client'),
entry: {
app: './index.js',
},
output: {
path: path.resolve('./dist'),
filename: '[name].js',
},
resolve: {
extensions: ['.js', '.jsx', '.mjs', '.json'],
mainFields: ['module', 'jsnext:main', 'browser', 'main'],
},
module: {
rules: [
{
loader: 'babel-loader',
},
{
test: SCSS_MODULE_REGEX,
use: getStyleLoaders(
{
importLoaders: 2,
sourceMap: true,
modules: {
localIdentName: LOCAL_IDENT_NAME,
},
},
true,
),
},
{
test: SCSS_REGEX,
exclude: SCSS_MODULE_REGEX,
use: getStyleLoaders(
{
sourceMap: true,
importLoaders: 2,
},
true,
),
},
{
test: CSS_MODULE_REGEX,
use: getStyleLoaders(
{
sourceMap: true,
importLoaders: 1,
modules: {
localIdentName: LOCAL_IDENT_NAME,
},
},
false,
),
},
{
test: CSS_REGEX,
exclude: CSS_MODULE_REGEX,
use: getStyleLoaders(
{
sourceMap: true,
importLoaders: 1,
},
false,
),
},
{
test: /\.(xml|html|txt|md)$/,
use: 'raw-loader',
},
],
},
stats,
optimization: {
splitChunks: {
cacheGroups: {
styles: {
name: 'styles',
test: /\.css$/,
chunks: 'all',
enforce: true,
},
},
},
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
}),
],
devServer: {
host: '0.0.0.0',
port: 1337,
contentBase: path.resolve('./static'),
stats,
},
}

7780
yarn.lock Normal file

File diff suppressed because it is too large Load Diff