webpack 4 + preact (#786)

This commit is contained in:
typicode
2018-05-30 12:39:10 +02:00
committed by GitHub
parent 8d0c5609fc
commit e9458a6409
16 changed files with 7935 additions and 192 deletions

View File

@ -1,10 +1,11 @@
{
"presets": [
["env", {
"targets": {
"node": 4
},
"exclude": ["transform-regenerator"]
}]
[
"env", {
"targets": {
"node": "6"
}
}
]
]
}

View File

@ -1,5 +1,5 @@
module.exports = {
extends: ['standard', 'prettier'],
extends: ['standard', 'standard-preact', 'prettier'],
plugins: ['prettier'],
rules: {
'prettier/prettier': [

1
.gitignore vendored
View File

@ -2,6 +2,7 @@
node_modules
tmp
lib
dist
.DS_Store
.idea
db.json

7882
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,20 @@
"directories": {
"test": "test"
},
"scripts": {
"test": "npm run test:cli && npm run test:server && npm run lint",
"test:cli": "npm run build && cross-env NODE_ENV=test mocha test/cli/*.js",
"test:server": "cross-env NODE_ENV=test mocha test/server/*.js",
"start": "run-p start:**",
"start:babel-node": "babel-node src/cli/bin db.json -r routes.json",
"start:webpack": "webpack -d --watch",
"lint": "eslint . --ignore-path .gitignore",
"fix": "npm run lint -- --fix",
"build": "babel src -d lib && webpack -p",
"toc": "markdown-toc -i README.md",
"prepublishOnly": "npm test && npm run build && pkg-ok",
"precommit": "npm test"
},
"dependencies": {
"body-parser": "^1.18.2",
"chalk": "^2.3.0",
@ -33,40 +47,47 @@
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.4",
"babel-plugin-transform-regenerator": "^6.26.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.7.0",
"babel-preset-preact": "^1.1.0",
"babel-register": "^6.26.0",
"clean-webpack-plugin": "^0.1.19",
"cross-env": "^5.1.1",
"css-loader": "^0.28.11",
"eslint": "^4.10.0",
"eslint-config-prettier": "^2.7.0",
"eslint-config-standard": "^10.2.1",
"eslint-config-standard-preact": "^1.1.6",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-node": "^5.2.1",
"eslint-plugin-prettier": "^2.3.1",
"eslint-plugin-promise": "^3.6.0",
"eslint-plugin-react": "^7.8.2",
"eslint-plugin-standard": "^3.0.1",
"html-webpack-plugin": "^3.2.0",
"husky": "^0.14.3",
"markdown-toc": "^1.2.0",
"milligram": "^1.3.0",
"mini-css-extract-plugin": "^0.4.0",
"mkdirp": "^0.5.1",
"mocha": "^4.0.1",
"npm-run-all": "^4.1.3",
"os-tmpdir": "^1.0.1",
"pkg-ok": "^2.1.0",
"preact": "^8.2.9",
"prettier": "^1.7.4",
"promise-polyfill": "^7.1.2",
"rimraf": "^2.6.2",
"server-ready": "^0.3.1",
"standard": "^10.0.3",
"supertest": "^3.0.0",
"temp-write": "^3.3.0"
},
"scripts": {
"test": "npm run test:cli && npm run test:server && eslint .",
"test:cli": "npm run build && cross-env NODE_ENV=test mocha test/cli/*.js",
"test:server": "cross-env NODE_ENV=test mocha test/server/*.js",
"start": "babel-node src/cli/bin",
"fix": "eslint . --fix",
"build": "babel src -d lib --copy-files",
"toc": "markdown-toc -i README.md",
"prepublishOnly": "npm run build && npm run lf && pkg-ok",
"precommit": "npm test"
"temp-write": "^3.3.0",
"webpack": "^4.9.1",
"webpack-cli": "^2.1.4",
"whatwg-fetch": "^2.0.4"
},
"repository": {
"type": "git",
@ -95,6 +116,6 @@
},
"homepage": "https://github.com/typicode/json-server",
"engines": {
"node": ">=4"
"node": ">=6"
}
}

View File

@ -7,9 +7,14 @@ const enableDestroy = require('server-destroy')
const pause = require('connect-pause')
const is = require('./utils/is')
const load = require('./utils/load')
const example = require('./example.json')
const jsonServer = require('../server')
const example = {
posts: [{ id: 1, title: 'json-server', author: 'typicode' }],
comments: [{ id: 1, body: 'some comment', postId: 1 }],
profile: { name: 'typicode' }
}
function prettyPrint(argv, object, rules) {
const host = argv.host === '0.0.0.0' ? 'localhost' : argv.host
const port = argv.port

3
src/front/.babelrc Normal file
View File

@ -0,0 +1,3 @@
{
"presets": [ "env", "preact"]
}

View File

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 318 B

View File

@ -2,10 +2,6 @@
<head>
<title>JSON Server</title>
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic">
<link rel="stylesheet" href="//cdn.rawgit.com/necolas/normalize.css/master/normalize.css">
<link rel="stylesheet" href="//cdn.rawgit.com/milligram/milligram/master/dist/milligram.min.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
@ -53,9 +49,5 @@
</p>
</div>
</footer>
<script src="https://unpkg.com/mithril/mithril.min.js"></script>
<script src="main.js"></script>
</body>
</html>
</html>

75
src/front/index.js Normal file
View File

@ -0,0 +1,75 @@
import 'promise-polyfill/src/polyfill'
import 'whatwg-fetch'
import { h, render } from 'preact'
import 'milligram/dist/milligram.css'
import './style.css'
function ResourceItem({ name, length }) {
return (
<li>
<a href={name}>/{name}</a> <sup>{length ? `${length}x` : 'object'}</sup>
</li>
)
}
function ResourceList({ db }) {
return (
<ul>
{Object.keys(db).map(name => (
<ResourceItem
name={name}
length={Array.isArray(db[name]) && db[name].length}
/>
))}
</ul>
)
}
function NoResources() {
return <p>No resources found</p>
}
function ResourcesBlock({ db }) {
return (
<div>
<h4>Resources</h4>
{Object.keys(db).length ? <ResourceList db={db} /> : <NoResources />}
</div>
)
}
window
.fetch('db')
.then(response => response.json())
.then(db =>
render(<ResourcesBlock db={db} />, document.getElementById('resources'))
)
function CustomRoutesBlock({ customRoutes }) {
const rules = Object.keys(customRoutes)
if (rules.length) {
return (
<div>
<h4>Custom Routes</h4>
<table>
{rules.map(rule => (
<tr>
<td>{rule}</td>
<td> {customRoutes[rule]}</td>
</tr>
))}
</table>
</div>
)
}
}
window
.fetch('__rules')
.then(response => response.json())
.then(customRoutes => {
render(
<CustomRoutesBlock customRoutes={customRoutes} />,
document.getElementById('custom-routes')
)
})

View File

@ -5,6 +5,7 @@ html {
body {
display: flex;
min-height: 100vh;
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
flex-direction: column;
padding:0;
margin: 0;

View File

@ -10,7 +10,7 @@ const bodyParser = require('./body-parser')
module.exports = function(opts) {
const userDir = path.join(process.cwd(), 'public')
const defaultDir = path.join(__dirname, 'public')
const defaultDir = path.join(__dirname, '../../dist')
const staticDir = fs.existsSync(userDir) ? userDir : defaultDir
opts = objectAssign({ logger: true, static: staticDir }, opts)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 278 B

View File

@ -1,57 +0,0 @@
/* global m */
// Resource list
var db = {}
m.request('db').then(function(data) {
db = data
})
m.mount(document.getElementById('resources'), {
view: function() {
var keys = Object.keys(db)
var resourceList = m(
'ul',
keys
.map(function(key) {
return m('li', [
m('a', { href: key }, '/' + key),
m(
'sup',
Array.isArray(db[key]) ? ' ' + db[key].length + 'x' : ' object'
)
])
})
.concat([m('a', { href: 'db' }, '/db'), m('sup', m('em', ' state'))])
)
return [
m('h4', 'Resources'),
keys.length ? resourceList : m('p', 'No resources found')
]
}
})
// Custom routes
var customRoutes = {}
m.request('__rules').then(function(data) {
customRoutes = data
})
m.mount(document.getElementById('custom-routes'), {
view: function() {
var rules = Object.keys(customRoutes)
if (rules.length) {
return [
m('h4', 'Custom routes'),
m(
'table',
rules.map(function(rule) {
return m('tr', [m('td', rule), m('td', '⇢ ' + customRoutes[rule])])
})
)
]
}
}
})

View File

@ -698,10 +698,10 @@ describe('Server', () => {
.expect(200))
})
describe('GET /style.css', () => {
describe('GET /main.css', () => {
it('should respond with css', () =>
request(server)
.get('/style.css')
.get('/main.css')
.expect('Content-Type', /css/)
.expect(200))
})

21
webpack.config.js Normal file
View File

@ -0,0 +1,21 @@
const CleanWebpackPlugin = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
entry: './src/front/index.js',
module: {
rules: [
{ test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] },
{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' }
]
},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
favicon: 'src/front/favicon.ico',
template: 'src/front/index.html'
}),
new MiniCssExtractPlugin()
]
}