Skip to content

Commit

Permalink
豆瓣电影VUE-SSR
Browse files Browse the repository at this point in the history
  • Loading branch information
monkeyWangs committed Mar 22, 2017
1 parent 4831016 commit e5cac11
Show file tree
Hide file tree
Showing 44 changed files with 6,385 additions and 1 deletion.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.DS_Store
node_modules/
dist/
npm-debug.log
.idea
*.iml
48 changes: 47 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,47 @@
# doubanMovie-SSR
# vue-hackernews-2.0

HackerNews clone built with Vue 2.0 + vue-router + vuex, with server-side rendering.

<p align="center">
<a href="https://vue-hn.now.sh" target="_blank">
<img src="https://cloud.githubusercontent.com/assets/499550/17546273/5aabc5fc-5eaf-11e6-8d6a-ad00937e8bd6.png" width="700px">
<br>
Live Demo
</a>
</p>

> Note: the demo may need some spin up time if nobody has accessed it for a certain period.
## Features

- Server Side Rendering
- Vue + vue-router + vuex working together
- Server-side data pre-fetching
- Client-side state & DOM hydration
- Automatically inlines CSS used by rendered components only
- Single-file Vue Components
- Hot-reload in development
- CSS extraction for production
- Real-time List Updates with FLIP Animation

## Architecture Overview

<img width="973" alt="screen shot 2016-08-11 at 6 06 57 pm" src="https://cloud.githubusercontent.com/assets/499550/17607895/786a415a-5fee-11e6-9c11-45a2cfdf085c.png">

## Build Setup

**Requires Node.js 6+**

``` bash
# install dependencies
npm install # or yarn

# serve in dev mode, with hot reload at localhost:8080
npm run dev

# build for production
npm run build

# serve in production mode
npm start
```
60 changes: 60 additions & 0 deletions build/setup-dev-server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const path = require('path')
const webpack = require('webpack')
const MFS = require('memory-fs')
const clientConfig = require('./webpack.client.config')
const serverConfig = require('./webpack.server.config')

module.exports = function setupDevServer (app, cb) {
let bundle
let template

// modify client config to work with hot middleware
clientConfig.entry.app = ['webpack-hot-middleware/client', clientConfig.entry.app]
clientConfig.output.filename = '[name].js'
clientConfig.plugins.push(
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin()
)

// dev middleware
const clientCompiler = webpack(clientConfig)
const devMiddleware = require('webpack-dev-middleware')(clientCompiler, {
publicPath: clientConfig.output.publicPath,
stats: {
colors: true,
chunks: false
}
})
app.use(devMiddleware)
clientCompiler.plugin('done', () => {
const fs = devMiddleware.fileSystem
const filePath = path.join(clientConfig.output.path, 'index.html')
if (fs.existsSync(filePath)) {
template = fs.readFileSync(filePath, 'utf-8')
if (bundle) {
cb(bundle, template)
}
}
})

// hot middleware
app.use(require('webpack-hot-middleware')(clientCompiler))

// watch and update server renderer
const serverCompiler = webpack(serverConfig)
const mfs = new MFS()
serverCompiler.outputFileSystem = mfs
serverCompiler.watch({}, (err, stats) => {
if (err) throw err
stats = stats.toJson()
stats.errors.forEach(err => console.error(err))
stats.warnings.forEach(err => console.warn(err))

// read bundle generated by vue-ssr-webpack-plugin
const bundlePath = path.join(serverConfig.output.path, 'vue-ssr-bundle.json')
bundle = JSON.parse(mfs.readFileSync(bundlePath, 'utf-8'))
if (template) {
cb(bundle, template)
}
})
}
8 changes: 8 additions & 0 deletions build/vue-loader.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
preserveWhitespace: false,
postcss: [
require('autoprefixer')({
browsers: ['last 3 versions']
})
]
}
65 changes: 65 additions & 0 deletions build/webpack.base.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const path = require('path')
const vueConfig = require('./vue-loader.config')

module.exports = {
devtool: '#source-map',
entry: {
app: './src/entry-client.js',
vendor: [
'es6-promise/auto',
'firebase/app',
'firebase/database',
'vue',
'vue-router',
'vuex',
'vuex-router-sync'
]
},
output: {
path: path.resolve(__dirname, '../dist'),
publicPath: '/dist/',
filename: '[name].[chunkhash].js'
},
resolve: {
alias: {
'public': path.resolve(__dirname, '../public')
}
},
module: {
noParse: /es6-promise\.js$/, // avoid webpack shimming process
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueConfig
},
{
test: /\.js$/,
loader: 'buble-loader',
exclude: /node_modules/,
options: {
objectAssign: 'Object.assign'
}
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'url-loader',
options: {
limit: 10000,
name: '[name].[ext]?[hash]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: 'fonts/[name].[hash:7].[ext]'
}
}
]
},
performance: {
hints: process.env.NODE_ENV === 'production' ? 'warning' : false
}
}
44 changes: 44 additions & 0 deletions build/webpack.client.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const webpack = require('webpack')
const merge = require('webpack-merge')
const base = require('./webpack.base.config')
const vueConfig = require('./vue-loader.config')
const HTMLPlugin = require('html-webpack-plugin')
const SWPrecachePlugin = require('sw-precache-webpack-plugin')

const config = merge(base, {
plugins: [
// strip dev-only code in Vue source
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
'process.env.VUE_ENV': '"client"'
}),
// extract vendor chunks for better caching
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor'
}),
// generate output HTML
new HTMLPlugin({
template: 'src/index.template.html'
})
]
})

if (process.env.NODE_ENV === 'production') {
config.plugins.push(
// minify JS
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
// auto generate service worker
new SWPrecachePlugin({
cacheId: 'vue-hn',
filename: 'service-worker.js',
dontCacheBustUrlsMatching: /./,
staticFileGlobsIgnorePatterns: [/index\.html$/, /\.map$/]
})
)
}

module.exports = config
21 changes: 21 additions & 0 deletions build/webpack.server.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const webpack = require('webpack')
const merge = require('webpack-merge')
const base = require('./webpack.base.config')
const VueSSRPlugin = require('vue-ssr-webpack-plugin')

module.exports = merge(base, {
target: 'node',
entry: './src/entry-server.js',
output: {
filename: 'server-bundle.js',
libraryTarget: 'commonjs2'
},
externals: Object.keys(require('../package.json').dependencies),
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
'process.env.VUE_ENV': '"server"'
}),
new VueSSRPlugin()
]
})
29 changes: 29 additions & 0 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "Vue Hackernews 2.0",
"short_name": "Vue HN",
"icons": [{
"src": "/public/logo-120.png",
"sizes": "120x120",
"type": "image/png"
}, {
"src": "/public/logo-144.png",
"sizes": "144x144",
"type": "image/png"
}, {
"src": "/public/logo-152.png",
"sizes": "152x152",
"type": "image/png"
}, {
"src": "/public/logo-192.png",
"sizes": "192x192",
"type": "image/png"
},{
"src": "/public/logo-384.png",
"sizes": "384x384",
"type": "image/png"
}],
"start_url": "/",
"background_color": "#f2f3f5",
"display": "standalone",
"theme_color": "#f60"
}
56 changes: 56 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"name": "vue-doubanMovieSSR-2.0",
"description": "A Vue.js project",
"author": "monkeyWangs",
"private": true,
"scripts": {
"dev": "node server",
"start": "cross-env NODE_ENV=production node server",
"build": "rimraf dist && npm run build:client && npm run build:server",
"build:client": "cross-env NODE_ENV=production webpack --config build/webpack.client.config.js --progress --hide-modules",
"build:server": "cross-env NODE_ENV=production webpack --config build/webpack.server.config.js --progress --hide-modules"
},
"engines": {
"node": ">=7.0",
"npm": ">=4.0"
},
"dependencies": {
"compression": "^1.6.2",
"cross-env": "^3.2.4",
"element-ui": "^1.2.5",
"es6-promise": "^4.1.0",
"express": "^4.15.2",
"firebase": "^3.7.2",
"http-proxy-middleware": "^0.17.4",
"https": "^1.0.0",
"lru-cache": "^4.0.2",
"serve-favicon": "^2.4.1",
"vue": "^2.2.4",
"vue-resource": "^1.2.1",
"vue-router": "^2.3.0",
"vue-server-renderer": "^2.2.4",
"vue-style-loader": "^2.0.4",
"vuex": "^2.2.1",
"vuex-router-sync": "^4.1.2",
"webpack-merge": "^4.0.0"
},
"devDependencies": {
"autoprefixer": "^6.7.7",
"buble": "^0.15.2",
"buble-loader": "^0.4.1",
"css-loader": "^0.27.3",
"file-loader": "^0.10.1",
"html-webpack-plugin": "^2.28.0",
"rimraf": "^2.6.1",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.1",
"sw-precache-webpack-plugin": "^0.9.1",
"url-loader": "^0.5.8",
"vue-loader": "^11.1.4",
"vue-ssr-webpack-plugin": "^1.0.2",
"vue-template-compiler": "^2.2.4",
"webpack": "^2.2.1",
"webpack-dev-middleware": "^1.10.1",
"webpack-hot-middleware": "^2.17.1"
}
}
Binary file added public/logo-120.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/logo-144.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/logo-152.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/logo-192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/logo-384.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/logo-48.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit e5cac11

Please sign in to comment.