diff --git a/README.md b/README.md
index 09ecc3f..ebf8d38 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
🚋 Batteries Included View Framework
## Install
-```
+```sh
npm install tram-one --save
```
@@ -375,6 +375,9 @@ are combined, and the app is mounted onto the `selector`.
`pathName` can be an initial path, if you don't want to check the browser's
current path.
+This method only works on the client. If you are running Tram on a server, then
+use `.toString()`.
+
Note: setting `pathName` is great for testing, but prevents other routes from
being reached on page reload.
@@ -434,10 +437,10 @@ if you want to manually attach the HTMLNode that Tram-One builds to whatever.
### `app.toString(pathName, [state])`
`app.toString` returns a string of the app for a given route and state. It has
-the same interface at `app.toNode`, and basically just calls `.outerHTML` on that.
+the same interface at `app.toNode`, and basically just calls `.outerHTML` (or
+`toString` on the server) on the node.
-This can be useful if you want to do server-sider rendering. Note, this really
-hasn't been explored too much, so, milage may vary.
+This can be useful if you want to do server-sider rendering or testing.
## Development
@@ -451,10 +454,5 @@ If you decide to clone this repo, there are several commands included in the
## Todo
+Check out our [Issues on Github](https://github.com/JRJurman/tram-one/issues).
PRs welcome!
-
-- badges on README
-- advertise build size
-- source maps
-- CI (probably with Circle-CI?)
-- List Repositories with Example Apps
diff --git a/configs/rollup.esm.config.js b/configs/rollup.esm.config.js
new file mode 100644
index 0000000..08ffa60
--- /dev/null
+++ b/configs/rollup.esm.config.js
@@ -0,0 +1,26 @@
+import uglify from 'rollup-plugin-uglify'
+
+const babel = require('rollup-plugin-babel')
+const filesize = require('rollup-plugin-filesize')
+
+const pkg = require('../package.json')
+const external = Object.keys(pkg.dependencies)
+
+const plugins = [
+ babel({
+ presets: [
+ 'es2015-rollup'
+ ]
+ }),
+ uglify(),
+ filesize()
+]
+
+export default {
+ entry: 'tram-one.js',
+ external: external,
+ dest: pkg.main,
+ format: 'es',
+ plugins: plugins,
+ sourceMap: true
+}
diff --git a/configs/rollup.umd.config.js b/configs/rollup.umd.config.js
new file mode 100644
index 0000000..aafb456
--- /dev/null
+++ b/configs/rollup.umd.config.js
@@ -0,0 +1,33 @@
+import uglify from 'rollup-plugin-uglify'
+
+const commonjs = require('rollup-plugin-commonjs')
+const resolve = require('rollup-plugin-node-resolve')
+const babel = require('rollup-plugin-babel')
+const builtins = require('rollup-plugin-node-builtins')
+const globals = require('rollup-plugin-node-globals')
+const filesize = require('rollup-plugin-filesize')
+
+const pkg = require('../package.json')
+
+const plugins = [
+ resolve({ main: true, preferBuiltins: true }),
+ commonjs(),
+ globals(),
+ builtins(),
+ babel({
+ presets: [
+ 'es2015-rollup'
+ ]
+ }),
+ uglify(),
+ filesize()
+]
+
+export default {
+ entry: 'tram-one.js',
+ dest: pkg.browser,
+ format: 'umd',
+ plugins: plugins,
+ moduleName: 'tram-one',
+ sourceMap: true
+}
diff --git a/configs/testem.yml b/configs/testem.yml
index b595c93..ac7136a 100644
--- a/configs/testem.yml
+++ b/configs/testem.yml
@@ -1,6 +1,10 @@
framework: jasmine
launch_in_dev:
- - phantomjs
+ - PhantomJS
+ - Node
+launchers:
+ Node:
+ command: npm run test-server
src_files:
- tram-one.js
- tests/specs/*.js
diff --git a/configs/webpack.config.js b/configs/webpack.config.js
deleted file mode 100644
index 116231f..0000000
--- a/configs/webpack.config.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const webpack = require('webpack')
-
-module.exports = {
- entry: './tram-one.js',
- module: {
- rules: [{
- use: {
- loader: 'babel-loader',
- options: {
- presets: ['env']
- }
- }
- }]
- },
- plugins: [
- new webpack.optimize.UglifyJsPlugin({
- compress: {
- warnings: false
- },
- output: {
- comments: false
- }
- })
- ],
- output: {
- filename: './dist/tram-one.js',
- // export to AMD, CommonJS, or window
- libraryTarget: 'umd',
- // the name exported to window
- library: 'tram-one'
- }
-}
diff --git a/examples/ssr-example/index.js b/examples/ssr-example/index.js
new file mode 100644
index 0000000..3d4c158
--- /dev/null
+++ b/examples/ssr-example/index.js
@@ -0,0 +1,22 @@
+const Tram = require('../../tram-one')
+const app = new Tram()
+const html = Tram.html()
+const home = () => html`
+
+
This is the Home Page
+
This is rendered on a server, and then served up to you!
+
We also have a number page here:
/num
+
+`
+const num = (state) => html`
+
+
This is a Number Page
+
This is rendered on a server, and then served up to you!
+
We can even take in stuff from the server, like this number: ${state.number}
+
+`
+
+app.addRoute('/', home)
+app.addRoute('/number', num)
+
+module.exports = app
diff --git a/examples/ssr-example/server.js b/examples/ssr-example/server.js
new file mode 100644
index 0000000..244296d
--- /dev/null
+++ b/examples/ssr-example/server.js
@@ -0,0 +1,17 @@
+const express = require('express')
+const server = express()
+
+const app = require('./index')
+
+server.get('/', (req, res) => {
+ res.send(app.toString('/'))
+})
+
+server.get('/num', (req, res) => {
+ const number = Math.random() * 10
+ res.send(app.toString('/number', {number}))
+})
+
+server.listen(5000, () => {
+ console.log('ssr express server running on port 5000!')
+})
diff --git a/package.json b/package.json
index a4c25f4..805a8e9 100644
--- a/package.json
+++ b/package.json
@@ -1,16 +1,23 @@
{
"name": "tram-one",
- "version": "1.0.0",
+ "version": "1.1.0",
"description": "🚋 Batteries Included View Framework",
- "main": "dist/tram-one.js",
- "files": ["dist/tram-one.js"],
+ "main": "dist/tram-one.esm.js",
+ "browser": "dist/tram-one.umd.js",
+ "files": [
+ "dist/tram-one.esm.js",
+ "dist/tram-one.umd.js"
+ ],
"scripts": {
"lint": "eslint ./",
"example": "node dev-scripts/example-selector.js",
"examples": "npm run example",
- "build": "webpack --config configs/webpack.config.js",
- "test-build": "webpack --config configs/webpack.config.js && webpack --config configs/webpack.testem.config.js",
+ "build": "npm run build-esm && npm run build-umd",
+ "build-esm": "rollup -c configs/rollup.esm.config.js",
+ "build-umd": "rollup -c configs/rollup.umd.config.js",
+ "test-build": "npm run build && webpack --config configs/webpack.testem.config.js",
"test-dev": "testem -f configs/testem.yml",
+ "test-server": "jasmine tests/specs/tram-spec.js",
"test": "testem ci -f configs/testem.yml"
},
"author": {
@@ -32,14 +39,30 @@
"devDependencies": {
"babel-core": "^6.25.0",
"babel-loader": "^7.0.0",
+ "babel-plugin-external-helpers": "^6.22.0",
"babel-preset-env": "^1.5.2",
+ "babel-preset-es2015": "^6.24.1",
+ "babel-preset-es2015-rollup": "^3.0.0",
"eslint": "^3.19.0",
"eslint-config-standard": "^10.2.1",
+ "eslint-plugin-import": "^2.6.0",
+ "eslint-plugin-node": "^5.0.0",
"eslint-plugin-promise": "^3.5.0",
"eslint-plugin-standard": "^3.0.1",
+ "express": "^4.15.3",
"inquirer": "^3.1.0",
"internal-ip": "^1.2.0",
+ "jasmine": "^2.6.0",
+ "min-document": "^2.19.0",
"opn": "^5.0.0",
+ "rollup": "^0.43.0",
+ "rollup-plugin-babel": "^2.7.1",
+ "rollup-plugin-commonjs": "^8.0.2",
+ "rollup-plugin-filesize": "^1.4.2",
+ "rollup-plugin-node-builtins": "^2.1.2",
+ "rollup-plugin-node-globals": "^1.1.0",
+ "rollup-plugin-node-resolve": "^3.0.0",
+ "rollup-plugin-uglify": "^2.0.1",
"testem": "^1.16.2",
"webpack": "^2.6.1",
"webpack-dev-server": "^2.4.5"
diff --git a/tests/specs/tram-spec.js b/tests/specs/tram-spec.js
index 748ab47..e213848 100644
--- a/tests/specs/tram-spec.js
+++ b/tests/specs/tram-spec.js
@@ -1,5 +1,15 @@
-const Tram = window['tram-one']
-const testemPath = window.location.pathname
+const Tram = require('../../dist/tram-one.esm')
+
+const isBrowser = typeof window !== 'undefined'
+const testemPath = isBrowser ? window.location.pathname : '/'
+const document = isBrowser ? window.document : require('min-document')
+
+const stringify = (node) => {
+ if (node.outerHTML !== undefined) {
+ return node.outerHTML
+ }
+ return node.toString()
+}
describe('Tram', () => {
let app
@@ -23,14 +33,14 @@ describe('Tram', () => {
app = new Tram()
app.addRoute('/404', errorPage)
- expect(app.toString('/')).toEqual(errorPage().outerHTML)
+ expect(app.toString('/')).toEqual(stringify(errorPage()))
})
it('should take in a default route', () => {
app = new Tram({defaultRoute: '/200'})
app.addRoute('/200', successPage)
- expect(app.toString('/')).toEqual(successPage().outerHTML)
+ expect(app.toString('/')).toEqual(stringify(successPage()))
})
it('should not always go to the default', () => {
@@ -38,7 +48,7 @@ describe('Tram', () => {
app.addRoute('/404', errorPage)
app.addRoute('/200', successPage)
- expect(app.toString('/200')).not.toEqual(errorPage().outerHTML)
+ expect(app.toString('/200')).not.toEqual(stringify(errorPage()))
})
})
@@ -63,10 +73,10 @@ describe('Tram', () => {
app.addRoute('/good', successPage)
app.addRoute('/bad', errorPage)
app.addRoute('/404', errorPage)
- expect(app.toString('/')).toEqual(successPage().outerHTML)
- expect(app.toString('/good')).toEqual(successPage().outerHTML)
- expect(app.toString('/bad')).toEqual(errorPage().outerHTML)
- expect(app.toString('/404')).toEqual(errorPage().outerHTML)
+ expect(app.toString('/')).toEqual(stringify(successPage()))
+ expect(app.toString('/good')).toEqual(stringify(successPage()))
+ expect(app.toString('/bad')).toEqual(stringify(errorPage()))
+ expect(app.toString('/404')).toEqual(stringify(errorPage()))
})
it('should include the default state in app', () => {
@@ -86,6 +96,8 @@ describe('Tram', () => {
})
describe('start', () => {
+ if (!isBrowser) { return }
+
beforeEach(() => {
const childDiv = document.createElement('div')
childDiv.id = 'tram_test_container'
@@ -120,6 +132,8 @@ describe('Tram', () => {
})
describe('mount', () => {
+ if (!isBrowser) { return }
+
beforeEach(() => {
const childDiv = document.createElement('div')
childDiv.id = 'tram_test_container'
@@ -136,9 +150,9 @@ describe('Tram', () => {
app.addRoute('/', queryablePage)
const target = document.getElementById('tram_test_container')
- app.mount(target, '/')
+ app.mount(target, '/', undefined, document)
const mountedTarget = document.querySelector(queryableSelector)
- expect(mountedTarget.outerHTML).toEqual(queryablePage().outerHTML)
+ expect(mountedTarget.outerHTML).toEqual(stringify(queryablePage()))
})
it('should use the default route', () => {
@@ -149,7 +163,7 @@ describe('Tram', () => {
const target = document.getElementById('tram_test_container')
app.mount(target)
const mountedTarget = document.querySelector(queryableSelector)
- expect(mountedTarget.outerHTML).toEqual(queryablePage(200).outerHTML)
+ expect(mountedTarget.outerHTML).toEqual(stringify(queryablePage(200)))
})
it('should attach the app to a selector', () => {
@@ -158,7 +172,7 @@ describe('Tram', () => {
app.addRoute('/', queryablePage)
app.mount('#tram_test_container', '/')
const mountedTarget = document.querySelector(queryableSelector)
- expect(mountedTarget.outerHTML).toEqual(queryablePage().outerHTML)
+ expect(mountedTarget.outerHTML).toEqual(stringify(queryablePage()))
})
it('should update the app on re-mount', () => {
@@ -169,7 +183,7 @@ describe('Tram', () => {
app.mount('#tram_test_container', '/')
app.mount('#tram_test_container', '/200')
const mountedTarget = document.querySelector(queryableSelector)
- expect(mountedTarget.outerHTML).toEqual(queryablePage(200).outerHTML)
+ expect(mountedTarget.outerHTML).toEqual(stringify(queryablePage(200)))
})
})
@@ -177,7 +191,7 @@ describe('Tram', () => {
it('should resolve the path', () => {
app = new Tram()
app.addRoute('/', successPage)
- expect(app.toNode('/').outerHTML).toEqual(successPage().outerHTML)
+ expect(stringify(app.toNode('/'))).toEqual(stringify(successPage()))
})
it('should have the default state', () => {
@@ -198,7 +212,7 @@ describe('Tram', () => {
it('should return a string', () => {
app = new Tram()
app.addRoute('/404', errorPage)
- expect(app.toString('/')).toEqual(errorPage().outerHTML)
+ expect(app.toString('/')).toEqual(stringify(errorPage()))
})
})
diff --git a/tests/testem.html b/tests/testem.html
index 11aa567..0167072 100644
--- a/tests/testem.html
+++ b/tests/testem.html
@@ -19,7 +19,6 @@
-
diff --git a/tram-one.js b/tram-one.js
index 0484714..c94d3a0 100644
--- a/tram-one.js
+++ b/tram-one.js
@@ -61,7 +61,10 @@ class Tram {
}
toString(pathName, state) {
- return this.toNode(pathName, state).outerHTML
+ if (typeof window !== 'undefined') {
+ return this.toNode(pathName, state).outerHTML
+ }
+ return this.toNode(pathName, state).toString()
}
static html(registry) {