-
Notifications
You must be signed in to change notification settings - Fork 27.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for customizing compress encodings #657
Changes from all commits
c427d5a
9b60143
0274b23
4adbf0c
0794418
3f93273
83c5798
fcabbc8
318a9d5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Example app with custom compress encodings | ||
|
||
## How to use | ||
|
||
Download the example (or clone the repo)[https://github.com/zeit/next.js.git]: | ||
|
||
```bash | ||
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/with-custom-compress-encodings | ||
cd with-custom-compress-encodings | ||
``` | ||
|
||
Install it and run: | ||
|
||
```bash | ||
npm install | ||
npm run dev | ||
``` | ||
|
||
Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download)) | ||
|
||
```bash | ||
now | ||
``` | ||
|
||
## The idea behind the example | ||
|
||
By default, Next.js compile your assets with `gzip` compression. But if you want to add support more encodings like `br` or `deflate` you can do it very easily. | ||
|
||
This example shows how to add support for `br` and `gzip` compress encodings. For that it uses a config in `next.config.js`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import React from 'react' | ||
|
||
let count = 0 | ||
|
||
export default class Counter extends React.Component { | ||
add () { | ||
count += 1 | ||
this.forceUpdate() | ||
} | ||
|
||
render () { | ||
return ( | ||
<div> | ||
<p>Count is: {count}</p> | ||
<button onClick={() => this.add()}>Add</button> | ||
</div> | ||
) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import Link from 'next/link' | ||
|
||
export default () => ( | ||
<div> | ||
<Link href='/'> | ||
<a style={styles.a} >Home</a> | ||
</Link> | ||
|
||
<Link href='/about'> | ||
<a style={styles.a} >About</a> | ||
</Link> | ||
</div> | ||
) | ||
|
||
const styles = { | ||
a: { | ||
marginRight: 10 | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
var zlib = require('zlib') | ||
var iltorb = require('iltorb') | ||
|
||
module.exports = { | ||
// Returns a map of compression streams for the types of encodings you want to support | ||
// Here's a list of common encoding types: https://goo.gl/ke7zOK | ||
|
||
// The first listed encoding has the higher priority over others. | ||
// In this case, first it'll try to serve the `br` version if the browser supports it. | ||
// Otherwise, it'll serve the gzipped version. | ||
compress: { | ||
br: function () { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about compress the syntax to something like:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't is the same as right now except it should be If you are looking at ES2015 features, I didn't use them because we don't transpile the |
||
return iltorb.compressStream() | ||
}, | ||
gzip: function () { | ||
// You can also return a promise which resolve a compression stream | ||
return new Promise(function (resolve) { | ||
resolve(zlib.createGzip()) | ||
}) | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"name": "with-custom-compress-encodings", | ||
"version": "1.0.0", | ||
"description": "This example features:", | ||
"main": "index.js", | ||
"scripts": { | ||
"dev": "next", | ||
"build": "next build", | ||
"start": "next start" | ||
}, | ||
"dependencies": { | ||
"iltorb": "^1.0.13", | ||
"next": "^2.0.0-beta" | ||
}, | ||
"author": "", | ||
"license": "ISC" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import Header from '../components/Header' | ||
import Counter from '../components/Counter' | ||
|
||
export default () => ( | ||
<div> | ||
<Header /> | ||
<p>This is the about page.</p> | ||
<Counter /> | ||
</div> | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import Header from '../components/Header' | ||
import Counter from '../components/Counter' | ||
|
||
export default () => ( | ||
<div> | ||
<Header /> | ||
<p>HOME PAGE is here!</p> | ||
<Counter /> | ||
</div> | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import fs from 'fs' | ||
import path from 'path' | ||
import zlib from 'zlib' | ||
import glob from 'glob-promise' | ||
import getConfig from '../config' | ||
|
||
export default async function compressAssets (dir) { | ||
const nextDir = path.resolve(dir, '.next') | ||
const config = getConfig(dir) | ||
|
||
const coreAssets = [ | ||
path.join(nextDir, 'commons.js'), | ||
path.join(nextDir, 'main.js') | ||
] | ||
const pages = await glob('bundles/pages/**/*.json', { cwd: nextDir }) | ||
|
||
const allAssets = [ | ||
...coreAssets, | ||
...pages.map(page => path.join(nextDir, page)) | ||
] | ||
|
||
while (true) { | ||
// compress only 10 assets in parallel at a time. | ||
const currentChunk = allAssets.splice(0, 10) | ||
if (currentChunk.length === 0) break | ||
|
||
await Promise.all(currentChunk.map((f) => compress(config, f))) | ||
} | ||
} | ||
|
||
export function compress (config, filePath) { | ||
const compressionMap = config.compress || { | ||
gzip: () => zlib.createGzip() | ||
} | ||
|
||
const promises = Object.keys(compressionMap).map((type) => { | ||
return new Promise(async (resolve, reject) => { | ||
const input = fs.createReadStream(filePath) | ||
const output = fs.createWriteStream(`${filePath}.${type}`) | ||
// We accept stream resolved via a promise or not | ||
const compression = await compressionMap[type](filePath) | ||
|
||
// We need to handle errors like this. | ||
// See: http://stackoverflow.com/a/22389498 | ||
input.on('error', reject) | ||
compression.on('error', reject) | ||
|
||
const stream = input.pipe(compression).pipe(output) | ||
|
||
// Handle the final stream | ||
stream.on('error', reject) | ||
stream.on('finish', resolve) | ||
}) | ||
}) | ||
|
||
return Promise.all(promises) | ||
} |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be cool to use styled-jsx
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just wanna talk about this feature in this example.
Anyway, I don't mind using that too.